1

私は 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;
}
4

2 に答える 2

2

バッファを として宣言していることに気付きましたCL_MEM_READ_ONLYが、カーネル内でバッファに書き込んでいます。OpenCL 仕様によると、これは未定義です。CL_MEM_READ_WRITE代わりに使用してみてください。

于 2012-04-07T08:48:58.673 に答える
1

そうですね、思っていたのとは全然違いました。問題は、私が電話をしていたときでした

clEnqueueNDRangeKernel (command_queue, kernel, work_dim, *global_work_offset,     
                        *global_work_size, *local_work_size, num_events_in_wait_list,
                        *event_wait_list, *event)

global_work_sizeで割り切れませんでしたlocal_work_size。これにより、浮動小数点例外が発生しました。

于 2012-04-07T09:16:25.317 に答える