2012-09-17 142 views
3

我试图使用CURAND库来生成随机数,这是完全相互独立的从0到100因此我给时间作为种子给每个线程并指定“ id = threadIdx.x + blockDim.x * blockIdx.x“作为序列和偏移量。 然后获得随机数作为浮动后,我乘以100,并采取其整数值。现在制作CURAND从均匀分布生成不同的随机数

,我面临的问题是,它得到相同的随机数的线程[0,0]和[0,1],无论多少次,我跑这是11我无法代码了解我做错了什么。请帮忙。

我贴我下面的代码:

#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 
#include<curand_kernel.h> 
#include "util/cuPrintf.cu" 
#include<time.h> 

#define NE WA*HA //Total number of random numbers 
#define WA 2 // Matrix A width 
#define HA 2 // Matrix A height 
#define SAMPLE 100 //Sample number 
#define BLOCK_SIZE 2 //Block size 

__global__ void setup_kernel (curandState * state, unsigned long seed) 
{ 
int id = threadIdx.x + blockIdx.x + blockDim.x; 
curand_init (seed, id , id, &state[id]); 
} 

__global__ void generate(curandState* globalState, float* randomMatrix) 
{ 
int ind = threadIdx.x + blockIdx.x * blockDim.x; 
if(ind < NE){ 
    curandState localState = globalState[ind]; 
    float stopId = curand_uniform(&localState) * SAMPLE; 
    cuPrintf("Float random value is : %f",stopId); 
    int stop = stopId ; 
    cuPrintf("Random number %d\n",stop); 
    for(int i = 0; i < SAMPLE; i++){ 
      if(i == stop){ 
        float random = curand_normal(&localState); 
        cuPrintf("Random Value %f\t",random); 
        randomMatrix[ind] = random; 
        break; 
      } 
    } 
    globalState[ind] = localState; 
} 
} 

///////////////////////////////////////////////////////// 
// Program main 
///////////////////////////////////////////////////////// 

int main(int argc, char** argv) 
{ 

// 1. allocate host memory for matrix A 
unsigned int size_A = WA * HA; 
unsigned int mem_size_A = sizeof(float) * size_A; 
float* h_A = (float*) malloc(mem_size_A); 
time_t t; 

// 2. allocate device memory 
float* d_A; 
cudaMalloc((void**) &d_A, mem_size_A); 

// 3. create random states  
curandState* devStates; 
cudaMalloc (&devStates, size_A*sizeof(curandState)); 

// 4. setup seeds 
int n_blocks = size_A/BLOCK_SIZE; 
time(&t); 
printf("\nTime is : %u\n",(unsigned long) t); 
setup_kernel <<< n_blocks, BLOCK_SIZE >>> (devStates, (unsigned long) t); 
// 4. generate random numbers 
cudaPrintfInit(); 
generate <<< n_blocks, BLOCK_SIZE >>> (devStates,d_A); 
cudaPrintfDisplay(stdout, true); 
cudaPrintfEnd(); 
// 5. copy result from device to host 
cudaMemcpy(h_A, d_A, mem_size_A, cudaMemcpyDeviceToHost); 


// 6. print out the results 
printf("\n\nMatrix A (Results)\n"); 
for(int i = 0; i < size_A; i++) 
{ 
    printf("%f ", h_A[i]); 
    if(((i + 1) % WA) == 0) 
     printf("\n"); 
} 
printf("\n"); 

// 7. clean up memory 
free(h_A); 
cudaFree(d_A); 

} 

输出,我得到的是:

时间是:1347857063 [0,0]:浮法随机值:11.675105 [0,0 ]:随机数11 [0,0]:随机值0.358356 [0,1]:浮点随机值为:11.675105 [0,1]:随机数11 [0,1]:随机值0.358356 [ 1,0]:浮点随机值为:63.840496 [1,0]:随机数63 [1,0]:随机值0.696459 [1,1]:浮动随机值:44.712799 [1,1]:随机数44 [1,1]:随机值0.735049

+0

使用CUDA 5.0我无法重现此问题。我运行了你的代码,它创建了四个完全不同的随机值。你可以尝试升级到CUDA 5.0 RC吗?注意我也用'-arch = sm_20'编译,所以我可以使用'printf',因为我现在没有'cuPrintf'了。 – harrism

+0

我使用的是CUDA 4.2 ...请问您可以使用此版本运行代码并检查,因为我无法找到要在Nvidia上下载CUDA 5.0 RC的位置。 – user1439690

+1

[这是它](http://developer.nvidia.com/cuda/cuda-pre-production)。请尝试。顺便说一句,谷歌很擅长找到这些东西。 :) – harrism

回答

4

有几个事情错在这里,我在这里解决的第一批,让你开始:

一般分

  • 请检查所有CUDA API调用的返回值,请参阅here获取更多信息。
  • 请运行cuda-memcheck检查显而易见的事情,如超出边界访问。

具体点

  • 当分配的RNG状态空间,你应该有空间,每个线程一个状态(你现在有每个矩阵元素不是一个)。
  • 您在setup_kernel()中的线程ID计算错误,应该是threadIdx.x + blockIdx.x * blockDim.x(*而不是+)。
  • 您使用线程ID的序列号以及偏移量,您应该只设置在cuRAND手册中描述的偏移为零:

提供最高质量的并行伪随机数生成,每个 实验应分配一个独特的种子。在一个实验中,每个计算线程应该分配一个唯一的序列号码 。

最后你每块运行两个线程,这是非常低效的。查看“CUDA C编程指南”中的“最大化利用率”部分以获取更多信息,但您应该希望启动每块32个线程(例如128,256)和大量块(例如数万)。如果问题很小,那么可以考虑一次运行多个问题(或者在单个内核启动时进行批处理,或者作为不同流中的内核进行批处理以获得并发执行)。

+0

我没有得到为每个线程分配1个状态的空间,因为根据我的理解,每个线程都会生成一个随机数字对应于我的矩阵中的一个元素。无论如何,你发现正确的错字错误... setup_kernel中的id计算是问题。非常感谢汤姆:) – user1439690