私は OpenCL (total noob) に関していくつかの問題を抱えていますが、これを解決できれば他の問題も解決できると思います。構造体のデータによって計算された数値を double 配列に格納したい次のカーネルがあります。カーネルに渡す引数は構造体配列であり、初期化され、値はゼロではありません (テストしました)。
カーネルを実行すると、「浮動小数点例外」が発生します。私が正しければ、 local_density 変数がゼロであり、除算によってエラーが発生することを意味します。私が得られないのは、ホストではゼロ以外の値であるため、ゼロである理由です。カーネルで何か間違ったことをしていますか?
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
typedef struct
{
double speeds[9];
} t_speed;
__kernel void prepare(__global const t_speed* cells,
__global const int* obstacles,
__global double* results,
const unsigned int count)
{
int pos = get_global_id(0);
if(pos >= count) return;
if(obstacles[pos] == 1) results[pos] = 0.00;
else
{
double local_density = 0.00;
for(int kk = 0; kk < 9; kk++)
local_density += cells[pos].speeds[kk];
results[pos] = (cells[pos].speeds[1] + cells[pos].speeds[5] +
cells[pos].speeds[8] - (cells[pos].speeds[3] +
cells[pos].speeds[6] + cells[pos].speeds[7])) /
local_density;
}
}
ここでは、引数として渡す変数の初期化も行います。params->ny/nx には正しい値があります。
cells = (t_speed*) malloc(sizeof(t_speed) * (params->ny * params->nx));
また、セル変数のカーネルの引数設定を引用します。
m_cells = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(t_speed) * count, NULL, NULL);
err = clEnqueueWriteBuffer(commands, m_cells, CL_TRUE, 0, sizeof(t_speed) * count, cells, 0, NULL, NULL);
err |= clSetKernelArg(av_velocity_prepare_kernel, 0, sizeof(cl_mem), &m_cells);
- - - - - - - - - - - - - - - - - - - - - 編集 - - - - -----------------------------------
OK、本当に奇妙なのは、次の非常に単純なカーネルでも同じエラー (浮動小数点例外) が発生することです。誰でも手がかりを持っていますか?
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void test(__global float* result, const unsigned int n)
{
int i = get_global_id(0);
if(i >= n) return;
result[i] += 1.0f;
}