Ha aufait je vais ecrire en francais a partir de cet article, apres tout il n'y a pas d'articles en francais sur cuda (en tout cas pas la derniere fois que j'ai regarde :p) et puis ca me permettra surement d'etre plus clair.

Donc, personnellement les cudaMemcpy, cudaFree etc, ca va 5minutes, mais ca va me gonfler de devoir taper cudaMemcpyHostToDevice a longueur de temps, donc je me suis code une petite classe pour faire officer de "container" cuda. Il n'y aura rien d'extraordinaire la dedans, juste une petite classe fonctionnelle :)

Un rapide "cahier des charges", la classe doit pouvoir :

  • Envoyer des donnees vers la carte graphique
  • S'occuper seule comme une grande d'allouer la memoire dans la memoire de la carte graphique
  • liberer cet espace
  • Permettre de recuperer le pointeur vers le device pour pouvoir appeler les kernels
  • Pouvoir fonctionner avec n'importe quel type
  • Recuperer les donnees traitees par la CG

Ce qui nous donne la declaration de classe suivante :

template <typename T>
class		CudaContainer
{
public:
	CudaContainer(T* var, size_t size);
	CudaContainer(T& var);
	CudaContainer(size_t size);
	~CudaContainer();
	void		sendToDevice();
	void		getFromDevice();
	T*		getHost()
	T*		getDevice()
private:
       //probably more stuff here
};

ce qui une fois implemente, donne le fichier fourni en piece jointe de ce billet :)

Je n'ai pas commente abusivement, je pense que les noms de methodes et des fonctions de l'API cuda sont assez clairs ;)

Et voila le main du billet precedent, retouche pour fonctionner avec ce "container" :

int		main()
{
	const int NbElems = 100;
	float *toSquare = new float[NbElems];
	for (int i = 0; i < NbElems; ++i)
		toSquare[i] = (float)i;
 
	CudaContainer<float>		c(toSquare, sizeof(float) * NbElems);
	c.sendToDevice();
	//Cuda Kernel execution
	{
		dim3 blockSize(5, 5);
		const int nbThreads = blockSize.x * blockSize.y;
		int nbBlocks = NbElems / nbThreads + (NbElems % nbThreads == 0 ? 0 : 1);
		SquareArray<<<nbBlocks, blockSize>>>(c.getDevice(), NbElems);
	}
	c.getFromDevice();
	for (int i = 0; i < NbElems; ++i)
		std::cout << i << " => " << toSquare[i] << "\n";
	std::cout.flush();
}

Ce qui, a mes yeux, est toujours un peu plus agreable a lire/utiliser, qu'avec les fonctions initiales :)