15 Stimmen

Wie verwendet man 2D Arrays in CUDA?

Wie man ein 2D-Array der Größe MXN zuweist? Und wie man durch dieses Array in CUDA navigiert?

__global__ void test(int A[BLOCK_SIZE][BLOCK_SIZE], int B[BLOCK_SIZE][BLOCK_SIZE],int C[BLOCK_SIZE][BLOCK_SIZE])
{

    int i = blockIdx.y * blockDim.y + threadIdx.y;
    int j = blockIdx.x * blockDim.x + threadIdx.x;

    if (i < BLOCK_SIZE && j < BLOCK_SIZE)
        C[i][j] = A[i][j] + B[i][j];

}

int main()
{

    int d_A[BLOCK_SIZE][BLOCK_SIZE];
    int d_B[BLOCK_SIZE][BLOCK_SIZE];
    int d_C[BLOCK_SIZE][BLOCK_SIZE];

    int C[BLOCK_SIZE][BLOCK_SIZE];

    for(int i=0;i>>(d_A,d_B,d_C); 

    cudaMemcpy(C,d_C,BLOCK_SIZE*BLOCK_SIZE , cudaMemcpyDeviceToHost);

    for(int i=0;i

1 Stimmen

Sie können den Wert des 2D-Arrays nicht mit cudaMemcpy zurücknehmen, stattdessen müssen Sie cudaMallocPitch oder cudaPitchPtr mit cudaMalloc3D verwenden, wie @Dave gesagt hat.

20voto

ardiyu07 Punkte 1770

Wie man ein 2D-Array zuweist:

int main() {
    #define BLOCK_SIZE 16
    #define GRID_SIZE 1
    int d_A[BLOCK_SIZE][BLOCK_SIZE];
    int d_B[BLOCK_SIZE][BLOCK_SIZE];

    /* d_A-Initialisierung */

    dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE); // damit Ihre Threads BLOCK_SIZE*BLOCK_SIZE, 256 in diesem Fall sind
    dim3 dimGrid(GRID_SIZE, GRID_SIZE); // 1*1 Blöcke in einem Raster

    YourKernel<<>>(d_A,d_B); //Kernel-Aufruf
}

Wie man dieses Array durchläuft:

__global__ void YourKernel(int d_A[BLOCK_SIZE][BLOCK_SIZE], int d_B[BLOCK_SIZE][BLOCK_SIZE]){
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    if (row >= h || col >= w) return;
    /* was auch immer Sie mit d_A[][] und d_B[][] machen wollen */
}

Ich hoffe, das ist hilfreich, und Sie können auch CUDA Programming Guide über die Matrixmultiplikation nachschlagen

3 Stimmen

@user621508 während dies funktioniert, erstellt es nur ein riesiges lineares Array im Gerätespeicher. Sie können auch cudaMalloc3D verwenden, um zweidimensionale Arrays zuzuweisen, die für den 2D-Datenzugriff optimiert sind. Ich wusste nicht, ob Sie nur die Indizierung eines 2D-Arrays oder die Leistung wollten.

2 Stimmen

@username_4567, das bedeutet /* d_A-Initialisierung */. Allerdings fehlt das Freigeben des Speichers.

7 Stimmen

Der tatsächliche Inhalt der /* d_A-Initialisierung */ ist auch ein wichtiger Teil der Antwort. Können Sie ihn auch bereitstellen?

12voto

Suren Punkte 113

Der beste Weg wäre, ein zweidimensionales Array A in seiner Vektorform zu speichern. Zum Beispiel haben Sie eine Matrix A der Größe nxm, und ihr (i,j) Element in der Pointer-zu-Pointer-Darstellung wird sein

A[i][j] (mit i=0..n-1 und j=0..m-1). 

In Vektorform können Sie schreiben

A[i*n+j] (mit i=0..n-1 und j=0..m-1).

Die Verwendung eines eindimensionalen Arrays vereinfacht in diesem Fall den Kopiervorgang, der einfach wäre:

double *A,*dev_A; //A-Hauszeiger, dev_A - Gerätezeiger;
A=(double*)malloc(n*m*sizeof(double));
cudaMalloc((void**)&dev_A,n*m*sizeof(double));
cudaMemcpy(&dev_A,&A,n*m*sizeof(double),cudaMemcpyHostToDevice); //Falls A double ist

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X