このような問題が発生しています。基本的に、私はホスト上で割り当てられた2Dグリッドを持っている:特定のシステムサイズを超えた場合のOpenCLランダムカーネルの動作
のOpenCLデバイス上でそれを置くために、通常のOpenCLの手順をFolllowingdouble* grid = (double*)malloc(sizeof(double)*(ny*nx) * 9);
:
cl_mem cl_grid = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(double) * (ny*nx) * 9, grid, &error);
エンキューと打ち上げ:では
clEnqueueNDRangeKernel(queue, foo, 1, NULL, &global_ws, &local_ws, 0, NULL, NULL);
カーネル関数、単純演算はグリッドの第1列で実行されます。
__kernel void foo(__constant ocl_param* params, __global double* grid)
{
const int ii = get_global_id(0);
int jj;
jj=0;
if (ii < params->ny) {
grid[getIndexUsingMacro(ii,jj)] += params->someNumber;
}
}
最後に、バッファーとチェック値を読み戻します。
clEnqueueReadBuffer(queue, cl_grid, CL_TRUE, 0, sizeof(double) * 9 * nx * ny, checkGrid, 0, NULL, NULL);
問題は、グリッドサイズ(すなわちNX * NY * 9)16384×9×8バイト= 1152キロバイトを超える場合である(*倍精度を用いているため8)。私はglobal_wsとlocal_ws(Iは1にそれらを設定するとエラーがまだスローされます)のために設定したものに関係なく、カーネルを起動していないとき
- は、CPU上でのOpenCLを使用している場合、エラーCL_OUT_OF_RESOURCESがスローされます。 CPUは8GBのRAMと3MBのキャッシュを備えたIntel i5 2415mです。
GPU(NVIDIA TESLA M2050)でopenCLを使用しても、エラーは発生しません。しかし、バッファから値を読み戻すとき、グリッドはまったく変更されません。つまり、カーネル関数に送られる前の値とまったく同じ値を持つグリッドを返します。
nx = 30、ny = 546、nx * ny = 16380を設定すると、すべて正常に動作します。予想通りに結果が変更されたグリッドが返されました。しかし、ny = 547、nx * ny = 16410の場合、上記のようにCPUとGPUの両方で問題が発生します。問題は、もしnxとnyを入れ替えても同じです。したがって、nx = 547、ny = 30なら、それは起こります。皆さんはここで何が問題になるかもしれないかを提案できますか?これは、同期の問題のように見える
感謝
1つのワークグループだけをエンキューしない限り、バリアを使用して安全に障壁を使用することはできません。 OpenCLの障壁は、ワークグループ内のすべてのワークアイテムに対して同期を提供しますが、ワークグループ間のアクセスは同期されません。 – sbabbi
さて、それは私が意味することです: "彼らは単一の作業グループにいる"。 –