2016-03-25 10 views
1

Ich möchte d_t globale 2D-Array-Variable mit "printf" innerhalb der Hauptmethode zu drucken. Aber ich habe eine Compiler-Warnung sagen, dass:Zugriff auf Geräte-2D-Array globale Variable von Host

eine __device__ Variable „D_t“ kann nicht direkt in einer Host-Funktion gelesen wird

Wie kann ich globales 2D-Array-Variable von Gerät kopieren zu hosten und dann drucken die erste Spalte jeder Zeile?

__device__ double *d_t; 

__device__ size_t d_gridPitch; 


__global__ void kernelFunc() 
{ 
    int i = blockIdx.x * blockDim.x + threadIdx.x; 

    double* rowt = (double*)((char *)d_t + i * d_gridPitch); 
    rowt[0] = rowt[0] + 40000; 

} 


int main() 
{ 
    int size = 16; 
    size_t d_pitchLoc; 
    double *d_tLoc; 

    cudaMallocPitch((void**)&d_tLoc, &d_pitchLoc, size * sizeof(double), size); 
    cudaMemset2D(d_tLoc, d_pitchLoc, 0, size * sizeof(double), size); 

    cudaMemcpyToSymbol(d_gridPitch, &d_pitchLoc, sizeof(int)); 
    cudaMemcpyToSymbol(d_t, & d_tLoc, sizeof(d_tLoc)); 

    kernelFunc<<<1,size>>>(); 

    for(int i=0; i< size; i++){ 
     double* rowt = (double*)((char *)d_t + i * d_gridPitch); 
     printf("%.0f, ",rowt[0]); 
    } 

    cudaDeviceReset(); 

    return 0; 
} 
+0

Die 'cudaMemcpy2D' -Funktion wird verwendet, um zu oder von einer geneigten Zuweisung zu kopieren (d. H. Erstellt mit' cudaMallocPitch'). [Hier] (http://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1g3a58270f6775efe56c65ac47843e7cee) ist die API-Dokumentation für 'cudaMemcpy2D'. Wenn Sie auf diesem CUDA-Tag suchen, finden Sie * viele * Fragen und Antworten, die die richtige Verwendung demonstrieren, wie z. B. [diese] (http://stackoverflow.com/questions/35771430/cuda-cudallocpitch-cudamemcpy2d-with-2d- Array-Fehler). Verwenden Sie [ordnungsgemäße CUDA-Fehlerprüfung] (http://stackoverflow.com/questions/14038589). –

Antwort

1

Wie in den Kommentaren angegeben, die cudaMemcpy2D API ist für genau diese Aufgabe konzipiert. Sie müssen einen Hostspeicherpuffer oder -container zuordnen oder statisch definieren, um als Speicher für die Daten vom Gerät zu fungieren, und dann die Schrittweite dieses Hostpuffers dem cudaMemcpy2D-Aufruf zuweisen. Die API verarbeitet die Tonhöhenumwandlung ohne weitere Eingriffe auf der Anruferseite.

Wenn Sie die Druckschleife mit so etwas wie diese ersetzen:

double* h_t = new double[size * size]; 
cudaMemcpy2D(h_t, size * sizeof(double), d_tLoc, d_pitchLoc, 
     size * sizeof(double), size, cudaMemcpyDeviceToHost); 
for(int i=0, j=0; i< size; i++){ 
    std::cout << h_t[i * size + j] << std::endl; 
} 

[Anmerkung I iostream hier für den Druck bin mit. CUDA verwendet einen C++ - Compiler zum Kompilieren von Host-Code und Sie sollten iostream Funktionen über cstdio bevorzugen, da diese weniger fehleranfällig sind und die Diagnose auf den meisten Plattformen verbessern.

Sie können sehen, dass das API-Anrufformular sehr ähnlich zu dem cudaMemset2D Anruf ist, den ich für Sie in Ihrer letzten Frage zur Verfügung gestellt habe.

Verwandte Themen