2012-04-06 9 views
1

OpenCLに関するいくつかの問題がありますが、私がこの問題を解決できれば、他のいくつかの問題を解決できると思います。私は構造体のデータによって計算された数値を二重配列に格納したい次のカーネルを持っています。私がカーネルに渡す引数は構造体配列であり、初期化され、値はゼロではありません(私はそれをテストしました)。OpenCLカーネルの引数構造体に0の値があります

カーネルを実行しているときに、私は "浮動小数点例外"を取得します。私が正しいとすれば、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は正しい値を持ちます。

また、セル変数のカーネルの引数設定を引用します。

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); 

------------------------------------------ EDIT ------------------------------------------

[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; 
} 
+0

'params-> ny * params-> nx'は2次元配列のような匂いがします。あなたは1つの配列を割り当てています。なぜ 'params-> ny * params-> nx'を使うのですか? –

+0

理論上、それは2D配列であると考えられていますが、データが連続するためには1Dと宣言されています。 – gkaran89

答えて

1

OK、それは私がそれと思っていたものとは全く違うものでした。問題は、私はglobal_work_size

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

を呼んでいたときはlocal_work_sizeで割り切れないということでした。そのため、浮動小数点例外が発生しました。

+0

これは実際にあなたのホストコードに 'CL_INVALID_WORK_GROUP_SIZE'エラーなどを引き起こすはずです。 CLエラーをチェックしていませんか? –

+0

私はチェックしていたが、正確なエラーが何であるかを確認していなかった。私が記事で言っているように、これはOpenCLの最初のステップです。 – gkaran89

+0

'clEnqueueNDRangeKernel'はすぐにCLエラーを出さなければならないが、浮動小数点例外が発生するというのは奇妙なことです。(これを直ちにチェックすると仮定した場合、20個のCL関数が発生した可能性のあるエラー呼び出しはあまり使われていないので、例外のあるC++バインディングが好きなのです)。 –

2

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

+0

申し訳ありません。私はそれを見逃しています。私はどこに書いているのですか? (今すぐ巨大な頭痛) – gkaran89

+0

あなたの短いカーネルで - あなたがresult [i] + = 1.0fと言うとき、あなたはバッファに書き込んでいます。 –

+0

ああ、あなたはそれを意味します。ええ、私の悪いところは、議論がそこでは異なっていることを忘れてしまったことです。ところで、私は問題を理解しました。今すぐ解決策を書くでしょう。 – gkaran89

関連する問題