2012-03-12 134 views
4

CUDAのcudaMemcpyToSymbol()が問題に

を「無効な引数」エラーがスローされます私は、デバイスの定数メモリにint配列をコピーしようとしているが、私は次のエラーを取得しておいてください。

[ERROR] 'invalid argument' (11) in 'main.cu' at line '386'

コード

多くのコードが開発されているので、私は自分のものを単純化するつもりです。

私のmain.cuファイルの最上部に、関数の外で変数__constant__が宣言されました。

__device__ __constant__ int* dic; 

私はまたmain()の内側に、それは次のようにmallocを'S、ホスト変数、flatDicを持っている:

int* flatDic = (int *)malloc(num_codewords*(bSizeY*bSizeX)*sizeof(int)); 

をそれから私はまた、そうすることによってdicflatDicの内容をコピーしようmain()に:

cudaMemcpyToSymbol(dic, flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int)); 

このcudaMemcpyToSymbol()呼び出し、それはラインmain.cuの386だし、それはどこです前述のエラーがスローされます。

私はいつも同じエラーを返す、以下の全てを試してみた:

私は

を試してみたことはここで私が問題を解決するために、これまで試したものだ

cudaMemcpyToSymbol(dic, &flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int)); cudaMemcpyToSymbol(dic, flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int)); cudaMemcpyToSymbol(dic, &flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int), 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(dic, flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int), 0, cudaMemcpyHostToDevice); 

は、私はまた、cudaMemcpyToSymbol()を呼び出す前に、cudaMalloc()dic変数にしようとしました。 cudaMalloc()にエラーはスローされませんが、cudaMemcpyToSymbol()エラーが引き続き発生します。

cudaMalloc((void **) &dic, num_codewords*(bSizeY*bSizeX)*sizeof(int)); 

私はまた、ウェブ、ドキュメント、フォーラム、例など、すべて無駄に広く徹底を検索しました。

私のコードに間違っている人はいますか?前もって感謝します。

+1

"私は、ウェブ、ドキュメント、フォーラム、事例などを広範に徹底的に検索してきました。 ... CUDA Cプログラミングガイド - 1.「Ctrl + S」を押して、ブラウザ/ PDFリーダーを探している通話を入力します。 2.該当するものを読み、ガイドのコードサンプルを見てください。 3.#2が失敗した場合は、フォーラムダイビングに進みます。この場合の情報は、直接形式のNVIDIAのガイドにありました。CUDA APIコールの問題へのアプローチ方法についての今後のアドバイスです。 –

+1

私は通常、HTML形式で入手可能なリファレンスガイドから始めます。 [ここにはCUDA 4.1のリファレンスがあります](http://developer.download.nvidia.com/compute/cuda/4_1/rel/toolkit/docs/online/modules.html)コール名のGoogleは通常このようになります。参照を確認したら、プログラミングガイドを確認してください。 – harrism

答えて

3

cudaMemcpyToSymbolを定数変数にコピーします。int(割り当てられたARRAY)の複数のバイトをint *のポインタにコピーしようとしています。これらのタイプは同じではないため、invalid typeです。この作業を行うには、例えば、intのデバイス(静的長)ARRAY(定数)にintのARRAY(割り当てられた)をコピーする必要があります。

__device__ __constant__ int dic[LEN]; 

例私はあなたが読むことをお勧めCUDA C Programming Guide(から - それはかなりいいです!):

私の知識あなたも cudaMemcpyToSymbolあなたが)ポインタへの配列をコピーしているあなたの例とは異なり、ポインタ(へのポインタが、用心ができる唯一のこと ポインタ
__constant__ float constData[256]; 
float data[256]; 
cudaMemcpyToSymbol(constData, data, sizeof(data)); 
cudaMemcpyFromSymbol(data, constData, sizeof(data)); 

は、一定ではないだろうそれがあなたのデバイス上で指しているメモリ。このルートに行く場合は、cudaMallocを追加し、次にcudaMemcpyToSymbolの結果のptrをデバイスメモリの__constant__デバイスvarに追加する必要があります。もう一度、この場合は配列の値は一定ではありません。メモリへのポインタだけになります。また

int * d_dic; 
cudaMalloc((void **) &d_dic, num_codewords*(bSizeY*bSizeX)*sizeof(int)); 
cudaMemcpyToSymbol(c_dic_ptr, &d_Dic, sizeof(int *)); 

あなたが内部のエラーチェックロジックをデバッグ中にCUDAの呼び出しをラップする必要があります。この場合の

あなたの呼び出しは何かのようになります。私は、talonmiesから次のロジックを借りてきました:

__inline __host__ void gpuAssert(cudaError_t code, char *file, int line, 
       bool abort=true) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), 
      file, line); 
     if (abort) exit(code); 
    } 
} 

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 

単にそのようにそれにあなたのCUDAのコールをラップ呼び出すには:

gpuErrchk(cudaMemcpyToSymbol(dic, flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int))); 

あなたは割り当てを持っている場合、プログラミングはエラーメッセージを表示して終了します問題またはその他の一般的なエラー。エラーコードをチェックするためのtalonmies

MyKernel<<<BLK,THRD>>>(vars...); 

//Make sure nothing went wrong. 
gpuErrchk(cudaPeekAtLastError()); 
gpuErrchk(cudaDeviceSynchronize()); 

ありがとう:

があなたのカーネルを確認するには、のような何かをします!

注:
あなたはバニラcudaMemcpyをしていた場合でも、あなたのアレイのcudaMalloc編のメモリを持っていないとして、あなたのコードは失敗するだろう - その場合INT、しかし、失敗の可能性が高いGPUと同等になりますあなたがそのジャンク値によって与えられたアドレスでメモリを書き込もうとしているなら、segfault(おそらくUnspecified launch failure)の中にポインタが何らかの種類のジャンク値を持っているからです。

関連する問題