2012-09-04 2 views
1

Il s'agit d'un programme de multiplication matricielle sur l'architecture CUDA. Ce code fonctionne correctement lorsque la taille du tableau est de 30 x 30 mais donne une sortie sous la forme d'une série de 0 lorsque la taille est supérieure. J'utilise une instance ec2 standard pour CUDA hébergée sur une machine linux. Quelqu'un peut-il comprendre la raison?échec du programme pour la matrice 30 x 30

#include <stdio.h> 
#define SIZE 30 

__global__ void matrix_multiply(float *input1,float *input2,float *output,int dimension){ 


    int input1_index = threadIdx.x/dimension * dimension; 
    int input2_index = threadIdx.x % dimension; 
    int i=0; 
    for(i =0; i <dimension; i++){ 
     output[threadIdx.x] += input1[input1_index + i] * input2[input2_index + i * dimension]; 
    } 
} 
int main(){ 
    int i,j,natural_number=1; 
    float input1[SIZE][SIZE],input2[SIZE][SIZE],result[SIZE][SIZE]={0}; 
    float *c_input1,*c_input2,*c_result; 
    for(i=0;i<SIZE;i++){ 
     for(j=0;j<SIZE;j++){ 
      input1[i][j]=input2[i][j]=natural_number++; 
     } 
    } 
    cudaMalloc((void**)&c_input1,sizeof(input1)); 
    cudaMalloc((void**)&c_input2,sizeof(input2)); 
    cudaMalloc((void**)&c_result,sizeof(result)); 
    cudaMemcpy(c_input1,input1,sizeof(input1),cudaMemcpyHostToDevice); 
    cudaMemcpy(c_input2,input2,sizeof(input2),cudaMemcpyHostToDevice); 
    cudaMemcpy(c_result,result,sizeof(result),cudaMemcpyHostToDevice); 

    matrix_multiply<<<1,SIZE * SIZE>>>(c_input1,c_input2,c_result,SIZE); 
    if(cudaGetLastError()!=cudaSuccess){ 
     printf("%s\n",cudaGetErrorString(cudaGetLastError())); 
    } 
    cudaMemcpy(result,c_result,sizeof(result),cudaMemcpyDeviceToHost); 
    for(i=0;i<SIZE;i++){ 
     for(j=0;j<SIZE;j++){ 
      printf("%.2f ",result[i][j]); 
     } 
     printf("\n"); 
    } 
    cudaFree(c_input1); 
    cudaFree(c_input2); 
    cudaFree(c_result); 
    return 0; 
} 

Répondre

3

Vous avez probablement un maximum de 1 024 threads par bloc sur votre GPU. 30 x 30 = 900, donc cela devrait être OK, mais par ex. 40 x 40 entraînerait un échec du lancement du noyau (message à retenir: vérifiez toujours les erreurs!).

Vous souhaitez probablement envisager d'organiser vos données différemment, par ex. SIZE blocs de SIZE fils puis appeler le noyau comme:

matrix_multiply<<<SIZE, SIZE>>>(c_input1,c_input2,c_result,SIZE); 

(Il est évident que vous devez modifier votre indexation de tableau dans le code du noyau, par exemple utiliser l'index de bloc comme la ligne et l'indice de fil comme la colonne

+0

Je vais vérifier dès que la machine sera à nouveau accessible pour moi. – Terminal

+0

Et en fait, j'ai vérifié les erreurs après avoir appelé la fonction matrix_multiply. Où d'autre devrais-je appeler la fonction? – Terminal

+0

fonctionne bien maintenant. Y at-il des limites similaires pour le nombre de blocs parallèles également. J'ai appelé l'appel avec matrix_multiply << <1,SIZE*SIZE>>. Son obtention échoue quelque part après 200. – Terminal

2

Vous invoquez le noyau avec une configuration de 1 grille avec la taille 30x30:

matrix_multiply<<<1, SIZE * SIZE>>>(c_input1,c_input2,c_result,SIZE); 

Il n'y a pas assez pour traiter les sujets plus.