2013-06-23 45 views
1

我想在设备上生成统一的随机数,用于设备函数内部。每个线程应该生成一个不同的统一的随机数。我有这个代码,但我得到了分段错误。在CUDA设备上生成均匀的双随机数

int main{ 
    curandStateMtgp32 *devMTGPStates; 
    mtgp32_kernel_params *devKernelParams; 

    cudaMalloc((void **)&devMTGPStates, NUM_THREADS*NUM_BLOCKS * sizeof(curandStateMtgp32)); 
    cudaMalloc((void**)&devKernelParams,sizeof(mtgp32_kernel_params)); 

    curandMakeMTGP32Constants(mtgp32dc_params_fast_11213, devKernelParams); 
    curandMakeMTGP32KernelState(devMTGPStates, 
    mtgp32dc_params_fast_11213, devKernelParams,NUM_BLOCKS*NUM_THREADS, 1234); 

    doHenry <<NUM_BLOCKS,NUM_THREADS>>> (devMTGPStates); 
} 

和,我的整体功能doHenry,设备上的评价里面,我把:

double rand1 = curand_uniform_double(&state[threadIdx.x+NUM_THREADS*blockIdx.x]); 

这是生成每个线程随机数的最佳方式?我不明白devKernelParams在做什么,但是我知道每个线程都需要一个状态,对吧?

谢谢你的帮助。

+1

如果您发现这样的问题,如果您为您的读者确定哪条线路会给您发生故障,这很方便。如果你不知道 - 请做那种微不足道的调试。此外,你应该[检查你的cuda API调用](http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using-the-cuda-runtime -api)和curand调用,并进行错误检查。 Curand错误检查包含在[documentation](http://docs.nvidia.com/cuda/curand/index.html#topic_1_2_3)中。是的,如果你想要每个线程独立的随机序列,你需要每个线程一个状态。 –

回答

2

我觉得你要在这条线的赛格故障:

curandMakeMTGP32KernelState(devMTGPStates, mtgp32dc_params_fast_11213, devKernelParams,NUM_BLOCKS*NUM_THREADS, 1234); 

相信对于赛格故障的原因是因为你已经超过了200的n参数,要为其传递NUM_BLOCKS*NUM_THREADS。我尝试了一个你的代码版本,并且我能够在n = 540左右重现seg故障。

当使用预先生成的内核参数(mtgp32dc_params_fast_11213)时,MT发生器对它可以设置的状态量有限制。您不妨阅读documentation的相关章节。 (使用MTGP32发生器生成位)

我不是CURAND的专家,但其他生成器(如XORWOW)没有这种类型的限制,所以如果您想要生成大量的独立线程状态很容易,请考虑其他发生器之一。使用您所概述的特定方法,MTGP32生成器似乎被限制在约200 * 256个独立线程生成。与我在评论中所说的相反(对于其他生成器类型,这是正确的),对于多达256个线程的块,MTGP32状态在一种状态下似乎是足够的。 documentation(参考第二个示例)中给出的示例使用该类型的状态生成和线程块分层结构。

+0

谢谢。我在想我每个线程需要一个状态;但是看起来,每个块的一个状态就足以在每个线程上生成一个不同的统一数字,而与所有其他块无关,从您向我展示的示例中。 – Cokes