2011-06-25 86 views
51

我一直在寻找一些有关C#编码CUDA(nvidia gpu语言)的信息。我见过一些库,但似乎它们会增加一些开销(因为p/invokes等)。用C#编码CUDA?

  • 我应该如何在C#应用程序中使用CUDA?用C++编写代码并编译成dll会更好吗?
  • 使用包装的这种开销是否会丧失使用CUDA的优势?
  • 有没有任何使用CUDA与C#的好例子?

回答

39

有这样一个不错的完整的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); 
11

这已经评价过去NVIDIA的名单上:

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

这将是易于使用的P/Invoke来使用它的组件,如下所示:

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

删除的链接。有没有必要表现出死进一步链接如果你删除你的评论,会很友善。人们可能会对此置之不理。 –

+0

我没有意识到,你可以PInvoke CUDA调用。耻辱,你需要购买NVidia为此工作。 –

2

在您的C#应用​​程序中,您可以使用几种方法来使用CUDA。

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

你可以找到其中几个在线:看看在this answer例如,

2

我猜混杂,解释here作为Nvidia的博客文章也值得一提。Here是其相关GitHub库似乎。