# How to round off a Float32 to Int32 on GPU

**URL:** <https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129>\
**Category:** GPU\
**Tags:** question\
**Created:** [April 14, 2019, 3:05am UTC](https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129 "2019-04-14T03:05:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![11116](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/11116/32/7775_2.png) [@11116](https://discourse.julialang.org/u/11116)\
**Post date:** [April 14, 2019, 3:05am UTC](https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129/1 "2019-04-14T03:05:41Z")

</div>

```julia
using CUDAdrv, CUDAnative,CuArrays
#try to convert a Float32 to Int32
function addKernel!(x,y,θ)
    x = threadIdx().x+blockDim().x*(blockIdx().x-1)
    m = x*CUDAnative.cos(θ)+CUDAnative.sin(θ)*y
    z = Int32(m)
    x[z,z] = y[z,z]
    return
end
#create GPU arrays
N = 512
x = CuArray(fill(1.0f0,N,N))
y = CuArray(fill(1.0f0,N,N))

@device_code_warntype @cuda threads=(16,16) blocks = (32,32) addKernel!(x,y,Float32(1.0))

```

It doesn’t compile:

```julia
GPU compilation of addKernel!(CuDeviceArray{Float32,2,CUDAnative.AS.Global}, CuDeviceArray{Float32,2,CUDAnative.AS.Global}, Float32) failed
KernelError: kernel returns a value of type `Union{}`

Make sure your kernel function ends in `return`, `return nothing` or `nothing`.
If the returned value is of type `Union{}`, your Julia code probably throws an exception.
Inspect the code with `@device_code_warntype` for more details.`

```

using round doesn’t work either.Any idea?

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [April 14, 2019, 10:18am UTC](https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129/2 "2019-04-14T10:18:30Z")

</div>

That error isn’t due to the conversion. You’re passing two arrays to your kernel, `x` and `y`, and multiplying that array doing `CUDAnative.sin(θ)*y`. You can kind-of see that from the `code_warntype ` output, since it is the last executed instruction before the kernel errors (the `unreachable` in the output):

```julia
│ %31 = Base.llvmcall::Core.IntrinsicFunction
│ %32 = (%31)(("declare float @__nv_sinf(float)", "%2 = call float @__nv_sinf(float %0)\nret float %2"), Float32, Tuple{Float32}, θ)::Float32
│ %33 = invoke Base.broadcast(Base.:*::typeof(*), %32::Float32, _3::CuDeviceArray{Float32,2,CUDAnative.AS.Global})::Array{Float32,2}
│ (%30 + %33)
└── $(Expr(:unreachable))

```

---

<div class="post-metadata">

**Author:** ![11116](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/11116/32/7775_2.png) [@11116](https://discourse.julialang.org/u/11116)\
**Post date:** [April 14, 2019, 2:25pm UTC](https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129/3 "2019-04-14T14:25:07Z")

</div>

Oh,I make such a mistake!(I use the same name x)But even after I change the kernel

```julia
function addKernel!(a,b,θ)
    x = threadIdx().x+blockDim().x*(blockIdx().x-1)
    m = x*CUDAnative.cos(θ)+CUDAnative.sin(θ)*y
    z = Int32(m)
    a[z,z] = b[z,z]
    return
end

```

It still doesn’t work:

```julia
InvalidIRError: compiling addKernel!(CuDeviceArray{Float32,2,CUDAnative.AS.Global}, CuDeviceArray{Float32,2,CUDAnative.AS.Global}, Float32) resulted in invalid LLVM IR
Reason: unsupported call to the Julia runtime (call to jl_box_float32)
Stacktrace:
 [1] Type at float.jl:703
 [2] addKernel! at In[2]:6

```

So I think it still has something to do with type conversion.

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [April 14, 2019, 4:18pm UTC](https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129/4 "2019-04-14T16:18:25Z")

</div>

`y` is still undefined in that kernel? Assuming you meant the following:

```julia
julia> function addKernel!(a,b,θ)
           x = threadIdx().x+blockDim().x*(blockIdx().x-1)
           y = threadIdx().y+blockDim().y*(blockIdx().y-1)
           m = x*CUDAnative.cos(θ)+CUDAnative.sin(θ)*y
           z = Int32(m)
           a[z,z] = b[z,z]
           return
       end
addKernel! (generic function with 1 method)

```

You can use `z = unsafe_trunc(Int32, m)` to force an unsafe conversion. I had expected the box to work though, but performance would have been bad so it’s better to do that unsafe conversion instead.

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [April 16, 2019, 11:11am UTC](https://discourse.julialang.org/t/how-to-round-off-a-float32-to-int32-on-gpu/23129/5 "2019-04-16T11:11:34Z")

</div>

Conversion using `Int32` constructor now also works: [https://github.com/JuliaGPU/CUDAnative.jl/pull/388](https://github.com/JuliaGPU/CUDAnative.jl/pull/388)
