2016-04-17 4 views
1

乱数を生成しようとしていますが、1と0しかありません。以下のコードはほとんど動作します。私がループのための印刷をするとき、私は1または0ではない数字を生成することがあることに気がついています。何か分からないことが分かっています。私はその記憶が誤っていると思う。cuda乱数は常に0と1を返しません。

#include <stdio.h> 
#include <curand.h> 
#include <curand_kernel.h> 
#include <math.h> 
#include <assert.h> 
#define MIN 1 
#define MAX (2048*20) 

#define MOD 2 // only need one and zero for each random value. 
#define THREADS_PER_BLOCK 256 

__global__ void setup_kernel(curandState *state, unsigned long seed) 
{ 
    int idx = threadIdx.x+blockDim.x*blockIdx.x; 
    curand_init(seed, idx, 0, state+idx); 
} 

__global__ void generate_kernel(curandState *state, unsigned int *result){ 

    int idx = threadIdx.x + blockDim.x*blockIdx.x; 
    result[idx] = curand(state+idx) % MOD; 
} 

int main(){ 

    curandState *d_state; 
    cudaMalloc(&d_state, sizeof(curandState)); 

    unsigned *d_result, *h_result; 
    cudaMalloc(&d_result, (MAX-MIN+1) * sizeof(unsigned)); 
    h_result = (unsigned *)malloc((MAX-MIN+1)*sizeof(unsigned)); 

    cudaMemset(d_result, 0, (MAX-MIN+1)*sizeof(unsigned)); 

    setup_kernel<<<MAX/THREADS_PER_BLOCK,THREADS_PER_BLOCK>>>(d_state,time(NULL)); 

    generate_kernel<<<MAX/THREADS_PER_BLOCK,THREADS_PER_BLOCK>>>(d_state, d_result); 

    cudaMemcpy(h_result, d_result, (MAX-MIN+1) * sizeof(unsigned), cudaMemcpyDeviceToHost); 

    printf("Bin: Count: \n"); 
    for (int i = MIN; i <= MAX; i++) 
    printf("%d %d\n", i, h_result[i-MIN]); 

    free(h_result); 
    cudaFree(d_result); 

    system("pause"); 
    return 0; 
} 

私がしようとしているのは、このサイトから遺伝子アルゴリズムを変換することです。

http://www.ai-junkie.com/ga/intro/gat3.html

私はCUDAを学ぶと同時に、いくつかの楽しみを持っていることは良い問題だろうと思いました。

最初の部分は私のランダム配列を生成することです。

+0

@PaulR:これは当てはまりますが、この場合は無関係です。ランダムジェネレータの戻り値は符号なしなので、モジュロ分母は符号なしに昇格されます。負の値はモジュロには参加できず、予期しない動作は発生しません。 – talonmies

+0

@talonmies:ありがとう - 私は間違っていると思った - 私は私のコメントを削除します。 –

答えて

4

ここでの問題は、範囲外のメモリアクセスのためにsetup_kernelgenerate_kernelの両方が完了していないことです。どちらのカーネルも、各スレッドのジェネレータ状態が存在することを期待していますが、デバイス上には1つの状態しか割り当てていません。この結果、両方のカーネルでメモリの読み書きが不安定になります。あなたが実行しているスレッドごとに1つの発電機の状態を持っている、そして物事が作業を開始する必要がありますように

curandState *d_state; 
cudaMalloc(&d_state, sizeof(curandState) * (MAX-MIN+1)); 

のようなものに

curandState *d_state; 
cudaMalloc(&d_state, sizeof(curandState)); 

:これを変更します。ランタイムAPIの戻り状況かcuda-memcheckを使用してエラーをチェックしようとした場合は、エラーの原因がすぐに明らかになります。

+0

それはそれでした。ありがとう、私はそれを逃して、メモリの問題でなければならないと考えた。ちょうどどこではわからなかった。プログラムは今働いています。 –

+1

答えが問題を解決したら、それを受け入れるべきです。 – rossum

関連する問題