2013-06-19 11 views
11

Sto lavorando con CUDA e ho creato una classe int2_ per gestire numeri interi complessi.Collegamento di classe esterna CUDA e funzione extern non risolta nel file ptxas

dichiarazioni classe nel file ComplexTypes.h come segue:

namespace LibraryNameSpace 
{ 
    class int2_ { 

     public: 
      int x; 
      int y; 

      // Constructors 
      __host__ __device__ int2_(const int,const int); 
      __host__ __device__ int2_(); 
      // etc. 

      // Equalities with other types  
      __host__ __device__ const int2_& operator=(const int); 
      __host__ __device__ const int2_& operator=(const float); 
      // etc. 

    }; 
} 

implementazioni di classe nel file ComplexTypes.cpp come segue:

#include "ComplexTypes.h" 

__host__ __device__   LibraryNameSpace::int2_::int2_(const int x_,const int y_)   { x=x_; y=y_;} 
__host__ __device__   LibraryNameSpace::int2_::int2_() {} 
// etc. 

__host__ __device__ const LibraryNameSpace::int2_& LibraryNameSpace::int2_::operator=(const int a)      { x = a;   y = 0.;    return *this; } 
__host__ __device__ const LibraryNameSpace::int2_& LibraryNameSpace::int2_::operator=(const float a)      { x = (int)a;  y = 0.;    return *this; } 
// etc. 

tutto funziona bene. Nel numero main (che include ComplexTypes.h) potrei occuparmi dei numeri int2_.

Nel file CudaMatrix.cu, ora sto compresi ComplexTypes.h e definire e istanziare correttamente la funzione __global__:

template <class T1, class T2> 
__global__ void evaluation_matrix(T1* data_, T2* ob, int NumElements) 
{ 
    const int i = blockDim.x * blockIdx.x + threadIdx.x; 
    if(i < NumElements) data_[i] = ob[i]; 
} 

template __global__ void evaluation_matrix(LibraryNameSpace::int2_*,int*,int); 

La situazione del file CudaMatrix.cu sembra essere simmetrica alla funzione main. Tuttavia, il compilatore si lamenta:

Error 19 error : Unresolved extern function '_ZN16LibraryNameSpace5int2_aSEi' C:\Users\Documents\Project\Test\Testing_Files\ptxas simpleTest 

Vi preghiamo di considerare che:

  1. Prima di spostare l'implementazione di file separati, tutto funzionava correttamente quando includendo sia le dichiarazioni e le implementazioni nel file main.
  2. L'istruzione problematica è data_[i] = ob[i].

Qualcuno ha un'idea di cosa sta succedendo?

+0

presumibilmente Non devi un file 'ComplexTypes.cpp', ma piuttosto un file' ComplexTypes.cu' che si sta passando a nvcc, altrimenti il ​​'__host__ __device__' non dovrebbe compilare ... – talonmies

+0

Ho trovato una soluzione al mio problema. L'ho postato come risposta sperando che possa essere utile ad altri utenti. – JackOLantern

risposta

24

La procedura che ho seguito nel mio post di cui sopra ha due problemi:

  1. Il nome del file ComplexTypes.cppdeve ruotare in modo che ComplexTypes.cunvcc potesse intercettare le parole chiave CUDA __device__ e __host__. Questo è stato sottolineato da Talonmies nel suo commento. In realtà, prima di pubblicare, stavo già cambiando il nome del file da .cpp a .cu, ma il compilatore si lamentava e mostrava lo stesso errore. Pertanto, stavo ingenuamente facendo un passo indietro;

  2. In Visual Studio 2010, è necessario utilizzare Visualizza -> Pagine delle proprietà; Proprietà di configurazione -> CUDA C/C++ -> Comune -> Genera codice dispositivo rilocabile -> Sì (-rdc = true). Questo è necessario per la compilazione separata. Infatti, a NVIDIA CUDA Compiler Driver NVCC, si dice che:

CUDA funziona inserendo codice dispositivo in oggetti host. Nell'intero programma di compilazione, incorpora il codice del dispositivo eseguibile nell'oggetto host. Nella compilazione separata, incorporiamo il codice del dispositivo rilocabile nell'oggetto host ed eseguiamo il linker del dispositivo (nvlink) per collegare insieme il codice del dispositivo. L'output di nvlink viene quindi collegato insieme a tutti gli oggetti host dal linker host per formare l'eseguibile finale.La generazione di relocatable vs codice eseguibile dispositivo è controllato dal -dispositivo-code --relocatable = {true, false} opzione, che può essere ridotto a -rdc = {true, false}.

+4

Fondamentalmente, hai solo due scelte: sposta tutto il codice del dispositivo nella stessa unità di compilazione, oppure usa una compilazione separata. La tua risposta è la seconda, e funziona solo con CUDA 5.0 o successivi. Il primo era l'unico modo per strutturare le applicazioni CUDA prima che il linker fosse introdotto. – talonmies

+0

GRAZIE. Ho seguito questo problema per ore. (Vale anche per CUDA 5.5 e VS2012) –

+4

In Nsight Eclipse, l'opzione è disponibile come pulsante di opzione "Compilazione separata" in Progetto> Proprietà> Crea> Impostazioni> CUDA – M2X