| 
		  	 Dans ce fichier, on commence par inclure le fichier calcul_cuda.h :  
	
		
			
1 
			 | 
			
#include "calcul_cuda.h"
 
			 | 
 
	
 
		Ensuite, on définit une structure qui contient tout les variables globales dont on a besoin pour le calcul :  
	
		
			
1
2
3
4
5 
			 | 
			
struct GlobalVarMatrix{
	float *matriceLeftd;
	float *matriceRightd;
	float *matriceResultd;
};
			 | 
 
	
 
		Ensuite on crée la variable globale proprement dite, et on l'initialise :  
	
		
			
1 
			 | 
			
GlobalVarMatrix globalVarMatrix = {NULL, NULL, NULL};
			 | 
 
	
 
		Maintenant, on peut créer la fonction qui fera le calcul :  
	
		
			
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 
			 | 
			
__global__ void matrixMulKernel(float * matriceResultd, float * matriceLeftd, float * matriceRightd, int width){
		int tx = threadIdx.x;
	int ty = threadIdx.y;
		float pResult = 0;
	for(int i = 0; i < width; ++i){
		float mdElement = matriceLeftd[ty*width + i];
		float ndElement = matriceRightd[i*width + tx];
		pResult        += mdElement * ndElement;
	}
			matriceResultd[ty*width + tx] = pResult;
}
			 | 
 
	
 
		
Heu... Il ne manque pas des boucles là ? On fait bien un produit matriciel avec 3 boucles.
 
		
Oui, il y a bien trois boucles dans un produit matriciel, mais qui vous dit qu'il en manque deux ?
 
		
Ben, il n'y a qu'un seul for
 
		
Voici une des subtilité de la programmation CUDA, dans notre programme il y aura bien trois boucles, mais c'est la carte graphique qui fera les deux boucles principales, en hardware et pas en software. C'est donc le matériel qui fait deux boucles à notre place. Donc le compte est bon.
 
		
En fait ce sont les variables threadIdx.x et threadIdx.y qui nous permettent de faire deux boucles avec le matériel.
 
		
Et rappeler-vous qu'une fonction __global__ ne retourne rien.
 
		Nous pouvons donc ajouter la fonction qui appelle notre fonction CUDA :  
	
		
			
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 
			 | 
			
///fonction qui appelle la fonction en cuda de multiplication de matrice
extern "C" void matrixMulOnDevice(float * matriceResult, float * matriceLeft, float * matriceRight, int width){
		int size = width*width*sizeof(float);
		cudaMalloc(&globalVarMatrix.matriceLeftd, size);
	cudaMemcpy(globalVarMatrix.matriceLeftd, matriceLeft, size, cudaMemcpyHostToDevice) ;
	cudaMalloc(&globalVarMatrix.matriceRightd, size);
	cudaMemcpy(globalVarMatrix.matriceRightd, matriceRight, size, cudaMemcpyHostToDevice);
		cudaMalloc(&globalVarMatrix.matriceResultd, size);
		dim3 dimGrid(1, 1);
		dim3 dimBlock(width, width);
		matrixMulKernel<<<dimGrid, dimBlock>>>(globalVarMatrix.matriceLeftd, globalVarMatrix.matriceRightd, globalVarMatrix.matriceResultd, width);
		cudaMemcpy(matriceResult, globalVarMatrix.matriceResultd, size, cudaMemcpyDeviceToHost);
		cudaFree(globalVarMatrix.matriceLeftd);
	cudaFree(globalVarMatrix.matriceRightd);
	cudaFree(globalVarMatrix.matriceResultd);
}
			 | 
 
	
 
		
N'oubliez pas que cudaMalloc prend un void** donc il faut un & devant le pointeur à allouer.
 
		Voici le fichier calcul_cuda.cu en entier :  
	
		
			
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 
			 | 
			
#include "calcul_cuda.h"
///on définit une variable globale pour avoir les matrices pour la carte graphique 
struct GlobalVarMatrix{
	float *matriceLeftd;
	float *matriceRightd;
	float *matriceResultd;
};
GlobalVarMatrix globalVarMatrix = {NULL, NULL, NULL};
///fonction qui va calculer la multiplication de la matrice dans la carte graphique
__global__ void matrixMulKernel(float * matriceResultd, float * matriceLeftd, float * matriceRightd, int width){
		int tx = threadIdx.x;
	int ty = threadIdx.y;
		float pResult = 0;
	for (int i = 0; i < width; ++i){
		float mdElement = matriceLeftd[ty*width + i];
		float ndElement = matriceRightd[i*width + tx];
		pResult        += mdElement * ndElement;
	}
			matriceResultd[ty*width + tx] = pResult;
}
///fonction qui appelle la fonction en cuda de multiplication de matrice
extern "C" void matrixMulOnDevice(float * matriceResult, float * matriceLeft, float * matriceRight, int width){
		int size = width*width*sizeof(float);
		cudaMalloc(&globalVarMatrix.matriceLeftd, size);
	cudaMemcpy(globalVarMatrix.matriceLeftd, matriceLeft, size, cudaMemcpyHostToDevice) ;
	cudaMalloc(&globalVarMatrix.matriceRightd, size);
	cudaMemcpy(globalVarMatrix.matriceRightd, matriceRight, size, cudaMemcpyHostToDevice);
		cudaMalloc(&globalVarMatrix.matriceResultd, size);
		dim3 dimGrid(1, 1);
		dim3 dimBlock(width, width);
		matrixMulKernel<<<dimGrid, dimBlock>>>(globalVarMatrix.matriceLeftd, globalVarMatrix.matriceRightd, globalVarMatrix.matriceResultd, width);
		cudaMemcpy(matriceResult, globalVarMatrix.matriceResultd, size, cudaMemcpyDeviceToHost);
		cudaFree(globalVarMatrix.matriceLeftd);
	cudaFree(globalVarMatrix.matriceRightd);
	cudaFree(globalVarMatrix.matriceResultd);
}
			 | 
 
	
 
		Vous pouvez le récupérer ici.  
 |