相当于OpenCL的curand

时间:2016-03-03 22:00:02

标签: c++ opencl

我正在考虑从我的计算卡从nvidia切换到amd,因为我想要双精度支持。在此之前,我决定在我的nvidia卡上学习opencl,看看我是否喜欢它。我想将以下代码从CUDA转换为OpenCL。我正在使用curand库来生成均匀和正态分布的随机数。每个线程都需要能够创建不同的随机数序列,并为每个线程生成几百万个。这是代码。我将如何在OpenCL中解决这个问题。我在网上看到的所有内容似乎都暗示我应该生成一个随机数的缓冲区,然后在gpu上使用它,但这对我来说不实用。

template<int NArgs, typename OptimizationFunctor>
__global__ 
void statistical_solver_kernel(float* args_lbounds, 
                    float* args_ubounds, 
                    int trials,
                    int initial_temp,
                    unsigned long long seed,
                    float* results,
                    OptimizationFunctor f)
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if(idx >= trials) 
        return;

    curandState rand;
    curand_init(seed, idx, 0, &rand);
    float x[NArgs];
    for(int i = 0; i < NArgs; i++)
    {
        x[i] = curand_uniform(&rand) * (args_ubounds[i]- args_lbounds[i]) + args_lbounds[i];
    }
    float y = f(x);
    for(int t = initial_temp - 1; t > 0; t--)
    {
        float t_percent = (float)t / initial_temp;
        float x_prime[NArgs];
        for(int i = 0; i < NArgs; i++)
        {
            x_prime[i] = curand_normal(&rand) * (args_ubounds[i] - args_lbounds[i]) * t_percent + x[i];
            x_prime[i] = fmaxf(args_lbounds[i], x_prime[i]);
            x_prime[i] = fminf(args_ubounds[i], x_prime[i]);
        }

        float y_prime = f(x_prime);
        if(y_prime < y || (y_prime - y) / y_prime < t_percent)
        {
            y = y_prime;
            for(int i = 0; i < NArgs; i++)
            {
                x[i] = x_prime[i];
            }
        }
    }   

    float* rptr = results + idx * (NArgs + 1);
    rptr[0] = y;
    for(int i = 1; i <= NArgs; i++)
        rptr[i] = x[i - 1];
}

1 个答案:

答案 0 :(得分:1)

VexCL库提供了基于计数器的生成器的实现。您可以在较大的表达式中使用它们,请参阅此slide作为示例。

编辑:带上一点sault,因为我是VexCL的作者:)。