2016-05-07 10 views
-1

Ich habe gerade angefangen, CUDA zu lernen, und ich wollte ein Array (ein 2D-Array, das als 1D-Array dargestellt wurde) mit Zufallszahlen füllen. Ich folgte anderen Posts, um Zufallszahlen zu generieren, aber ich weiß nicht, ob es ein Problem mit der Generierung von Zahlen oder mit der Wiederherstellung des Speichers von dem Gerät oder irgendetwas anderem gibt. Das Problem ist, dass, obwohl ich versucht habe, eine Zelle des Arrays mit der ID des Threads zu füllen, der es anstellt, um die Ergebnisse nach dem Kopieren in den Host-Speicher zu sehen, erhalte ich ein Array, das mit 0 in irgendeinem gefüllt wird Position nach dem Wiederherstellen der Daten mit cudaMemcpy().Viele Nullen, die empfangen wurden, wenn cudaMemcpy() verwendet wurde

Ich programmiere auf Visual Studio 2013, mit Cuda 7.5, auf einem i5 2500k als mein Prozessor und eine 960 GTX-Grafikkarte.

Hier ist die Haupt-und die Methode, wo ich versuche, es zu füllen. Ich werde auch die cuRand-Initialisierung aktualisieren. Wenn du etwas anderes sehen willst, sag es mir einfach.

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

__global__ void poblar(int * adn, curandState * state){ 

    curandState localState = state[threadIdx.x]; 
    int random = curand(&localState); 
    adn[threadIdx.x] = random; 
    // It doesn't mind if i use the following instruction, the result is a lot of 0's 
    //adn[threadIdx.x] = threadIdx.x; 

} 

int main() 
{ 

    const int adnLength = NUMCROMOSOMAS * SIZECROMOSOMAS; // 256 * 128 (32.768) 
    const size_t adnSize = adnLength * sizeof(int); 
    int adnCPU[adnLength]; 
    int * adnDevice; 

    cudaError_t error = cudaSetDevice(0); 
    if (error != cudaSuccess) 
     exit(-EXIT_FAILURE); 

    curandState * randState; 
    error = cudaMalloc(&randState, adnLength * sizeof(curandState)); 
    if (error != cudaSuccess){ 
     cudaFree(randState); 
     exit(-EXIT_FAILURE); 
    } 
    //Here is initialized cuRand 
    setup_cuRand <<<1, adnLength >> > (randState, unsigned(time(NULL))); 

    error = cudaMalloc((void **)&adnDevice, adnSize); 

    if (error == cudaErrorMemoryAllocation){// cudaSuccess){ 
     cudaFree(adnDevice); 
     cudaFree(randState); 
     printf("\n error"); 
     exit(-EXIT_FAILURE); 
    } 


    poblar <<<1, adnLength >>> (adnDevice, randState); 
    error = cudaMemcpy(adnCPU, adnDevice, adnSize, cudaMemcpyDeviceToHost); 
    //After here, for any i, adnCPU[i] is 0 and i cannot figure what is wrong 
    if (error == cudaSuccess){ 
     for (int i = 0; i < NUMCROMOSOMAS; i++){ 
      for (int j = 0; j < SIZECROMOSOMAS; j++){ 
       printf("%i,", adnCPU[(i*SIZECROMOSOMAS) + j]); 
      } 
      printf("\n"); 
     } 
    } 

    return 0; 
} 

EDIT nach Antwort gelöst: Es gibt eine Besonderheit über die Antwort gegeben war, und ist, dass Sie eine geringere Anzahl von Threads (die Hälfte dieser Menge war für mich) benötigen, um richtig die Zufallszahlen auf Saatgut mit cuRand. Aus irgendeinem Grund konnte ich die Threads perfekt erstellen, aber ich konnte den Pseudozufallsalgorithmus nicht erzeugen.

+0

Der Code in dieser Frage ist unvollständig und kann nicht kompiliert oder ausgeführt werden. Die (jetzt geänderte) Frage, die Sie stellen, kann nur definitiv beantwortet werden, indem Sie den Code für 'setup_cuRand' sehen. Aber bitte bearbeiten Sie diese Frage nicht so lange, bis die angenommene Antwort nicht mehr relevant ist. Wenn Sie Fragen zum Seeding und zur Initialisierung des cuRand-Generators haben, fragen Sie ihn auf jeden Fall. Aber tu es in einer neuen Frage. Dies ist nicht Ihre Person helfen Thread, es ist eine Frage und Antwort-Paar, das für alle nützlich sein soll, nicht nur Sie. – talonmies

+0

@Talonmies Entschuldigung, wenn ich nicht einen korrekten Weg zur Lösung meiner Fehler befolgt habe. Ich hatte ein weiteres kleines Problem im Code und habe es benachrichtigt, bevor jemand den Code verwendet hat. Danach habe ich die Lösung gefunden und auch gepostet. Ich werde den Titel ein letztes Mal ändern, weil ein vorheriger von dem Problem am relevantesten war, das ich schließlich hatte (und dass ich nicht wusste, dass das das war). Ich möchte mich bei allen entschuldigen, wenn ich ein Verhalten hätte, das dem Lernen der Gemeinschaft schaden könnte. – Kaostias

Antwort

2

Die maximale Anzahl von Threads pro Block 1024 auf Ihrer Hardware, daher können Sie keinen Anruf mit adnLength planen, wenn es größer als 1024.

ist der Fehler, den Sie am meisten haben wahrscheinlich ein Anruf Konfigurationsfehler und es wird von cudaPeekAtLastError zurückgegeben, wie es vor jeder GPU-Arbeit auftritt, gleich nach dem Aufruf der dreifachen Winkelklammer. Tatsächlich kann cudaMemcpy es nicht zurückgeben, obwohl es Fehler von früheren asynchronen Aufrufen zurückgibt.

Der Fehler, der auftreten kann, ist cudaErrorLaunchOutOfResources.

+0

Um das zu lösen, habe ich gerade 256 Threads und 128mal Looping ausgeführt und es hat wirklich funktioniert. Danke vielmals. – Kaostias

+0

Gibt es ein Problem mit der Art, wie ich cuRand initialisiere? Die Zahlen, die ich erhalte, sind für jeden Thread gleich. – Kaostias

+0

Sie sollten ein Seeding-Schema so einrichten, dass jeder Thread einen anderen Wert ausgibt. Der Begriff der Subsequenz ist für Sie von Interesse. Dig in curand Dokumentation und vielleicht eine andere Frage, wenn Sie immer noch stecken. –