C、C++、および OpenCL は初めてです。2 つの質問があります。
(1) long 配列や double 配列などの多数のホスト入力データ変数がある場合、それぞれを (従来の OpenCL の方法、つまり createBuffer などで) デバイスにコピーすることを回避し、代わりに単にデバイスから一部のメモリをマップする方法はありますか?カーネル内でアクセスするためにホスト ポインタをデバイス メモリに書き込みますか? あると言われましたが、これを行うコードがわかりません。
以下に、入力データ配列の例を示します。目的は、さまざまな入力データ変数が非常に大きくなる可能性があるため、ポインタをコピーせずにデバイスに何らかの形で中継することです。バッファーを割り当て、マップ バッファーをエンキューし、デバイス ポインターを取得しますが、そのデバイス ポインターに入力を渡す方法がわかりません。デバイス ポインターに cl_long の型を使用しましたが、これは間違っている可能性があります。
cl_long inputData[2] = {1,2};
cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
sizeof(cl_long) * 2, NULL, NULL);
cl long* inputMap = (cl_long*) clEnqueueMapBuffer(
queue, inputBuffer, TRUE, CL_MAP_WRITE, 0,
sizeof(cl_long) * 2, 0, NULL, NULL, NULL);
// what to do here?
clEnqueueUnmapMemObject(queue, inputBuffer, inputMap, 0, NULL, NULL);
上記の 2 つの cl_long にスペースを使用しましたが、実際には、ホスト データへのポインターを渡す場合、ここに何を割り当てますか?
(2) 複数の入力変数へのポインタを clEnqueueMapBuffer によって返される同じメモリ空間にパッキングするのはどうですか? long 配列と double 配列があるとします。両方へのポインタをマップされたデバイス メモリの同じ部分に渡すことができますか?
ホストとデバイスのメモリと、それらが同期を維持する方法と、ポインターについて少し詳しく説明されているソースコードの例を本当に感謝しています。
PSホストデータをデバイスマップメモリに書き込むSOの別の例を見ました(http://stackoverflow.com/questions/5673794/opencl-mapped-memory-doesnt-work)が、ここでも手動でデータをコピーと同等のメモリ。
更新: Raj のコメント (コメントが長すぎる場合に備えてここに返信) に応えて、私はすでにそのフラグを使い始めていますが、おそらくポインター コードのどこかに間違いがあります。
double a[2] = { 3.0, 6.0 } ;
size_t pointerSize = sizeof(double*);
cl_mem bufA = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, pointerSize, NULL, NULL);
clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufA);
double* pA = (double*) clEnqueueMapBuffer(queue, bufA, CL_TRUE, CL_MAP_WRITE, 0, pointerSize, 0, NULL, NULL, &err);
*pA = *a;
この時点で、カーネル自体に a[0] と a[1] を出力すると、次のようになります。
a[0]=3.000000
a[1]=-0.000000
a[1] は明らかに間違っています。私が間違っていることはありますか?