如何从 CUDA C++ 创建和使用动态库“.so”并在 Linux 环境 (CentOS) 下的 C# 代码中使用它?

Posted

技术标签:

【中文标题】如何从 CUDA C++ 创建和使用动态库“.so”并在 Linux 环境 (CentOS) 下的 C# 代码中使用它?【英文标题】:How can I create and use a dynamic library ".so" from CUDA C++ and use it inside C# code under Linux environment (CentOS)? 【发布时间】:2021-02-25 01:52:30 【问题描述】:

我正在尝试使用 CUDA C++ 内核创建一个动态库 .so,以便在 LinuxC# 代码中使用它/strong> 环境(CentOS)。我搜索了一种方法来做到这一点,但不幸的是没有找到一个完整的解决方案。一些解决方案只制作其中的一部分,例如creating C++ shared library on Linux 或creating chain of libraries in CUDA using nvcc,但没有从CUDA C++ 创建动态库的方法。从 C++ 创建的 .so 的使用可以像 this solution 一样缝合。

有没有办法创建这个动态库并在 C# 代码中成功使用它?

【问题讨论】:

【参考方案1】:

在搜索了多种不同的解决方案,并尝试收集和测试可用的可能性后,我终于找到了这个简单的方法。 可以使用 gcc 像this answer 一样一步完成原始 C++ 库。

gcc -shared -o dll.so -fPIC dllmain.cpp

但请确保在 .cpp 文件中的所需函数之前添加extern "C",如下所示:

#include <stdio.h>
extern "C" void func()

    // code

对于 CUDA C++nvcc 的使用方式与 this answer 和 this answer 的组合使用方式相同。确保使用 .so 而不是 .dll 并使用正确的设备架构,我在这里使用 60,因为我使用的是“Tesla P100-PCIE-16GB”。

nvcc -arch=sm_60 --compiler-options '-fPIC' -o dll.so --shared kernel.cu

.cu 文件将与此类似。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>

extern "C" void myfunc(int a, int b, ...);
__global__ void kernel(int a, int b, ...);

__global__ void kernel(int a, int b, ...)

    int i = threadIdx.x;
    // kernel code


void myfunc(int a, int b, ...)

    // code

现在动态库 .so 已创建,可以像这样在 C# 代码中使用。

using System;
using System.Runtime.InteropServices;
class Program

    [DllImport("dll.so")]
    static extern myfunc(int a, int b, ...);

    private void Method()
    
        int a, b;
        // code
        myfunc(a, b, ...);
    

然后编译 C# 代码using Mono。

mcs Program.cs
mono Program.exe

但可能需要像这样设置使用的库的路径。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library/

这适用于简单的 CUDA C++ 代码,它可能适用于其他代码,但根据其复杂性可能会出现一些问题。

【讨论】:

以上是关于如何从 CUDA C++ 创建和使用动态库“.so”并在 Linux 环境 (CentOS) 下的 C# 代码中使用它?的主要内容,如果未能解决你的问题,请参考以下文章

linux下,有几个.so。如何将这几个动态库编译成一个动态库

从 C++ 源文件创建 Windows DLL

如何编写一个 .so 库来替换现有的 C++ .so 库?

Linux 动态链接库(.so)的使用

Linux动态链接库.so文件的创建与使用

为啥我无法链接到使用动态并行和可分离编译的 CUDA 静态库?