【问题标题】:Equivalent of curand for OpenCL相当于 OpenCL 的 curand
【发布时间】:2016-06-17 11:17:57
【问题描述】:

我正在考虑将我的计算卡从 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];
}

【问题讨论】:

  • 我卡在第一句话这里。 Nvidia 至少支持双精度超过 5 年。你用哪张卡?真的有那么老吗?您可以添加一个 cuda 编译器标志来启用双精度支持。 - 除此之外,我欢迎您选择用您的软件支持除 nvidia 以外的供应商。 ;) 随机性通常由 noise 函数 完成,该函数采用种子和线程 ID 分别为每个线程获取随机数。请参阅this question 作为开始。
  • 对不起,我的意思是快速双精度。
  • 您可以使用 Boost.Compute 或 VexCL 库中的(基于计数器的)随机数生成器。
  • 我使用this RNG named MWC64X 在我的 OpenCL Monte-Carlo 代码中替换 curand。它重量轻且非常有效。 IDK 如果它是最好的或任何东西,但它对我来说做得非常好

标签: c++ opencl


【解决方案1】:

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

编辑:我是 VexCL 的作者 :)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2015-10-07
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多