这是我第一次处理一个比简单的write-single-source-file-and-compile例程稍微复杂一点的CUDA项目。正如预期的那样,我面临着C头的一些问题,即重复的符号。
根据链接器,在多个.cu
文件中包含以下头文件会产生冲突:
env_vars.h
#ifndef ENV_VARS_H_
#define ENV_VARS_H_
/*** GLOBAL VARIABLES ***/
unsigned int h_n_osc;
__device__ unsigned int d_n_osc;
/*** CONSTANTS ***/
const double OMEGA_0 = 6.447421494058077e+09;
/* other constants defined in the middle */
#endif
multigpu.cu
#include "env_vars.h"
/* assigns h_n_osc */
adm_matrix.cu
#include "env_vars.h"
/* uses h_n_osc */
在Nsight Eclipse Edition中构建项目会导致链接器抱怨h_n_osc
变量被定义两次:
duplicate symbol _h_n_osc in:
./adm_matrix.o
./multigpu.o
ld: 1 duplicate symbol for architecture x86_64
通过互联网搜索,我意识到将h_n_osc
变量的声明移至multigpu.cu
并在extern
中将其重新声明为adm_matrix.cu
变量(以及我以后可能需要它的地方)解决问题,实际上它确实。
问题解决了,但我想深入研究一下:
d_n_osc
变量?为什么常量(例如OMEGA_0
)同样不是问题?提前感谢您的耐心,伙计们!
答案 0 :(得分:9)
头文件通常应包含仅声明性代码。 h_n_osc
应该声明,而不是已定义。
extern unsigned int h_n_osc;
在您的至少一个模块中,或者您自己的新模块中,您将需要一个定义;例如:
<强> env_vars.cu 强>
#include "env_vars.h"
unsigned int h_n_osc;
然后链接那个。或者,您当然可以将定义放在其中一个现有模块multigpu.cu或adm_matrix.cu中。
我不确定CUDA __device__
扩展名的语义,虽然它可能链接,但它不一定正确;您最终可能会引用每个模块引用设备变量的单独副本;可能有必要使用extern
来限定它。 This question似乎可以解决这个问题。