2016-08-19 44 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變量,從而跨越整個問題並使您的代碼更容易理解/理解進入討價還價。