CUDA nvcc строит цепочку библиотек

Моя цель: library2.so использует library1.so, а mycode.o использует (библиотеки должны быть связаны) library2.so (и, возможно, library1.so).

Исходный код (файлы заголовков одной строки опущены):

библиотека1.cu:

__device__ void func1_lib1(void){}

библиотека2.cu:

#include "library1.h"
__global__ void func1_lib2(void)
{
    func1_lib1();
}
extern "C"
void func2_lib2(void)
{
    func1_lib2<<<1,1>>>();
}

мой код.с:

#include "library2.h"
int main(void)
{
    func2_lib2();
}

Я создаю общие библиотеки в соответствии с с помощью 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

make working работает без проблем. Но это не цепочка библиотек. library1.cu и library2.cu находятся в одном файле .so.

make broken терпит неудачу с

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'

Если я осматриваю library1.so с помощью nm, внутри цели (T) _Z10func1_lib1v.


person Luuuucky    schedule 09.03.2016    source источник
comment
А ваш вопрос?   -  person talonmies    schedule 09.03.2016
comment
make working делает только одну библиотеку, а не цепочку библиотек. Вопрос в заголовке: Как сделать цепочку библиотек.   -  person Luuuucky    schedule 09.03.2016
comment
Что я делаю неправильно, если компиляция не удалась.   -  person Luuuucky    schedule 09.03.2016
comment
Что означает цепочка библиотек?   -  person talonmies    schedule 09.03.2016
comment
Мой код зависит от библиотеки2, а библиотека2 зависит от библиотеки1. Сначала я хотел бы скомпилировать библиотеку1. Чем я хотел бы скомпилировать библиотеку2 (без исходного кода библиотеки1, только с файлами заголовков). Последним шагом может быть компиляция mycode с использованием скомпилированных lib1 и lib2 и их заголовочных файлов без исходного кода этих библиотек.   -  person Luuuucky    schedule 09.03.2016


Ответы (1)


В вашем «сломанном» подходе вы пытаетесь создать library1.so (общую библиотеку), которая содержит только функцию __device__:

__device__ void func1_lib1(void){}

Любой другой объект, который хотел бы использовать эту функцию __device__, должен использовать перемещаемый код устройства/отдельная компиляция и компоновка, что вы, конечно же, пытаетесь сделать.

Однако, что касается библиотек, привязка устройств поддерживает только функции, содержащиеся в в статических библиотеках. Обратите внимание на следующие утверждения из руководства nvcc:

Компоновщик устройств может считывать форматы статических библиотек узлов (.a в Linux и Mac OS X, .lib в Windows). Он игнорирует любые динамические библиотеки (.so или .dll).

и:

Обратите внимание, что компоновщик устройств поддерживает только статические библиотеки.

Так что ваша общая стратегия не сработает. Возможный обходной путь — поместить код library1.cu в статическую библиотеку:

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 библиотек, не требующих связывания устройств через границы библиотек, что более или менее продемонстрировано в вашем «рабочем» случае.

person Robert Crovella    schedule 19.03.2016