GPU产生随机数问题

最近尝试Julia的GPU计算,似乎目前我只看到了通过CuArrays.rand来使用GPU产生随机数,而我需要使用CUDAnative来写一个Kernel函数,还没有见到能在CUDAnative的内核函数中产生随机数的方法,目前我只能想到用CuArrays.rand来产生,然后再传递给Kenel函数这个蹩脚的方法,请问大家有没有听过直接在CUDAnative的Kernel函数产生随机数的方法呢?

搜了一下,都是推荐 CuArray 的。要用 native 得自己写。

下面这种用了自定义的 xorshift 来产生随机数

https://discourse.julialang.org/t/generating-random-number-from-inside-kernel/8071/2

1 个赞

了解了,谢谢版主。

有个 gpu_rand 函数,应该是你需要的

https://github.com/JuliaGPU/GPUArrays.jl/blob/4463977a37108edeec83ccf0f2d8e11b6178f177/src/host/random.jl#L31-L59

我之前写的一个sample code 你可以参考下,不知道现在还能不能用:

function cu_alias_sample!(a::GPUArray{Ta}, wv::AbstractVector{Tw}, x::GPUArray{Ta}) where {Tw<:Number, Ta}
    length(a) == length(wv) || throw(DimensionMismatch("weight vector must have the same length with label vector"))
    n = length(wv)
    # create alias table
    ap = Vector{Tw}(undef, n)
    alias = Vector{Int64}(undef, n)
    make_alias_table!(wv, sum(wv), ap, alias)
    
    # to device
    alias = CuArray{Int64}(alias)
    ap = CuArray{Tw}(ap)
    
    function kernel(state, alias, ap, x, a, randstate)
        r1, r2 = GPUArrays.gpu_rand(Float32, state, randstate), GPUArrays.gpu_rand(Float32, state, randstate)
        r1 = r1 == 1.0 ? 0.0 : r1
        r2 = r2 == 1.0 ? 0.0 : r2
        i = linear_index(state)
        if i <= length(x)
            j = floor(Int, r1 * n) + 1
            @inbounds x[i] = r2 < ap[j] ? a[j] : a[alias[j]]
        end
        return
    end
    gpu_call(kernel, x, (alias, ap, x, a, GPUArrays.global_rng(x).state))
    x
end
1 个赞

谢谢 :smiley:,不过我有点看不太懂

另外我还看到这篇文章中可以直接使用curand(),我也曾经尝试过写在内核函数中,不过直接报错。感觉Julia的GPU还是缺很多基本的轮子。

另外您知道如何在CUDAnative的Kernel中创建新数组吗?