问题描述
我的目标是: library2.so
正在使用 library1.so
和 mycode.o
正在使用(应该链接库) library2.so
(也许还有 library1.so
).
My goal is: library2.so
is using library1.so
and mycode.o
is using (libs should be linked) library2.so
(and maybe library1.so
).
源代码是(省略了一行头文件):
The source code is (one line header files are omitted):
library1.cu:
library1.cu:
__device__ void func1_lib1(void){}
library2.cu:
library2.cu:
#include "library1.h"
__global__ void func1_lib2(void)
{
func1_lib1();
}
extern "C"
void func2_lib2(void)
{
func1_lib2<<<1,1>>>();
}
mycode.c:
#include "library2.h"
int main(void)
{
func2_lib2();
}
我正在构建共享库根据使用Makefile
I'm building the shared libraries according to with Makefile
broken:
rm -f *.o *.so
nvcc -arch=sm_30 --compiler-options '-fPIC' -dc library1.cu
nvcc -arch=sm_30 --compiler-options '-fPIC' -dlink -o cuda-lib1.o library1.o
gcc -shared -Wl,-soname,library1.so -o library1.so library1.o uda-lib1.o
nvcc -arch=sm_30 --compiler-options '-fPIC' -dc library2.cu
nvcc -arch=sm_30 --compiler-options '-fPIC' -dlink -o cuda-lib2.o library2.o -lrary1
gcc -shared -Wl,-soname,library2.so -o library2.so library2.o cuda-lib2.o
gcc -c mycode.c
gcc -o mycode -L. -lrary2 -lrary1 mycode.o
working:
rm -f *.o *.so
nvcc -arch=sm_30 --compiler-options '-fPIC' -dc library1.cu
nvcc -arch=sm_30 --compiler-options '-fPIC' -dc library2.cu
nvcc -arch=sm_30 --compiler-options '-fPIC' -dlink -o cuda-lib.o library1.o library2.o
gcc -shared -Wl,-soname,library.so -o library.so library1.o library2.o cuda-lib.o
gcc -c -fPIC mycode.c
gcc -o mycode -L. -lrary -L/usr/local/cuda/lib64 -lcuda -lcudart mycode.o
使工作正常
可以正常工作.但这并不能构成一连串的库. library1.cu
和 library2.cu
位于同一 .so
文件中.
make working
works without any problems. But it doesn't make a chain of libraries. library1.cu
and library2.cu
are in the same .so
file.
弄破
失败
nvcc -arch=sm_30 --compiler-options '-fPIC' -dlink -o cuda-lib2.o library2.o -lrary1
nvlink error : Undefined reference to '_Z10func1_lib1v' in 'library2.o'
如果我通过 nm
检查 library1.so
,则会在目标(T) _Z10func1_lib1v
中.
If I inspect library1.so
by nm
there is inside a target (T) _Z10func1_lib1v
.
推荐答案
在折断"方法中,您试图创建一个 library1.so
(共享库),其中仅包含一个 __ device __
函数:
In your "broken" approach, you are attempting to create a library1.so
(a shared library) which contains only a __device__
function:
__device__ void func1_lib1(void){}
任何其他希望使用该 __ device __
函数的对象都必须使用可重定位的设备代码/单独的编译和链接,您当然会尝试这样做.
Any other object that wished to use that __device__
function must make use of relocatable device code/separate compilation and linking, which of course you are trying to do.
但是,对于库,仅链接设备支持静态库中包含的功能.请注意 nvcc
手册中的以下语句:
However, with respect to libraries, device linking only supports functions contained in static libraries. Note these statements from the nvcc
manual:
和:
因此,您的总体策略无效.可能的解决方法是将library1.cu代码放在静态库中:
So your general strategy won't work. A possible workaround would be to place the library1.cu code in a static library:
rm -f *.o *.so
nvcc -arch=sm_30 --compiler-options '-fPIC' -dc library1.cu
nvcc -arch=sm_30 --lib -o cuda-lib1.a library1.o
nvcc -arch=sm_30 --compiler-options '-fPIC' -dc library2.cu
nvcc -arch=sm_30 --compiler-options '-fPIC' -dlink -o cuda-lib2.o library2.o cuda-lib1.a
gcc -shared -Wl,-soname,library2.so -o library2.so -L/usr/local/cuda/lib64 -lcuda -lcudart library2.o cuda-lib2.o cuda-lib1.a
gcc -c mycode.c
gcc -o mycode -L. -lrary2 mycode.o
否则,将创建一系列 .so
库,这些库不需要跨库链接的设备链接,这在您的工作"案例中或多或少地得到了证明.
Or else to create a sequence of .so
libraries that don't require device linking across library boundaries, which is more-or-less demonstrated in your "working" case.
这篇关于CUDA nvcc图书馆建设链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!