Это мой первый раз, когда я занимаюсь проектом CUDA, который немного сложнее, чем простая процедура write-single-source-file-and-compile. Как и ожидалось, я столкнулся с некоторыми проблемами с заголовками 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
) одинаково не проблема?Заранее спасибо за ваше терпение, ребята!
Заголовочные файлы должны обычно содержать только декларативный код. 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
также. Этот вопрос кажется, имеет дело с этой проблемой.