如何从 C# 调用 CUDA

Posted

技术标签:

【中文标题】如何从 C# 调用 CUDA【英文标题】:How to invoke CUDA from C# 【发布时间】:2020-10-14 02:21:17 【问题描述】:

我已经使用 Hybridizer 构建了一个程序,用 C# 编写 CUDA 代码并调用函数。该程序可以正常运行,但我注意到设置 GPU 和调用函数的开销非常高。例如,在 CPU 上运行时需要 3000 个滴答的作业需要大约 5000 万个滴答来设置 GPU 包装器,然后在 GPU 上运行时需要另外 5000 万个滴答。我试图弄清楚这种滞后是由于 Hybridizer 本身造成的,还是在从我的 C# 程序调用 GPU 代码时是不可避免的。

所以我正在寻找替代方法。我的搜索发现提到了一些名为 P/invoke 的东西,但我真的找不到关于如何使用它的好指南,而且所有这些线程都有 9 年以上的历史,所以我不知道他们的信息是否仍然相关.我还发现了一些关于 ManagedCuda 的信息,但它似乎不再处于开发阶段。

【问题讨论】:

【参考方案1】:

您可以尝试CppSharp 生成与 CUDA 的 C# 绑定。我们能够使用这种方法初始化 CUDA,并将其称为简单的硬件信息函数(GetDeviceProperties、CudaSetDevice、CudaGetDeviceCount、CudaDriverGetVersion、CudaRuntimeGetVersion)。

似乎可以使用 CUDA API 的其他部分,但我们没有尝试:CppSharp 为整个 CUDA 运行时 API 生成绑定。我们通过 NVIDIA 的 Flex 库间接使用 CUDA。所有的 Flex 功能都可以通过 CppSharp 使用,而不会受到很大的惩罚。

通过 CppSharp 生成的类的示例用法如下所示:

int driverVersion = 0;
CudaRuntimeApi.CudaDriverGetVersion(ref driverVersion);

int runtimeVersion = 0;
CudaRuntimeApi.CudaRuntimeGetVersion(ref runtimeVersion);

int deviceCount = 0;
var errorCode = CudaRuntimeApi.CudaGetDeviceCount(ref deviceCount);

if (errorCode != CudaError.CudaSuccess)

    Console.Error.WriteLine("'cudaGetDeviceCount' returned " + errorCode + ": " + CudaRuntimeApi.CudaGetErrorString(errorCode));
    return;


for (var device = 0; device < deviceCount; ++device)

    using (var deviceProperties = new CudaDeviceProp()) 
    
        CudaRuntimeApi.CudaGetDeviceProperties(deviceProperties, device);
    

         

CudaRuntimeApi 和 CudaDeviceProp 是 CppSharp 生成的类。

【讨论】:

为什么不举个例子? 谢谢,我会试试这个技巧 C# 部分。您可以简单地演示如何从 C# 运行像 deviceQuery 这样的示例代码。用作示例的 CUDA 代码并不那么重要,但很高兴看到一些完整的、有效的东西。我在我的答案中提供了许多完整的示例,甚至包括诸如 OpenMP 和从 python 调用 CUDA 代码之类的示例。在我看来,没有人会按字词或字符向您收费,因此极端简洁并不是 SO 答案中真正有吸引力的功能。 Here 是使用 ctypes 从 python 调用 CUDA 的示例。 @Robert Crovella,哦,我明白了。我会尝试发布代码。 在 SO 上,我认为大家都同意我们喜欢代码。

以上是关于如何从 C# 调用 CUDA的主要内容,如果未能解决你的问题,请参考以下文章

从 python 调用 cv::cuda::HOG

从 cuda 文件调用外部 C 文件中的函数

我可以从c ++调用用cupy代码编写的cuda代码吗?

如何从 JavaScript 调用 C# 函数?

如何从 jQuery 调用 C# 静态方法

如何从 C# 调用组装过程并返回结果?