2016-03-03 19 views
2

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

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

我被困在这里的第一句话。 Nvidia至少支持超过5年的双精度。你使用哪张牌?这真的是那么古老吗?您可以添加一个cuda编译器标志来启用双精度支持。 - 除此之外,我欢迎您选择使用您的软件支持nvidia以外的厂商。 ;)通常使用*噪声函数*完成随机性,这是一个函数,它使用种子和线程ID分别为每个线程获取一个随机数。看看[这个问题](http://stackoverflow.com/questions/9912143/how-to-get-a-random-number-in-opencl)作为开始。 – leemes

+0

对不起,我的意思是快速双重percision。 – chasep255

+0

您可以使用来自Boost.Compute或VexCL库的(基于计数器的)随机数生成器。 – ddemidov

回答

1

VexCL库提供了一个基于计数器的生成器的实现。您可以使用较大表达式中的内容,例如,请参阅此slide

编辑:采取一粒苏丹,因为我是VexCL的作者:)。