random - 使 CURAND 从均匀分布中生成不同的随机数

标签 random cuda seed

我正在尝试使用 CURAND 库生成从 0 到 100 之间完全独立的随机数。因此我将时间作为每个线程的种子并指定“id = threadIdx.x + blockDim.x * blockIdx.x"作为序列和偏移量。 然后在得到随机数作为 float 后,我将它乘以 100 并取其整数值。

现在,我面临的问题是它为线程 [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]: float 随机值是:11.675105[0, 1]: 随机数 11 [0, 1]: Random Value 0.358356 [1, 0]: Float random value is : 63.840496[1, 0]: Random number 63 [1, 0]: Random Value 0.696459 [1, 1]: Float random value is : 44.712799[1, 1]: Random number 44 [1, 1]: 随机值 0.735049

最佳答案

这里有一些问题,我在这里解决第一个问题以帮助您入门:

一般要点

  • 请检查所有 CUDA API 调用的返回值,参见 here了解更多信息。
  • 请运行 cuda-memcheck 来检查明显的事情,例如越界访问。

具体要点

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

For the highest quality parallel pseudorandom number generation, each experiment should be assigned a unique seed. Within an experiment, each thread of computation should be assigned a unique sequence number.

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

关于random - 使 CURAND 从均匀分布中生成不同的随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12453312/

相关文章:

javascript - createJS - 容器中多个对象的随机移动

java - 如何用Java中另一个整数数组中的值随机填充ant int数组?

php - 如何使用 PHP 创建随机字符串?

python - 从 itertools 随机化链

c - 二维数组的倾斜内存分配是否更有效?

cuda - NPP 函数可以作为设备函数调用吗?

CUDA - atomicAdd(float) 不会添加非常小的值

javascript - 如何将单个文件指定为仅种子

database - 如何在 Mac OS X 应用程序中播种数据库

ruby-on-rails - 使用回形针在 heroku 中播种图像