1

我有一个 cuda 应用程序,我想在其中生成 0 到 1 之间的随机数。我编写了一个虚拟代码,其中一个大小为 8x256 的矩阵将被内核生成的随机数填充。我的原始矩阵类似于 8XBIG_NUMBER。但可能我在我的代码中遗漏了一些东西,因为我无法产生想要的结果。我在下面发布我的代码。

void main(int argc,char* argv[])    
{
    float *test_var,*dev_test;
    curandState *state;

    test_var = (float *)malloc(8*256*sizeof(float));
    memset(test_var,0,8*256*sizeof(float));

    cudaMalloc((void **)&dev_test,8*256*sizeof(float));
    cudaMemcpy(dev_test,test_var,8*256*sizeof(float),cudaMemcpyHostToDevice);
    dim3 gridDim(1,256/32,1);
    dim3 blockDim(8,32,1);
    cudaMalloc((void **)&state,8*256*sizeof(curandState));
    setup_kernel<<<gridDim,blockDim>>>(state,unsigned(time(NULL)));
    test_kernel<<<gridDim,blockDim>>>(state,dev_test);
    cudaMemcpy(test_var,dev_test,8*256*sizeof(float),cudaMemcpyDeviceToHost);
    system("PAUSE");

    for (int i=0;i<256;i++)
    {   for (int j=0;j<8;j++)
        { printf("%f\t",test_var[i*8+j]);
        }
        printf("\n");
    }

    cudaFree(dev_test);
    cudaFree(state);
    free(test_var);
    exit(0);
}

__global__ void setup_kernel(curandState *state,unsigned long seed)
{
    int id_col  = threadIdx.x + blockDim.x*blockIdx.x;
    int id_row = threadIdx.y+blockDim.y*blockIdx.y;

    curand_init(seed,(id_row*8+id_col),0,&state[id_row*8+id_col]);
}

__global__ void test_kernel(curandState *state,float *dev_test)
{
    int id_col  = threadIdx.x + blockDim.x*blockIdx.x;
    int id_row = threadIdx.y+blockDim.y*blockIdx.y;

     curandState local_state = state[id_row*8+id_col];
     dev_test[id_row*8+id_col] = curand(&local_state);   
     state[id_row*8+id_col] = local_state;
}

我想为矩阵中的每个单元格生成一个介于 0 和 1 之间的随机数。我非常感谢任何人的帮助。谢谢

4

1 回答 1

4

如果您参考 curand文档,您会注意到为您正在使用的设备 api 函数给出的声明:

__device__ unsigned int curand (curandState_t *state)

这个特定的 API 调用返回一个unsigned int. 因此,除非您以某种方式对其进行修改,否则您将不会获得浮点值。

由于它返回unsigned int值,因此一种可能的修改就是缩放结果:

 dev_test[id_row*8+id_col] = curand(&local_state)/(float)(0x0FFFFFFFFUL);

此修改应为您提供介于 0 和 1 之间的浮点值。但是,由于各种原因,这相当粗糙。正如评论中所建议的那样,选择可以为您执行此操作的设备生成器之一更有意义,例如:

 dev_test[id_row*8+id_col] = curand_uniform(&local_state);

我不是这方面的专家,但似乎多项分布基本上是离散分布。因此,如果您打算从 0 到 1 之间的浮点随机数开始,您将需要一些方法将连续值分布转换为离散分布。维基百科提供了一种从 0 之间的连续值随机数开始的方法和 1,根据我对该方法的阅读,curand_uniform分发/生成器将是一个合理的起点。

于 2013-06-22T16:10:47.680 回答