2016-08-19 5 views
0

Я начинаю использовать CUDA и тянуть для моего проекта, поэтому я все еще новичок в некоторых его аспектах. Я столкнулся с следующей проблемой.Ошибка множественного определения CUDA при связывании

Мне нужно отделить файлы .cu, которые я хочу использовать, с общим файлом заголовка, который имеет структуру, которую они оба могут использовать. Это что-то вроде этого:

////////Global.h 
#ifndef global_h 
#define global_h 
struct globalParam 
{ 
    uint64_t spaceToUse; 
    globalParams() : spaceToUse(1024*1024*1024) {} 
}; 

globalParam glParam; 
#endif 

Первый файл .cu выглядит следующим образом:

////////firstcufile.cu 
#ifndef firstcufile_cu 
#define firstcufile_cu 
#include "Global.h" 

template<typename T> 
QVector<T> GPUcalculateNormSq(const QVector<T>& real, const QVector<T>& imag) 
{ 
    QVector<T> result (real.size()); 
    uint64_t maxSpace = glParam.spaceToUse; 

    //Some Code to use thrust and using tops maxSpace bytes. 

    return result; 
} 

template QVector<float> GPUcalculateNormSq(const QVector<float>& real, const QVector<float>& imag); 
template QVector<double> GPUcalculateNormSq(const QVector<double>& real, const QVector<double>& imag); 

#endif 

Второй файл .cu выглядит следующим образом:

////////secondcufile.cu 
#ifndef secondcufile_cu 
#define secondcufile_cu 
#include "Global.h" 

template<typename T> 
double getMean(const T& vec) 
{ 
    uint64_t spaceNeededOnGPU = vec.size() * sizeof (T); 
    uint64_t maxSpace = glParam.spaceToUse; 

    //Some code to make sure tops maxSpace bytes on GPU 
    double sum = thrust::reduce(std::begin(vec), std::end(vec)); 
    return sum/vec.size(); 
} 

template double getMean(const QVector<float>& vec); 
#endif 

Теперь Я получаю ошибку это:

secondcufilecuda_d.o:(.bss+0x18): multiple definition of `glParam' 
firstcufilecuda_d.o:(.bss+0x18): first defined here 

Функции, указанные выше похоже, но это потому, что я старался сделать их максимально простыми. Можно было бы написать все в один файл .cu, но я хотел бы разбить его, если это возможно.

Что я делаю неправильно с компоновщиком? Я компилирую и связываю из проекта Qt Creator. Дайте мне знать, если вам нужны мои строки из файла .pro, чтобы узнать, как я использую компилятор nvcc.

ответ

1

Это связано с тем, что Global.h включен несколько раз, и каждый раз, когда он включен, он обеспечивает: globalParam glParam;. Это не является прямым заявлением (т. Е. Не только сигнатурой типа), но и является фактическим экземпляром структуры globalParam. Тогда это приводит к двум переменным, которые называются glParam (каждый соответствует отдельному #includeGlobal.h), и это дает вам несколько ошибок определения.

Быстрое исправление: попробуйте использовать extern, если вы хотите поделиться своей глобальной переменной (тогда компоновщик знает, что это просто ссылка на символ «внешний»).

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

 Смежные вопросы

  • Нет связанных вопросов^_^