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