Hi All,
I’m trying to understand the use of random numbers inside CUDA kerrnels in Julia. Below I have a simple script to estimate pi, but I have a few questions regarding its implementation.
- Is my implementation of random numbers inside the
mc_pi_kernel!
even correct? The code runs, but if I try to callx = CUDA.rand(Float32, 1)
the code crashes with anunsupported call
error and I’m not sure why. - I’ve tried using the
Random123.jl
library to use a counter-based RNG but this also gets anunsupported dynamic function invocation
error.
What am I doing wrong here?
Here’s the minimal reproducible example,
using CUDA
using Random123 # CUDA counter-based PRNG?
function mc_pi_kernel!(results::CuDeviceVector{Int32}, N::Int)
tid = threadIdx().x + (blockIdx().x - 1) * blockDim().x
if tid < 1 || tid > N
return
end
x = rand(Float32) # Does this call CPU rand host-side?
y = rand(Float32)
results[tid] = (x*x + y*y <= 1.0f0) ? 1 : 0
return
end
function estimate_pi(N::Int=10^6)
d_results = CuArray(zeros(Int32, N))
# Get configuration threads/blocks
kernel = @cuda launch=false mc_pi_kernel!(d_results, N)
config = launch_configuration(kernel.fun)
threads = min(N, config.threads)
blocks = cld(N, threads)
println("Estimating π with $N samples ($blocks blocks, $threads threads)")
@cuda always_inline=true threads=threads blocks=blocks mc_pi_kernel!(d_results, N)
inside = sum(Array(d_results))
return 4 * inside / N
end
N = 10^9
pi_est = estimate_pi(N)
println("Estimated π with $N samples = $pi_est")