2013-06-19 14 views
11

私はCUDAで作業しており、複素数の数値を処理するためにint2_クラスを作成しました。 ComplexTypes.hファイル内ptxasファイルのCUDA外部クラスリンケージと未解決のextern関数

クラスの宣言を次のようにComplexTypes.cppファイルで

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. 

    }; 
} 

クラスの実装を次のように

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

すべてがうまく動作します。 mainComplexTypes.hを含む)では、int2_の数字を扱うことができました。 CudaMatrix.cuファイルで

、私は今ComplexTypes.h含むと定義し、適切__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); 

CudaMatrix.cuファイルの状況はmain関数に対称であるように思われます。それにもかかわらず、コンパイラは文句:

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

は、以下のことを考慮してください: mainファイル内の両方の宣言と実装を含むとき

  1. 別々のファイルに実装を移動する前に、すべてが正常に働いていました。
  2. 問題のある指示はdata_[i] = ob[i]です。

誰でも何が起こっているのか考えていますか?

+0

おそらくあなたがそうでなければ '__host__ __device__'がコンパイルべきではない、' ComplexTypes.cpp'ファイルではなく、あなたがNVCCに渡している 'ComplexTypes.cu'ファイルを持っているドント... – talonmies

+0

私は私の問題の解決策を見つけました。私はそれが他のユーザーに役立つことを望む答えとして投稿しました。 – JackOLantern

答えて

24

私は上記の私の記事に続いている手順では、二つの問題があります。nvccはCUDAのキーワード__device____host__を傍受することができるようにComplexTypes.cppファイル名ComplexTypes.cuオンにする必要があります

  1. を。これはTalonmiesのコメントで指摘されています。実際には、転記する前に、私はすでに.cppから.cuにファイル名を変更していましたが、コンパイラは不平を言って、同じエラーを示していました。したがって、私は堂々と歩み始めました。

  2. Visual Studio 2010では、表示 - >プロパティページを使用する必要があります。構成プロパティ - > CUDA C/C++ - >共通 - >リロケータブルデバイスコードの生成 - >はい(-rdc = true)。これは別々のコンパイルに必要です。 CUDAは、ホストオブジェクトに装置コードを埋め込むことによって動作

:実際、NVIDIA CUDA Compiler Driver NVCCで、それと言われています。プログラム全体のコンパイルでは、実行可能なデバイスコードをホストオブジェクトに埋め込みます。別のコンパイルでは、リロケータブルデバイスコードをホストオブジェクトに埋め込み、すべてのデバイスコードをリンクするためにデバイスリンカ(nvlink)を実行します。 nvlinkの出力は、ホストリンカによってすべてのホストオブジェクトとリンクされ、最終実行可能ファイルを形成します。relocatableと実行可能なデバイスコードの生成は、--relocatable-device-code = {true、false}オプションで制御されます。-rdc = {true、false}に短縮できます。

+4

基本的には、2つの選択肢があります。すべてのデバイスコードを同じコンパイル単位に移動するか、別のコンパイルを使用します。答えは後者で、CUDA 5.0以降でのみ動作します。前者はリンカが導入される前にCUDAアプリケーションを構築する唯一の方法でした。 – talonmies

+0

ありがとうございます。私はこの問題を何時間も追いかけてきました。 (CUDA 5.5とVS2012にも適用されます) –

+4

Nsight Eclipseでは、プロジェクト>プロパティ>ビルド>設定> CUDA – M2X