2016-04-17 51 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由於超出界限的內存訪問而沒有運行到完成狀態。兩個內核都期望每個線程都會有一個發生器狀態,但是您只是在設備上分配一個狀態。這會導致兩個內核之間的內存讀取和寫入超出界限。更改此:

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

喜歡的東西

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

,讓你有每個正在運行的線程一點發電機的狀態,事情應該開始工作。如果您嘗試從運行時API返回狀態或使用cuda-memcheck檢查錯誤,則錯誤的來源將立即顯現。

+0

就是這樣。謝謝,我錯過了,並認爲它必須是一個記憶問題。只是不知道在哪裏。計劃正在工作。 –

+1

如果答案解決了問題,那麼你應該接受它。 – rossum