59 votes

Coder CUDA avec C# ?

Je suis à la recherche d'informations sur le codage de CUDA (le langage des processeurs nvidia) avec C#. J'ai vu quelques-unes des bibliothèques, mais il semble qu'elles ajouteraient un peu de surcharge (à cause des p/invokes, etc.).

  • Comment dois-je procéder pour utiliser CUDA dans mes applications C# ? Serait-il préférable de le coder en C++ et de le compiler dans une dll ?
  • Cette surcharge liée à l'utilisation d'un wrapper annule-t-elle les avantages que je pourrais tirer de l'utilisation de CUDA ?
  • Existe-t-il de bons exemples d'utilisation de CUDA avec C# ?

48voto

Insomnious Points 491

Il existe une enveloppe complète pour cuda 4.2, telle que ManagedCuda . Vous ajoutez simplement le projet cuda C++ à votre solution, qui contient votre projet c#, puis vous ajoutez simplement

call "%VS100COMNTOOLS%vsvars32.bat"
for /f %%a IN ('dir /b "$(ProjectDir)Kernels\*.cu"') do nvcc -ptx -arch sm_21 -m 64 -o "$(ProjectDir)bin\Debug\%%~na_64.ptx" "$(ProjectDir)Kernels\%%~na.cu"
for /f %%a IN ('dir /b "$(ProjectDir)Kernels\*.cu"') do nvcc -ptx -arch sm_21 -m 32 -o "$(ProjectDir)bin\Debug\%%~na.ptx" "$(ProjectDir)Kernels\%%~na.cu"

aux événements post-build dans les propriétés de votre projet c#, ceci compile le fichier *.ptx et le copie dans le répertoire de sortie de votre projet c#.

Il suffit alors de créer un nouveau contexte, de charger le module depuis le fichier, de charger la fonction et de travailler avec le dispositif.

//NewContext creation
CudaContext cntxt = new  CudaContext();

//Module loading from precompiled .ptx in a project output folder
CUmodule cumodule = cntxt.LoadModule("kernel.ptx");

//_Z9addKernelPf - function name, can be found in *.ptx file
CudaKernel addWithCuda = new CudaKernel("_Z9addKernelPf", cumodule, cntxt);

//Create device array for data
CudaDeviceVariable<cData2> vec1_device = new CudaDeviceVariable<cData2>(num);            

//Create arrays with data
cData2[] vec1 = new cData2[num];

//Copy data to device
vec1_device.CopyToDevice(vec1);

//Set grid and block dimensions                       
addWithCuda.GridDimensions = new dim3(8, 1, 1);
addWithCuda.BlockDimensions = new dim3(512, 1, 1);

//Run the kernel
addWithCuda.Run(
    vec1_device.DevicePointer, 
    vec2_device.DevicePointer, 
    vec3_device.DevicePointer);

//Copy data from device
vec1_device.CopyToHost(vec1);

0 votes

Quel sera le montant des frais généraux ? J'ai besoin d'appeler un de mes noyaux CUDA de manière répétée dans une boucle for dans le code hôte.

0 votes

ManagedCuda ne semble malheureusement plus être actif.

15voto

Frank Points 626

Cela a été commenté sur la liste nvidia dans le passé :

http://forums.nvidia.com/index.php?showtopic=97729

il serait facile d'utiliser P/Invoke pour l'utiliser dans les assemblées comme ceci :

  [DllImport("nvcuda")]
  public static extern CUResult cuMemAlloc(ref CUdeviceptr dptr, uint bytesize);

0 votes

Je n'avais pas réalisé que vous pouviez simplement invoquer les appels CUDA. Dommage qu'il faille adhérer à NVidia pour que cela fonctionne.

0 votes

Les frais généraux seront-ils moindres ? Je pense que la version CUDA gérée ci-dessus devrait avoir une surcharge due à l'archivage et au désarchivage des données ?

6voto

Ebrahim Byagowi Points 1105

Je suppose que Hybridizer, a expliqué aquí comme un billet de blog sur Nvidia est également à mentionner. Ici est son repo GitHub correspondant, semble-t-il.

5voto

Regis Portalez Points 2750

Il existe plusieurs alternatives pour utiliser CUDA dans vos applications C#.

  • Écrivez une bibliothèque C++/CUDA dans un projet séparé, et utilisez P/Invoke. La surcharge de P/invoke par rapport aux appels natifs sera probablement négligeable.
  • Utilisez un wrapper CUDA tel que ManagedCuda (qui exposera toute l'API CUDA). Vous n'aurez pas à écrire vos DLLImports à la main pour l'ensemble de l'API d'exécution CUDA (ce qui est pratique). Malheureusement, vous devrez toujours écrire votre propre code CUDA dans un projet séparé.
  • ( recommandé ) Vous pouvez utiliser des compilateurs gratuits/opensables/propriétaires (qui généreront cuda (source ou binaire) à partir de votre code c#.

Vous pouvez en trouver plusieurs en ligne : consultez le site suivant cette réponse par exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X