2011-02-17 27 views
15

Soy nuevo en CUDA. Cómo asignar una matriz 2D de tamaño MXN?. Cómo atravesar esa matriz en CUDA ?. Dame un código de muestra. ................................................. ...........................................¿Cómo usar matrices 2D en CUDA?

Hola .. Gracias por responder. Usé tu código en el siguiente programa. Pero no estoy obteniendo resultados correctos.

__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<BLOCK_SIZE;i++) 
     for(int j=0;j<BLOCK_SIZE;j++) 
     { 
     d_A[i][j]=i+j; 
     d_B[i][j]=i+j; 
     } 


    dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE); 
    dim3 dimGrid(GRID_SIZE, GRID_SIZE); 

    test<<<dimGrid, dimBlock>>>(d_A,d_B,d_C); 

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

    for(int i=0;i<BLOCK_SIZE;i++) 
     for(int j=0;j<BLOCK_SIZE;j++) 
     { 
     printf("%d\n",C[i][j]); 

     } 
} 

Por favor, ayúdame.

+16

Podría ser mucho más amable, no le hará daño. – karlphillip

+1

No puede recuperar el valor de la matriz 2D con cudaMemcpy, en su lugar debe usar cudaMallocPitch o cudaPitchPtr con cudaMalloc3D, ya que @Dave dijo – ardiyu07

Respuesta

16

cómo asignar matriz 2D:

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 initialization */ 

dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE); // so your threads are BLOCK_SIZE*BLOCK_SIZE, 256 in this case 
dim3 dimGrid(GRID_SIZE, GRID_SIZE); // 1*1 blocks in a grid 

YourKernel<<<dimGrid, dimBlock>>>(d_A,d_B); //Kernel invocation 
} 

cómo atravesar esa matriz:

__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; 
/* whatever you wanna do with d_A[][] and d_B[][] */ 
} 

espero que esto sea útil

y también se puede referir a CUDA Programming Guide página 22 sobre la matriz Multiplicación

+3

@ user621508 mientras esto funciona, solo crea una enorme matriz lineal en la memoria del dispositivo. También puede usar [cudaMalloc3D] (http://developer.download.nvidia.com/compute/cuda/3_2/toolkit/docs/online/group__CUDART__MEMORY_g04a7553c90322aef32f8544d5c356a10.html#g04a7553c90322aef32f8544d5c356a10) para asignar matrices bidimensionales que están optimizadas para 2D- acceso a los datos. No sabía si solo quería indexar una matriz 2D o el rendimiento. –

+6

Donde id cudaMalloc en el código de aboce? –

+2

@ username_4567, eso es lo que/* d_Una inicialización */representa. Sin embargo, la liberación de memoria está ausente. –

4

La mejor manera sería almacenar un dos- matriz dimensional A en su forma de vector. Por ejemplo, usted tiene una matriz A nxm tamaño, y es el elemento (i, j) en puntero a la representación puntero será

A[i][j] (with i=0..n-1 and j=0..m-1). 

En una forma de vector se puede escribir

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

Uso de uno En este caso, la matriz dimensional simplificará el proceso de copia, que sería simple:

double *A,*dev_A; //A-hous pointer, dev_A - device pointer; 
A=(double*)malloc(n*m*sizeof(double)); 
cudaMalloc((void**)&dev_A,n*m*sizeof(double)); 
cudaMemcpy(&dev_A,&A,n*m*sizeof(double),cudaMemcpyHostToDevice); //In case if A is double 
Cuestiones relacionadas