2013-06-19 6 views
11

Pracuję z CUDA i stworzyłem klasę int2_ do obsługi złożonych liczb całkowitych.Łącze klasy zewnętrznej CUDA i nierozwiązana funkcja zewnętrzna w pliku ptxas

deklaracji klasy w pliku ComplexTypes.h w następujący sposób:

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. 

    }; 
} 

realizacje klasa w pliku ComplexTypes.cpp w następujący sposób:

#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. 

Wszystko działa dobrze. W main (który zawiera ComplexTypes.h) mógłbym obsłużyć numery int2_.

W pliku CudaMatrix.cu, jestem teraz w tym ComplexTypes.h i definiowania i prawidłowo uruchamianiu funkcji __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); 

Sytuacja pliku CudaMatrix.cu wydaje się być symetryczny do funkcji main. Niemniej jednak, kompilator narzeka:

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

Proszę wziąć pod uwagę, że:

  1. Przed przeniesieniem wdrożenia do oddzielnych plików, wszystko działa poprawnie, gdy w tym zarówno deklaracje i implementacje w pliku main.
  2. Problematyczna instrukcja to data_[i] = ob[i].

Ktoś ma pojęcie o tym, co się dzieje?

+0

przypuszczalnie Do not masz 'ComplexTypes.cpp' plik, ale raczej' ComplexTypes.cu' plik której przechodzą do nvcc, inaczej '__host__ __device__' nie powinien skompilować ... – talonmies

+0

Znalazłem rozwiązanie mojego problemu. Wysłałem to jako odpowiedź, mając nadzieję, że może być przydatna dla innych użytkowników. – JackOLantern

Odpowiedz

24

Procedura Śledzę w moim poście powyżej ma dwa problemy:

  1. ComplexTypes.cpp filename muszą być włączone doComplexTypes.cu tak że nvcc mógłby przechwycić kluczowych CUDA __device__ i __host__. Zostało to wskazane przez Talonmiesa w jego komentarzu. W rzeczywistości przed opublikowaniem zmieniłem nazwę pliku z .cpp na .cu, ale kompilator narzekał i pokazywał ten sam błąd. Dlatego też chciałem się cofnąć;

  2. W Visual Studio 2010, należy użyć Widok -> Strony właściwości; Właściwości konfiguracyjne -> CUDA C/C++ -> Wspólne -> Generuj relokowalny kod urządzenia -> Tak (-rdc = true). Jest to konieczne do oddzielnej kompilacji. Rzeczywiście, w NVIDIA CUDA Compiler Driver NVCC, to powiedział, że:

CUDA działa osadzając kod urządzenia do obiektów przyjmujących. W trakcie kompilacji całego programu osadza on wykonywalny kod urządzenia w obiekcie hosta. W osobnej kompilacji umieszczamy relokowalny kod urządzenia w obiekcie hosta i uruchamiamy linker urządzenia (nvlink), aby połączyć ze sobą cały kod urządzenia. Wyjście nvlink jest następnie łączone ze wszystkimi obiektami hosta przez linker hosta w celu utworzenia końcowego pliku wykonywalnego.Wytwarzanie nierelokacyjnego vs wykonywalnego kodu urządzenia jest sterowana przez --relocatable device code = {prawdziwego, fałszywej} opcją, która może być skrócony do -rdc = {prawda fałszywego}.

+4

Zasadniczo masz tylko dwie możliwości - przenieś cały kod urządzenia do tej samej jednostki kompilacji lub użyj osobnej kompilacji. Odpowiadasz na to drugie i działa tylko z CUDA 5.0 lub nowszym. Ten pierwszy był jedynym sposobem na uporządkowanie aplikacji CUDA zanim wprowadzono linker. – talonmies

+0

DZIĘKUJEMY. Goniłem za tym problemem od wielu godzin. (Dotyczy także CUDA 5.5 i VS2012) –

+4

W Nsight Eclipse, opcja jest dostępna jako przycisk radiowy "Oddzielna kompilacja" w obszarze Projekt> Właściwości> Kompilacja> Ustawienia> CUDA – M2X

Powiązane problemy