CUDA:使用单独的文件链接共享库.so

时间:2014-07-01 12:45:46

标签: cuda shared-libraries nvcc

我正在尝试使用单独的.cu文件中的nvcc 6.0编译.so库。我设法使用-rdc = true分别编译每个文件。当我尝试使用c链接我的库时,我得到了一堆错误。我已经从一个库编译了。我在nvcc 5.0的一个问题中读到这个问题不受支持here。我进入了nvcc 6.0的手册但是找不到(或理解)是否是这种情况。 Bellow是我的makefile(我在编写makefile方面不是很有经验,所以非常欢迎任何建议)。之后粘贴错误

NCC = /usr/local/cuda-6.0/bin/nvcc
CC = g++

LCUDA = -L/usr/local/cuda/lib64 -lcuda -lcudart
LNUM = -lm

OOP = -arch=sm_30 -rdc=true --shared -Xcompiler -fPIC -c

all: cuda_ddm.so

cuda_ddm.so : wfpt.o stationary.o
$(CC) -Wall -shared -include ./c_cuda_ddm.h -o $@ $^ $(LCUDA) 

wfpt.o : wfpt.cu
$(NCC) $(OOP) $@ $^ 

test.o : test.cu
$(NCC) $(OOP) $@ $^

错误:

(编辑:我更改了编译器错误以考虑当前情况。)

/usr/local/cuda-6.0/bin/nvcc -arch=sm_30 -rdc=true --shared -Xcompiler -fPIC -c wfpt.o wfpt.cu 
/usr/local/cuda-6.0/bin/nvcc -arch=sm_30 -rdc=true --shared -Xcompiler -fPIC -c test.o test.cu 
g++ -Wall -shared -o cuda_ddm.so wfpt.o test.o -L/usr/local/cuda/lib64 -lcuda -lcudart 
test.o: In function `big_random_block(int)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0x5e): multiple definition of `big_random_block(int)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0x5e): first defined here
test.o: In function `big_random_block_int(int)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0xde): multiple definition of `big_random_block_int(int)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0xde): first defined here
test.o: In function `value(float, float, int)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0x169): multiple definition of `value(float, float, int)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0x169): first defined here
test.o: In function `__device_stub__Z14float_to_colorPhPKf(unsigned char*, float const*)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0x788): multiple definition of `__device_stub__Z14float_to_colorPhPKf(unsigned char*, float const*)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0xb30): first defined here
test.o: In function `float_to_color(unsigned char*, float const*)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0x7f9): multiple definition of `float_to_color(unsigned char*, float const*)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0xba1): first defined here
test.o: In function `__device_stub__Z14float_to_colorP6uchar4PKf(uchar4*, float const*)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0x81e): multiple definition of `__device_stub__Z14float_to_colorP6uchar4PKf(uchar4*, float const*)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0xbc6): first defined here
test.o: In function `float_to_color(uchar4*, float const*)':
tmpxft_00003c24_00000000-3_test.cudafe1.cpp:(.text+0x88f): multiple definition of `float_to_color(uchar4*, float const*)'
wfpt.o:tmpxft_00003bc7_00000000-3_wfpt.cudafe1.cpp:(.text+0xc37): first defined here
collect2: error: ld returned 1 exit status
make: *** [cuda_ddm.so] Error 1

编辑:

为了澄清这种情况,我将代码更改为100%确保两个文件中没有重叠代码。我在 # include "c_cuda_ddm.hcu" 中都有以下内容:

# ifndef DDM_HEADER
# define DDM_HEADER

#include "book.h"
#include "math.h"

# define TOL 1e-7
# define PI 3.1415926535

# define DIM_X 0
# define DIM_Y 2
# define DIM_U 2
# define DIM_THETA 3
# define DIM_PTHETA 0

# define INDEX_V 0
# define INDEX_A 1
# define INDEX_W 2

# define CUE_LEFT 1
# define CUE_RIGHT 0
# define ANTISACCADE_TYPE 0
# define PROSACCADE_TYPE 1

// Number of threads for the predictive posterior
# define DDMBLOCKS 256
# define PPBLOCKS 1024
# define LLHBLOCKS 16 
# endif

__device__ double lp_ddm(double t, double v, double a, double w);

extern "C"
int llh_ddm(double *t, double *v, double *a, double *w, int ny,
    double *llh);


extern "C"
int llh_stationary_antisaccades(double *x, double *y, double *u,
    double *theta, double *ptheta, int ny, double *llh);

extern "C"
int lpp_stationary_antisaccades(double *x, double *y, double *u,
    double *theta, double *ptheta, int ny, int ns, double *llh);

1 个答案:

答案 0 :(得分:1)

big_random_block()float_to_color(内核),可能所有其他重复定义都来自book.h

这个头文件不同于(我认为通常的做法)其他头文件,因为它不仅包含函数原型,而且还包括实际的函数定义。

因此book.h只能(成功/正确/安全地)包含在整个项目的单个文件(即编译单元)中。如果将它包含在多个文件中,您将获得在多个模块中定义的相同功能,如果您尝试将这些模块链接在一起,将导致问题。

修复只是在一个文件中包含book.h,或者更好,只需抓住您需要的内容并从中创建自己正确组织的头文件。 book.h是一个标题文件,旨在附带CUDA by example本书。虽然我确信它对于那本书中的所有项目都能正常工作,但很明显,你不能只是捡起来并通过任何项目随意地将它洒在那本书中。某些头文件可能以这种方式工作。这个不会。

另外,我希望重申一点,即使用仅编译步骤(-rdc=true -c)无法完成单独的编译(和链接)。它还需要设备链接步骤。如果您的两个目标文件(wfpt.ostationary.o实际上没有共享或需要任何CUDA符号或入口点,那么可能无关紧要。但是如果有共享的cuda条目模块之间的点,设备链接步骤是必要的。但是,这不是你的问题的关键,如果最终需要,你肯定会发现你的编译序列在这个问题中描述不正确。