编译GPU的C++程序的一部分

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++程序找到测试函数,我可以尝试什么?

Eri*_*got 1

我复制了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)