【发布时间】:2014-07-01 12:45:45
【问题描述】:
我正在尝试使用 nvcc 6.0 从单独的 .cu 文件编译 .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);
【问题讨论】:
-
错误很明显 - 您已经编译了两次相同的代码,一次在
wfpt.o中,一次在stationary.o中(可能是因为将相同的代码包含到两个源文件中)。该问题可能与您显示的 makefile 无关。 -
@talonmies 我验证了问题是否是您提到的问题。我几乎可以肯定它与此无关,但请查看我的编辑。
-
您的 make 文件中确实缺少设备链接步骤。当您使用
-dc编译时,您不能简单地转到g++将事物链接在一起。需要一个单独的中间设备链接步骤。但是,这不是此问题中指出的问题的根源。 @talonmies 响应是正确的,您的编辑没有任何改变。包含守卫不会阻止将相同的代码包含到 2 个单独的文件中。它们只防止多个包含在一个 single 文件中。需要一个简化的测试用例来为您解决所有这些问题,但您没有像 SO 期望的那样提供它。 -
对不起@RobertCrovella,我很慢......我不明白。我查看了这两个文件并确保没有重叠的代码(我可以将其中一个转换为另一个并且代码编译 - 假设我更改了我的 makefile)。所以我不确定为什么两个文件中的代码都是两次。我想我仍然遇到编译错误,但这可能是一个不同的错误。我将更新我收到的错误。
-
@eaponte:如果您只阅读错误消息,事情会简单得多。无论发生什么,您都在编译 big_random_block、big_random_block_int、value 和 float_to_color 两次。一次在 wfpt.o 和一次在 test.o 。这是无可争议的。链接器会准确地告诉您问题出在哪里。您的任何编辑都没有告诉我们发生这种情况的原因。查看您的代码并找到这些函数的定义位置。然后分析这些函数是如何编译到您尝试链接的每个目标文件中的。只有您可以诊断和解决此问题。交给你.....
标签: cuda shared-libraries nvcc