2016-08-19 3 views
0

Ich fange an, CUDA zu verwenden und für ein Projekt von mir, so dass ich noch einige Aspekte davon neu bin. Ich stieß auf das folgende Problem.CUDA Mehrfachdefinition Fehler beim Verknüpfen

Ich muss .cu Dateien trennen, die ich mit einer gemeinsamen Header-Datei verwenden möchte, die eine Struktur hat, die beide von ihnen verwenden können. Es ist so etwas wie dieses:

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

globalParam glParam; 
#endif 

Die erste .cu Datei sieht wie folgt aus:

////////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 

Die zweite .cu Datei wie folgt aussieht:

////////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 

Jetzt ist der Fehler, den ich bekommen ist:

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

Die Funktionen oben scheinen ähnlich, aber das ist, weil ich versucht habe, sie so einfach wie möglich zu machen. Es wäre möglich, alles in eine einzige .cu-Datei zu schreiben, aber ich möchte es nach Möglichkeit aufteilen.

Was mache ich falsch mit dem Linker? Ich kompiliere und verlinke aus einem Qt Creator Projekt heraus. Lassen Sie mich wissen, wenn Sie meine Zeilen aus der .pro-Datei benötigen, um zu wissen, wie ich den nvcc-Compiler verwende.

Antwort

1

Es ist aufgrund der Tatsache, dass Global.h ist mehrfach enthalten und jedes Mal, wenn es im Lieferumfang enthalten ist: globalParam glParam;. Das ist keine Vorwärtsdeklaration (d. H. Nicht nur eine Typ-Signatur), sondern ist eine tatsächliche Instantiierung einer globalParam-Struktur. Dies führt dann dazu, dass es zwei Variablen gibt, die beide glParam genannt werden (die jeweils einer separaten #include von Global.h entsprechen) und die Ihnen mehrere Definitionsfehler gibt.

Schnellkorrektur: versuchen Sie extern zu verwenden, wenn Sie Ihre globale Variable teilen möchten (dann weiß der Linker, dass es nur ein Verweis auf, nun, ein 'externes' Symbol ist).

Besser beheben: Erwägen Sie Refactoring Ihres Codes, um den globalen Parameter über Verweis oder Zeiger als Argument für Ihre Funktionen zu übergeben. Auf diese Weise müssen Sie nicht einmal die Variable glParam in der Kopfzeile deklarieren, die gesamte Ausgabe durchgehen und Ihren Code verständlicher machen.

Verwandte Themen