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];
}
我被困在這裏的第一句話。 Nvidia至少支持超過5年的雙精度。你使用哪張牌?這真的是那麼古老嗎?您可以添加一個cuda編譯器標誌來啓用雙精度支持。 - 除此之外,我歡迎您選擇使用您的軟件支持nvidia以外的廠商。 ;)通常使用*噪聲函數*完成隨機性,這是一個函數,它使用種子和線程ID分別爲每個線程獲取一個隨機數。看看[這個問題](http://stackoverflow.com/questions/9912143/how-to-get-a-random-number-in-opencl)作爲開始。 – leemes
對不起,我的意思是快速雙重percision。 – chasep255
您可以使用來自Boost.Compute或VexCL庫的(基於計數器的)隨機數生成器。 – ddemidov