2016-04-17 15 views
1

Ich versuche, eine Reihe von Zufallszahlen zu generieren, gibt es nur 1 und Null. Der folgende Code funktioniert fast. Wenn ich den Druck für die Schleife mache, merke ich, dass ich manchmal eine Zahl habe, die nicht 1 oder 0 erzeugt. Ich weiß, dass mir etwas fehlt, nur nicht sicher, was. Ich denke, es ist ein Gedächtnisfehler.cuda Zufallszahl nicht immer 0 und 1 zurück

#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; 
} 

Was ich versuche zu tun, ist einen genetischen Algorithmus von dieser Seite zu transformieren.

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

Ich dachte, es ist ein gutes Problem CUDA wäre zu lernen und Spaß an der gleichen Zeit hat.

Der erste Teil besteht darin, mein zufälliges Array zu generieren.

+0

@PaulR: Während das stimmt, ist es in diesem Fall irrelevant. Der Rückgabewert des Zufallsgenerators ist nicht vorzeichenbehaftet, daher wird der Modulo-Nenner auf unsigned hochgestuft. Es können keine negativen Werte am Modulo teilnehmen und es tritt kein unerwartetes Verhalten auf. – talonmies

+0

@talonmies: danke - ich habe falsch geraten - ich werde meinen Kommentar löschen. –

Antwort

4

Das Problem hier ist, dass sowohl Ihre setup_kernel als auch generate_kernel nicht wegen Speicher-Out-of-Bounds-Zugriff vollständig ausgeführt werden. Beide Kernel erwarten, dass es für jeden Thread einen Generatorstatus gibt, Sie ordnen dem Gerät jedoch nur einen einzigen Status zu. Dies führt dazu, dass die Speicher- und Schreibvorgänge für beide Kernel außerhalb des zulässigen Bereichs ausgeführt werden. Ändern Sie dies:

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

um so etwas wie

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

, so dass Sie einen Generator Zustand pro Thread haben Sie ausgeführt werden, und die Dinge sollten anfangen zu arbeiten. Wenn Sie versucht hätten, Fehler entweder über den Runtime-API-Rückkehrstatus oder mithilfe von cuda-memcheck zu überprüfen, wäre die Fehlerquelle sofort ersichtlich gewesen.

+0

Das war es. Danke, das habe ich verpasst und dachte, dass es ein Speicherproblem sein muss. Ich war mir nicht sicher wo. Das Programm funktioniert jetzt. –

+1

Wenn die Antwort das Problem gelöst hat, sollten Sie es akzeptieren. – rossum