2012-09-17 2 views
3

저는 CURAND 라이브러리를 사용하여 0에서 100까지 완전히 독립적 인 난수를 생성하려고합니다. 따라서 각 스레드에 시드를 부여하고 " id = threadIdx.x + blockDim.x * blockIdx.x "를 시퀀스 및 오프셋으로 사용합니다. 그런 다음 난수를 float로 가져온 후 정수를 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에서는이 문제를 재현 할 수 없습니다. 나는 당신의 코드를 돌렸고 완전히 다른 4 개의 무작위 값을 만들었다. CUDA 5.0 RC로 업그레이드 할 수 있습니까? 참고'-arch = sm_20'으로 컴파일 했으므로 더 이상'cuPrintf'가 없으므로'printf'를 사용할 수 있습니다. – harrism

+0

CUDA 4.2를 사용 중입니다 ...이 버전의 코드를 실행하고 Nvidia에서 CUDA 5.0 RC를 어디에서 다운로드 할 수 있는지 확인하십시오. – user1439690

+1

[여기 있습니다] (http://developer.nvidia.com/cuda/cuda-pre-production). 그것을 시도하십시오. BTW, Google은 이러한 것들을 찾는 데 아주 능숙합니다. :) – 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 계산이 문제였습니다. 고마워 Tom. :) – user1439690

관련 문제