La Multiplication de matrice à l'aide de CUDA
Je suis frappé avec la multiplication de Matrice sur CUDA. Le produit résultant de la matrice est toujours à zéro. J'ai lu quelques exemples de codes comme la multiplication de matrice dans cuda pour résoudre mon problème, mais en vain.
En dehors de erratiques résultat de 0, la taille maximale de la "Largeur" (code ci-dessous) n'est même pas 512. Je n'étais pas en mesure de débogage où se trouve le problème. Peut-être que nous pouvons en discuter sur StackOverflow.
Je fais référence "de la Programmation des Processeurs Massivement Parallèles"
#include<cuda.h>
#include<stdio.h>
int main(void) {
void MatrixMultiplication(float *, float *, float *, int);
const int Width = 5;
float M[Width*Width], N[Width*Width], P[Width*Width];
for(int i = 0; i < (Width*Width) ; i++) {
M[i] = 5;
N[i] = 5;
P[i] = 0;
}
MatrixMultiplication(M, N, P, Width);
for(int i = 0; i < (Width*Width) ; i++) {
printf("%d \n", P[i]);
}
int quit;
scanf("%d",&quit);
return 0;
}
//Matrix multiplication kernel - thread specification
__global__ void MatrixMulKernel(float *Md, float *Nd, float *Pd, int Width) {
//2D Thread ID
int tx = threadIdx.x;
int ty = threadIdx.y;
//Pvalue stores the Pd element that is computed by the thread
float Pvalue = 0;
for(int k = 0; k < Width ; ++k) {
float Mdelement = Md[ty*Width + k];
float Ndelement = Nd[k*Width + tx];
Pvalue += (Mdelement*Ndelement);
}
Pd[ty*Width + tx] = Pvalue;
}
void MatrixMultiplication(float *M, float *N, float *P, int Width) {
int size = Width*Width*sizeof(float);
float *Md, *Nd, *Pd;
//Transfer M and N to device memory
cudaMalloc((void**)&Md, size);
cudaMemcpy(Md,M,size,cudaMemcpyHostToDevice);
cudaMalloc((void**)&Nd, size);
cudaMemcpy(Nd,N,size,cudaMemcpyHostToDevice);
//Allocate P on the device
cudaMalloc((void**)&Pd,size);
//Setup the execution configuration
dim3 dimBlock(Width,Width);
dim3 dimGrid(1,1);
//Launch the device computation threads!
MatrixMulKernel<<<dimGrid,dimBlock>>>(Md,Nd,Pd,Width);
//Transfer P from device to host
cudaMemcpy(P,Pd,size,cudaMemcpyDeviceToHost);
//Free device matrices
cudaFree(Md);
cudaFree(Nd);
cudaFree(Pd);
}
Pour obtenir la bonne mise en forme du code, vous avez besoin pour le retrait de tous les codes avec 4 espaces. Vous pouvez le faire facilement en mettant en valeur votre code et en appuyant sur
Merci Jeff! Allais le faire
Si vous n'avez pas à vous en tenir à votre propre code, le CUDA C Guide de Programmation a un merveilleux matrice-mul mise en œuvre qui peut manipuler des matrices avec d'autres dimensions que les puissances de deux et est optimisée en utilisant la mémoire partagée. Le recommande fortement pour l'utilisation dans le monde réel et pour l'apprentissage.
gouttes d'eau font un puissant océan. Pour arriver à un niveau que vous avez à suivre, étape par étape. par exemple, Si j'ai utiliser directement le code donné dans l'Annexe A, je risque de ne jamais arriver à savoir ce qu' __syncthreads() - ne pas considérer l'amicale de la syntaxe 😉
Ctrl + K
.Merci Jeff! Allais le faire
Si vous n'avez pas à vous en tenir à votre propre code, le CUDA C Guide de Programmation a un merveilleux matrice-mul mise en œuvre qui peut manipuler des matrices avec d'autres dimensions que les puissances de deux et est optimisée en utilisant la mémoire partagée. Le recommande fortement pour l'utilisation dans le monde réel et pour l'apprentissage.
gouttes d'eau font un puissant océan. Pour arriver à un niveau que vous avez à suivre, étape par étape. par exemple, Si j'ai utiliser directement le code donné dans l'Annexe A, je risque de ne jamais arriver à savoir ce qu' __syncthreads() - ne pas considérer l'amicale de la syntaxe 😉
OriginalL'auteur Gaurav Kalra | 2011-02-16
Vous devez vous connecter pour publier un commentaire.
Vous va bien jusqu'à ce point:
Je l'ai changé pour %f (parce que c'est un float) et ils ont tous l'impression de bien 🙂
OriginalL'auteur ardiyu07
J'ai compris ce qui n'allait pas. Nous allons l'analyser :
Point 1 : La quête pour supprimer le jamais monotone "zéro valeur"
Comme indiqué, vous devez remplacer
printf("%d \n", P[i]);
commeprintf("%f \n", P[i]);
Point 2 : Pourquoi le programme ne fonctionne pas avec une valeur de Largeur de 512 ?
En fait ce sera un échec, même pour une petite valeur telle que 23. Pourquoi ? Parce que 23*23 > 512 (Le nombre maximal de threads qu'un GPU peut avoir par bloc comme d'aujourd'hui!)
OriginalL'auteur Gaurav Kalra
Dans votre MatrixMulKernel fonction de votre boucle for est comme
Au lieu de
Width
, vous devez utiliserWidth*Width
que votre tableau est de tailleWidth*Width
.comme @Gaurav dit, la Largeur*Largeur seul coup la mémoire..
OriginalL'auteur Algorithmist