Eri*_*got 8 c++ dynamic-linking nvcc
是否可以将带有nvcc的GPU编译(C++)代码转换为共享对象(.so文件)并从C++程序动态加载它(在本例中,Cern的ROOT,它本质上是一个C++解释器("CINT")) ).
我想要运行的一个简单示例是:
extern "C"
void TestCompiled() {
printf("test\n");
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
这段代码是用nvcc --compiler-options '-fPIC' -o TestCompiled_C.so --shared TestCompiled.cu.编译的.使用以下命令将共享对象加载到ROOT:
{ // Test.C program
int error, check;
check = gROOT->LoadMacro("TestCompiled_C.so", &error);
cout << "check " << check << " " << " error: " << error << endl;
TestCompiled(); // run macro
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
加载库好,但找不到TestCompiled():
$ root -b -l Test.C
root [0]
Processing Test.C...
check 0 error: 0
Error: Function Hello() is not defined in current scope Test.C:11:
*** Interpreter error recovered ***
Run Code Online (Sandbox Code Playgroud)
通过使用ROOT(没有extern行,编译root TestCompiled.C++)编译第一个测试脚本来做同样的工作......当nvcc进行编译时,为了使C++程序找到测试函数,我可以尝试什么?
我复制了RootTalk 论坛上解决问题的答案的要点,以供参考:
一个关键点是ROOT(CINT)的C解释器需要一个“CINT字典”来用于外部编译的函数。(通过ROOT编译时没有问题,因为ACLiC在预编译宏[ root TestCompiled.C++]时创建了这个字典)。
因此,TestCompiled.h++必须创建一个接口:
#ifdef __cplusplus
extern "C" {
#endif
void TestCompiled(void);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
Run Code Online (Sandbox Code Playgroud)
然后,该接口必须与共享对象一起加载到 ROOT 内部:
{ // Test.C ROOT/CINT unnamed macro (interpreted)
Int_t check, error;
check = gROOT->LoadMacro("TestCompiled_C.so", &error);
std::cout << "_C.so check " << check << " error " << error << std::endl;
check = gROOT->LoadMacro("TestCompiled.h++", &error);
std::cout << "_h.so check " << check << " error " << error << std::endl;
TestCompiled(); // execute the compiled function
}
Run Code Online (Sandbox Code Playgroud)
ROOT现在可以使用外部编译的程序:root -b -l -n -q Test.C有效。
这可以使用 g++ 进行以下测试TestCompiled.C:
#include <cstdio>
extern "C" void TestCompiled(void) { printf("test\n"); }
Run Code Online (Sandbox Code Playgroud)
编译为
g++ -fPIC -shared -o TestCompiled_C.so TestCompiled.C
Run Code Online (Sandbox Code Playgroud)