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#?
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);
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);
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.
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.