用C#编写CUDA?

Ben*_*Ben 56 c# cuda

我一直在寻找有关使用C#编写CUDA(nvidia gpu语言)的一些信息.我已经看到了一些库,但似乎它们会增加一些开销(因为p/invokes等).

  • 我应该如何在C#应用程序中使用CUDA?用C++编写代码并将其编译成dll会更好吗?
  • 使用包装器的这种开销是否会破坏使用CUDA所带来的任何好处?
  • 有没有使用C#使用CUDA的好例子?

小智 44

有一个很好的完整的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"
Run Code Online (Sandbox Code Playgroud)

要在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);
Run Code Online (Sandbox Code Playgroud)


小智 13

这已在过去的nvidia列表中评论过:

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

使用P/Invoke很容易在程序集中使用它,如下所示:

  [DllImport("nvcuda")]
  public static extern CUResult cuMemAlloc(ref CUdeviceptr dptr, uint bytesize);
Run Code Online (Sandbox Code Playgroud)


Reg*_*lez 5

您可以使用多种替代方法在 C# 应用程序中使用 CUDA。

  • 在单独的项目中编写C++/CUDA库,并使用P/Invoke。P/invoke 相对于本机调用的开销可能可以忽略不计。
  • 使用 CUDA 包装器,例如ManagedCuda(它将公开整个 CUDA API)。您不必为整个 CUDA 运行时 API 手动编写 DLLImports(这很方便)。不幸的是,您仍然需要在单独的项目中编写自己的 CUDA 代码。
  • 推荐)您可以使用免费/开源/专有编译器(它将从您的 C# 代码生成 cuda(源代码或二进制文件)。

您可以在网上找到其中几个:例如,看看这个答案。


Ebr*_*owi 5

我想在这里作为Nvidia的博客文章解释的Hybridizer 也值得一提.是它的相关GitHub回购似乎.