使用dlopen从共享库加载设备功能

时间:2016-02-12 04:26:23

标签: cuda

我对cuda编程比较陌生,无法找到解决问题的方法。

我正在尝试拥有一个共享库,我们称之为func.so,它定义了一个设备函数

__device__ void hello(){ prinf("hello");}

然后我希望能够通过dlopen访问该库,并在我的程序中使用该函数。我尝试了以下几点:

func.cu

#include <stdio.h>
typedef void(*pFCN)();

__device__ void dhello(){
    printf("hello\n")
}

__device__ pFCN ptest = dhello;
pFCN h_pFCN;

extern "C" pFCN getpointer(){
    cudaMemcpyFromSymbol(&h_pFCN, ptest, sizeof(pFCN));
    return h_pFCN;
}

main.cu

#include <dlfcn.h>
#include <stdio.h>

typedef void (*fcn)();
typedef fcn (*retpt)();
retpt hfcnpt;
fcn hfcn;

__device__ fcn dfcn;
__global__ void foo(){
    (*dfcn)();
}
int main() {
    void * m_handle = dlopen("gputest.so", RTLD_NOW);
    hfcnpt = (retpt) dlsym( m_handle, "getpointer");
    hfcn = (*hfcnpt)();
    cudaMemcpyToSymbol(dfcn, &hfcn, sizeof(fcn), 0, cudaMemcpyHostToDevice);
    foo<<<1,1>>>();
    cudaThreadSynchronize();
    return 0;
}

但是这样在使用cuda-gdb调试时出现以下错误:

CUDA Exception: Warp Illegal Instruction

Program received signal CUDA_EXCEPTION_4, Warp Illegal Instruction.
0x0000000000806b30 in dtest () at func.cu:5

感谢大家给予我的任何帮助! :)

1 个答案:

答案 0 :(得分:3)

从另一个编译单元中的设备代码调用一个编译单元中的__device__函数需要separate compilation with device linking使用nvcc

但是,使用 only works with static libraries

因此,如果__device__库中的目标.so功能是,而.so库中的调用代码是 库,您的方法无法使用当前的nvcc工具链。

唯一的解决方案&#34;我可以建议将所需的目标函数放在静态库中,或者将调用者和目标放在同一个.so库中。 cuda标签上有许多问题/答案,给出了这些替代方法的例子。