Coder CUDA avec C #?

J’ai cherché des informations sur le codage CUDA (le langage NVIDIA GPU) avec C #. J’ai vu quelques bibliothèques, mais il semble qu’elles appendaient un peu de surcharge (à cause des invocations, etc.).

  • Comment dois-je utiliser CUDA dans mes applications C #? Serait-il préférable de le coder par exemple en C ++ et de le comstackr en dll?
  • Est-ce que cette surcharge de l’utilisation d’un wrapper éliminerait les avantages que j’aurais pu tirer de l’utilisation de CUDA?
  • Et existe-t-il de bons exemples d’utilisation de CUDA avec C #?

Il existe un aussi beau wrapper de cuda 4.2 que ManagedCuda . Vous ajoutez simplement le projet C ++ Cuda à votre solution, qui contient le 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" 

pour post-construire des événements dans vos propriétés de projet c #, cela comstack le fichier * .ptx et le copie dans votre répertoire de sortie de projet c #.

Ensuite, il vous suffit de créer un nouveau contexte, de charger le module à partir du fichier, de charger la fonction et de travailler avec le périphérique.

 //NewContext creation CudaContext cntxt = new CudaContext(); //Module loading from precomstackd .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 vec1_device = new CudaDeviceVariable(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); 

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

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

il serait facile d’utiliser P / Invoke pour l’utiliser dans des assemblages comme ceux-ci:

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

Je suppose que Hybridizer, expliqué ici comme un article de blog sur Nvidia, mérite également d’être mentionné. Voici son repo GitHub.

Vous pouvez utiliser plusieurs alternatives pour utiliser CUDA dans vos applications C #.

  • Ecrivez une bibliothèque C ++ / CUDA dans un projet distinct et utilisez P / Invoke. Le surcoût de P / invoque sur les appels natifs sera probablement négligeable.
  • Utilisez un wrapper CUDA tel que ManagedCuda (qui exposera l’intégralité de 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 distinct.
  • ( recommandé ) Vous pouvez utiliser les compilateurs free / opensource / proprietary (qui génèreront cuda (source ou binary) à partir de votre code c #).

Vous pouvez en trouver plusieurs en ligne: regardez par exemple cette réponse .