2016-03-03 29 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的作者:)。