私は C++ で opencl 用の dotproduct カーネルを作成しましたが、ベクトル長 4096 で動作しています (12k 要素を試しても問題なく動作しています) が、ベクトル長を 16k 要素に増やすと、結果は無限大になり、小さな浮動小数点数を超えることはありません。番号。明らかにリークなどがありますが、n<16k 要素では問題なく動作します。16k 要素と 4 バイトはそれぞれ 64kB になり、3 つのバッファの合計は 192kB になり、これは GPU のメモリの 1/1000 にもなりません。ホスト コード (C#) の同じリダクション アルゴリズムと結果を比較すると、ホストの結果は予想どおり小さいです。無限大を構築するための精度エラーもありません(特定の有限値に制限されることさえあります)。
DLL 呼び出しを介して C# から C++ に渡されるカーネル (Ln= ローカル ワーク サイズ、n= グローバル ワーク サイズ) は次のとおりです。
"__kernel void SkalarCarpim(__global float * v1, __global float * v2, __global float * v3)" +
"{" +
" int i = get_global_id(0);" +
" int j = get_local_id(0);" +
" __local float biriktirici [" + Ln.ToString() + "];" +
" barrier(CLK_LOCAL_MEM_FENCE);" +
" biriktirici[j]=v1[i]*v2[i];" +
" barrier(CLK_LOCAL_MEM_FENCE);" +
" barrier(CLK_GLOBAL_MEM_FENCE);" +
" float toplam=0.0f;" +
" if(j==0)" +
" {" +
" for(int k=0;k<"+Ln.ToString()+";k++)"+ // reduction
" {"+
" toplam+=biriktirici[k];"+
" }"+
" }" +
" barrier(CLK_GLOBAL_MEM_FENCE);" +
" v3[i]=toplam;" +
" barrier(CLK_GLOBAL_MEM_FENCE);" +
" toplam=0.0f;" +
" for(int k=0;k<"+(n/Ln).ToString()+";k++)" +
" {" +
" toplam+=v3[k*"+Ln.ToString()+"]; " + // sum of temporary sums
" }" +
" v3[i]=toplam;"+
"}";
C++ Opencl バッファは次のとおりです。
buf1=cl::Buffer(altYapi,CL_MEM_READ_WRITE,sizeof(cl_float) * N);
buf2=cl::Buffer(altYapi,CL_MEM_READ_WRITE,sizeof(cl_float) * N);
buf3=cl::Buffer(altYapi,CL_MEM_READ_WRITE,sizeof(cl_float) * N);
//CL_MEM_READ_ONLY makes same error, tried some other too, no solution :(
バッファの送信方法は次のとおりです。
komutSirasi.enqueueWriteBuffer(buf1,CL_TRUE,0,sizeof(cl_float)*N,v1);
komutSirasi.enqueueWriteBuffer(buf2,CL_TRUE,0,sizeof(cl_float)*N,v2);
//CL_TRUE makes a blocking action so waits until finished
実行:
komutSirasi.enqueueNDRangeKernel(kernel,0,Global,Local);
//I got this from an example and I dont know if it is blocking or not.
結果バッファの取得方法は次のとおりです(すべての要素が結果であり、未完成であることはわかっています):
komutSirasi.enqueueReadBuffer(buf3,CL_TRUE,0,sizeof(cl_float) * N,v3);
//CL_TRUE makes a blocking action so waits until finished
質問: C++ Opencl に飛び込む前に行う必要がある設定はありますか? これは、Java/Aparapi/Jocl では問題ではありませんでした。
Khronos のサイトからの Opencl 1.2 ヘッダーと、AMD Opencl.lib + Opencl.dll を使用すると、役立つ場合があります (ターゲット デバイスは HD7870)。