Подтвердить что ты не робот

Кодирование CUDA с С#?

Я искал некоторую информацию о кодировании CUDA (язык nvidia gpu) с помощью С#. Я видел несколько библиотек, но кажется, что они добавят немного накладных расходов (из-за p/invokes и т.д.).

  • Как мне использовать CUDA в моих приложениях С#? Было бы лучше закодировать его в слове С++ и скомпилировать его в dll?
  • Неужели это накладные расходы на использование обертки убьют все преимущества, которые я получаю от использования CUDA?
  • И есть ли хорошие примеры использования CUDA с С#?
4b9b3361

Ответ 1

Существует такая прекрасная полная оболочка cuda 4.2 как ManagedCuda. Вы просто добавляете проект С++ cuda в свое решение, которое содержит ваш проект С#, после чего вы просто добавляете

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"

для пост-сборки событий в ваших свойствах проекта С#, этот файл компилирует *.ptx и копирует его в каталог вывода проекта С#.

Затем вам нужно просто создать новый контекст, загрузить модуль из файла, загрузить функцию и работать с устройством.

//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);

Ответ 2

Это прокомментировано в списке nvidia в прошлом:

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

было бы легко использовать P/Invoke для использования в сборках:

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

Ответ 3

Существует несколько альтернатив, которые вы можете использовать для использования CUDA в ваших приложениях С#.

  • Напишите библиотеку С++/CUDA в отдельном проекте и используйте P/Invoke. Накладные расходы на P/вызовы по собственным вызовам, вероятно, будут незначительными.
  • Используйте обертку CUDA, такую ​​как ManagedCuda (которая откроет весь API CUDA). Вам не придется писать свои DLL файлы вручную для всего API-интерфейса CUDA (что удобно). К сожалению, вам все равно придется писать собственный код CUDA в отдельном проекте.
  • (рекомендуется). Вы можете использовать компиляторы free/opensource/proprietary (которые будут генерировать cuda (исходный или двоичный) из вашего кода С#.

Вы можете найти несколько из них в Интернете: например, посмотрите этот ответ.

Ответ 4

Я думаю, Hybridizer, объяснил здесь в качестве сообщения в блоге о Nvidia также стоит упомянуть. Здесь - это связанное с ним репозиционирование GitHub.