Кодирование CUDA с помощью C#?
Я искал некоторую информацию о кодировании CUDA (язык NVIDIA gpu) с C#. Я видел несколько библиотек, но кажется, что они добавят немного накладных расходов (из-за P/invokes и т. д.).
- как мне использовать CUDA в моих приложениях на C#? Было бы лучше закодировать его в C++ и скомпилировать его в dll?
- будут ли эти накладные расходы на использование обертки убивать любые преимущества, которые я получу от использования На CUDA?
- и есть ли хорошие примеры использования CUDA с C#?
4 ответов
есть такая хорошая полная оболочка cuda 4.2, как ManagedCuda. Вы просто добавляете проект c++ cuda в свое решение, которое содержит ваш проект c#, а затем просто добавляете
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"
для пост-сборки событий в свойствах проекта c# это компилируется *.ptx файл и копирует его в выходной каталог проекта c#.
тогда вам нужно просто создать новый контекст, загрузить модуль из файла, загрузить функцию и работать с устройством.
//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);
Это было прокомментировано в списке nvidia в прошлом:
http://forums.nvidia.com/index.php?showtopic=97729
было бы легко использовать P/Invoke для использования его в сборках, как так:
[DllImport("nvcuda")]
public static extern CUResult cuMemAlloc(ref CUdeviceptr dptr, uint bytesize);
есть несколько альтернатив, которые можно использовать для использования CUDA в приложениях c#.
- напишите библиотеку C++/CUDA в отдельном проекте и используйте P/Invoke. Накладные расходы P / invokes по собственным вызовам, вероятно, будут незначительными.
- используйте оболочку CUDA, такую как ManagedCuda(который будет выставлять весь API CUDA). Вам не придется писать DLLImports вручную для всего API времени выполнения CUDA (что удобно). К сожалению, у вас все еще будет написать свой собственный код CUDA в отдельном проекте.
- (рекомендовано) вы можете использовать бесплатные/opensource/проприетарные компиляторы (которые будут генерировать cuda (исходный или двоичный) из вашего кода C#.
вы можете найти несколько из них в интернете : посмотрите на ответ например.