4

正常に動作する CUDA プログラムがありますが、現在はすべて 1 つのファイルに書き込まれています。メンテナンスとナビゲートを容易にするために、この大きなファイルをいくつかの小さなファイルに分割したいと考えています。

新しい構造は次のとおりです。

foo.cuh
foo.cu
bar.cuh
bar.cu
main.cu

.cuhヘッダー ファイルには構造体と関数プロトタイプが含まれ、ファイル.cuには (通常どおり) 関数定義が含まれます。メイン ファイルにはbar.cuh、およびbar.cuが含まれますfoo.cuh。CUDA 関数を使用できるようにするために、すべての .cu ファイルには cutil_inline.h が含まれています。

したがって:

// main.cu
#include "bar.cuh"
#include <cutil_inline.h>

int main() [...]

// bar.cu
#include "bar.cuh"
#include "foo.cuh"
#include <cutil_inline.h>

[...]

// foo.cu
#include "foo.cuh"
#include <cutil_inline.h>

[...]

問題は、Visual Studio 2008 プロジェクトをこの新しい構造でコンパイルすると、大量のリンク エラーが発生することです。

error LNK2005: "void __cdecl __cutilBankChecker(unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,char *,int,char *,int)" (?__cutilBankChecker@@YAXIIIIIIPADH0H@Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cutilCondition(int,char *,int)" (?__cutilCondition@@YAXHPADH@Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cutilExit(int,char * *)" (?__cutilExit@@YAXHPAPAD@Z) already defined in cuda_generated_foo.cu.obj    cuda_generated_bar.cu.obj
error LNK2005: "int __cdecl cutGetMaxGflopsDeviceId(void)" (?cutGetMaxGflopsDeviceId@@YAHXZ) already defined in cuda_generated_foo.cu.obj   cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeCallNoSync(enum cudaError,char const *,int)" (?__cudaSafeCallNoSync@@YAXW4cudaError@@PBDH@Z) already defined in cuda_generated_foo.cu.obj    cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeCall(enum cudaError,char const *,int)" (?__cudaSafeCall@@YAXW4cudaError@@PBDH@Z) already defined in cuda_generated_foo.cu.obj    cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeThreadSync(char const *,int)" (?__cudaSafeThreadSync@@YAXPBDH@Z) already defined in cuda_generated_foo.cu.obj    cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cufftSafeCall(enum cufftResult_t,char const *,int)" (?__cufftSafeCall@@YAXW4cufftResult_t@@PBDH@Z) already defined in cuda_generated_foo.cu.obj  cuda_generated_bar.cu.obj

私はそれらの意味を理解しています (既に定義されているすべてのシンボルは cutil_inline.h の一部です) が、このヘッダーをすべてのファイルに含める必要があります。そうしないと、コンパイルされません。私は何を間違っていますか?

更新: 状況を明確にするために: * 1 つの大きなファイル内のすべてのコードで、コンパイル、リンク、正常に実行されます * 新しい構造 (いくつかの小さなファイル) を使用し、すべての .cu ファイルに cutil_inline.h を含めると、正しくコンパイルされますが、 * 新しい構造でリンクし、メイン ファイルにのみ cutil_inline.h をインクルードすると、cutil_inline.h がインクルードされていないファイルで cutil 関数が不明であると言って、コンパイル時に失敗します (予想どおりですが、すべてを試す必要がありました)。 - リスト項目

4

4 に答える 4

4

このエラーは私のプログラムでも発生しました。orのinline前にキーワードを追加して解決しました。その後、エラーはなくなりました。__global____device__

于 2012-09-20T02:16:33.833 に答える
2

どういうわけか、cutil_inline.h の関数は、コンパイル時に「インライン」としてフラグ付けされません。

Cuda 以外の通常の C++ プロジェクトでこのエラーが発生した場合、その答えは単純に、ヘッダー ファイルに関数定義 (宣言だけでなく) があり、"inline" キーワードが欠落しているということです。

すべてのマクロ展開後に何が起こっているかを実際に確認するには、対応する .i ファイル (プリプロセッサ) 出力を生成する必要がある場合があります。

編集 2009 年 1 月 2 日

マクロ展開の難読化のために .h ファイルを読んだだけでは何が問題なのかがわからない場合は、次のようにして .i ファイルを生成します。

  1. Visual Studio の [ソリューション エクスプローラー] ウィンドウで、ソース ファイルを右クリックし、[プロパティ] を選択します。

  2. プロパティ ツリーで、[C/C++]、[プリプロセッサ] を選択します。

  3. 「プリプロセス済みファイルの生成」を「いいえ」から他のオプションのいずれかに変更します。

  4. 次に、ファイルをコンパイルします。コンパイラは、プリプロセッサの出力をファイルに書き込み、実際にコンパイルせずに停止します。生成された .i ファイルで、すべてのマクロ展開の最終結果を確認できます。

  5. プロジェクトをコンパイラに再び適切に機能させるには、戻ってそのプロパティを「いいえ」にリセットする必要があります。

于 2009-12-30T19:15:25.443 に答える
0

cutil ライブラリ (つまり、32 ビット デバッグ用の cutil32D.lib など) とリンクする必要がありますか?

何らかの理由で、複数の定義があります。NVIDIA Cuda.rules ファイルを使用して、Visual Studio が .cu ファイルを .obj ファイルにコンパイルできるようにしていますか? cutil とリンクするようにルールを変更したようですが、NVIDIA Cuda.rules を使用して .cu を .obj にコンパイルする方法を VS に指示し、標準リンカー プロパティを変更して cutil ライブラリをプルする必要があります。

于 2009-12-30T10:09:35.330 に答える