Codage CUDA avec C#?

J'ai cherché des informations sur le codage CUDA (le langage gpu nvidia) avec C#. J'ai vu quelques-unes des bibliothèques, mais il semble qu'elles ajouteraient un peu de frais généraux (à cause des P / invokes, etc.).

  • Comment dois-je utiliser CUDA dans Mes applications C#? Serait-il mieux de coder en C++ et compiler une dll?
  • cette surcharge d'utilisation d'un wrapper tuerait-elle les avantages que j'obtiendrais en utilisant CUDA?
  • et y a-t-il du bon exemples d'utilisation de CUDA avec C#?
54
demandé sur Ben 2011-06-25 06:51:26

4 réponses

Il y a un beau wrapper Cuda 4.2 complet comme Gestion du programme. Vous ajoutez simplement le projet C ++ cuda à votre solution, qui contient le vôtre 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 les propriétés de votre projet c#, cela compile *.fichier ptx et le copie dans votre répertoire de sortie du projet c#.

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

//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);
42
répondu Insomnious 2016-11-30 08:18:00

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 des assemblys comme ceci:

  [DllImport("nvcuda")]
  public static extern CUResult cuMemAlloc(ref CUdeviceptr dptr, uint bytesize);
12
répondu Frank 2017-01-05 21:57:22

Je suppose que Hybridizer, expliqué ici comme un billet de blog sur Nvidia est également intéressant de mentionner. Ici est son repo GitHub lié il semble.

5
répondu Ebrahim Byagowi 2017-12-19 20:41:39

Il existe plusieurs alternatives que vous pouvez utiliser 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 / invokes sur les 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 toute L'API d'exécution CUDA (ce qui est pratique). Malheureusement, vous devrez toujours écrire votre propre CUDA code dans un projet séparé.
  • (recommandé ) Vous pouvez utiliser des compilateurs libres / opensource / propriétaires (qui généreront cuda (source ou binaire) à partir de votre code c#.

Vous pouvez en trouver plusieurs en ligne: jetez un oeil à cette réponse par exemple.

2
répondu Regis Portalez 2017-10-17 20:32:06