2016-03-29 48 views
-1

CUDAでCuRandライブラリを使用しようとしています。私は単にスレッドごとにランダムな整数を生成しようとしています。私のコードをチェックアウトし、私が間違ってやっているものを私に教えて、私はこれが動作しない理由を把握しようとしている私の髪を引っ張っていてくださいCudaカーネル内で乱数を生成

84 
84 
84 
84 
84 
5 

:以下は私の結果(明らかに非常にランダムではない)であります...

#include <stdio.h> 
#include <stdlib.h> 
#include <cuda.h> 
#include <curand.h> 
#include <curand_kernel.h> 

__device__ float generate(curandState* globalState, int ind) 
{ 
    //int ind = threadIdx.x; 
    curandState localState = globalState[ind]; 
    float RANDOM = curand_uniform(&localState); 
    globalState[ind] = localState; 
    return RANDOM; 
} 

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

__global__ void addToCount(int N, int *y, curandState* globalState) 
{ 
    int id = threadIdx.x + blockIdx.x * blockDim.x; 
while (id < N) 
{ 
    int number = generate(globalState, id) * 1000000; 
    printf("%i\n", number); 

    atomicAdd(&(y[0]), number); 
    id += blockDim.x * gridDim.x; 
} 
} 

int main(void) 
{ 
    int N = 5; 
    int *y, *d_y; 
    y = (int*)malloc(N*sizeof(int)); 

    cudaMalloc(&d_y, N * sizeof(int)); 
    cudaMemcpy(d_y, y, N * sizeof(int), cudaMemcpyHostToDevice); 

    curandState* devStates; 
    cudaMalloc (&devStates, N * sizeof(curandState)); 

    addToCount<<<2, 5>>>(N, d_y, devStates); 

    cudaMemcpy(y, d_y, N*sizeof(int), cudaMemcpyDeviceToHost); 
    printf("%i\n", *y); 
} 
+1

は、おそらくあなたは 'addToCount'カーネルを呼び出す前に、書いた' setup_kernel'を呼び出す必要がありますか? –

+0

適切なエラーチェックとデバッガの使用も役立ちます – Drop

答えて

1

AS @Robert Crovellaが彼のコメントで述べたように、カーネルをセットアップするのを忘れてしまった。 curand状態は、実際の乱数を提供する前にすべてのスレッドに対して初期化する必要があります。あなたはmainに変更する場合:

int main(void) 
{ 
    int N = 5; 
    int *y, *d_y; 
    y = (int*)malloc(N*sizeof(int)); 

    cudaMalloc(&d_y, N * sizeof(int)); 
    cudaMemcpy(d_y, y, N * sizeof(int), cudaMemcpyHostToDevice); 

    curandState* devStates; 
    cudaMalloc (&devStates, N * sizeof(curandState)); 
    srand(time(0)); 
    /** ADD THESE TWO LINES **/ 
    int seed = rand(); 
    setup_kernel<<<2, 5>>>(devStates,seed); 
    /** END ADDITION **/ 
    addToCount<<<2, 5>>>(N, d_y, devStates); 

    cudaMemcpy(y, d_y, N*sizeof(int), cudaMemcpyDeviceToHost); 
    printf("%i\n", *y); 
} 

あなたはデフォルトのコンパイルで素敵な結果を得る:

nvcc /tmp/so.cu -o /tmp/so 

$ /tmp/so 
900981 
469952 
494161 
31968 
880329 
2777391 
$ /tmp/so 
525835 
742594 
750423 
117137 
66318 
2202307 
$ /tmp/so 
919262 
60838 
89868 
57696 
770764 
1898428