我正在尝试使用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]:浮点随机值为: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 :(得分:4)
这里有一些问题,我在这里解决第一个问题,让你开始:
一般要点
具体要点
threadIdx.x + blockIdx.x * blockDim.x
(*而不是+)。用于生成最高质量的并行伪随机数 实验应该分配一个独特的种子。在一个实验中, 应为每个计算线程分配一个唯一的序列 号。
最后,你每个块运行两个线程,这非常低效。查看“最大化利用率”部分中的“CUDA C编程指南”以获取更多信息,但是您应该寻求每个块启动多个32个线程(例如128,256)和大量块(例如数万个) )。如果你的问题很小,那么考虑一次运行多个问题(在单个内核启动中批处理或在不同的流中作为内核来获得并发执行)。