2017-06-23 3 views
0

私はカーネルを持っています。clEnqueueNDRangeKernelグローバルな範囲全体で実行されていません

私のGPU上で実行するカーネルは、最初の2560の作業項目の上に実行されているが、私は734208.のグローバルワークサイズ( device->u_chunk)と

const size_t offset = 0; 
    clEnqueueNDRangeKernel(device->queue, device->kernels["int"], 1, &offset, &device->u_chunk, NULL, static_cast<cl_uint>(wait.size()), wait.data(), &event); 

から呼んでいる

__kernel void unprimed_grid_int(__global double *ar_u,   
           __global double *ap_u,   
           __global double *az_u,   
           __global const double *x_p,  
           __global const double *y_p,  
           __global const double *z_p,  
           __global const double *jx_p,  
           __global const double *jy_p,  
           __global const double *jz_p,  
           const uint nr,     
           const uint nz,     
           const uint nv,   
           const double rmin,  
           const double dr,  
           const double zmin,  
           const double dz,  
           const double dv, 
           const double dvol, 
           const uint p_size, 
           const uint offset) { 

    const size_t i = get_global_id(0); 

    const size_t ri = (i + offset)%nr; 
    const size_t zi = ((i + offset)/nr)%nz; 
    const size_t vi = ((i + offset)/(nr*nz))%nv; 

    const double r = ri*dr + rmin; 
    const double z = zi*dz + zmin; 
    const double v = vi*dv; 

    const double x = r*cos(v); 
    const double y = r*sin(v); 

    double ax = 0.0; 
    double ay = 0.0; 
    double az = 0.0; 

    for (uint j = 0; j < p_size; j++) { 
     const double dx = x_p[j] - x; 
     const double dy = y_p[j] - y; 
     const double dz = z_p[j] - z; 

     const double rp = sqrt(dx*dx + dy*dy + dz*dz); 

     ax += jx_p[j]/rp; 
     ay += jy_p[j]/rp; 
     az += jz_p[j]/rp; 
    } 

    ax *= dvol; 
    ay *= dvol; 
    az *= dvol; 

    ar_u[i] += x/r*ax + y/r*ay; 
    ap_u[i] += -y/r*ax + x/r*ay;        
    az_u[i] += az;            
} 

。私はget_global_size(0)の値を印刷して、カーネル内のグローバルワークサイズをチェックしました。 get_global_id(0)の項目があるかどうかを調べるためにprint文を追加すると、それは全範囲で実行されます。

カーネルがフルレンジで実行されない原因は何でしょうか?何が起こっているかの例を追加する追加するには

更新

、ここでのコード出力のプロットです。 Plot of the ap_u buffer カーネルがフルレンジで動作していないことがわかります。これをさらに実証するために、私は答えの1つによって提案されたテストケースを実行しました。カーネルを変更して追加の引数を追加しました。出力はカットオフ(2560)に表示される場所以下のグローバルID値については

__kernel void unprimed_grid_int(..., __global uint *test) { 
    ... 
    if (get_global_id(0) == 5) { // Reran with 5 changed to 700000 
     test[0] == 10; 
    } 
} 

、私はカットオフ以上のグローバルID値については10の正しい値をリードバック、私は間違った値が返され得ます。

+1

私の推測では、実際には全範囲で実行されています(2番目のprintfがそれを証明します)が、global_sizeのprintfは何とか間違っています。 – Dithermaster

答えて

0

なぜ私のカーネルが全世界的な範囲で動作していないのか分かりました。この問題は、カーネルのforループに起因しています。 p_sizeは、700000の順番です。これにより、カーネルの実行に時間がかかりました。私のGPUはディスプレイに接続されているので、the kernel is timing outだからUI doesn't lock upです。

2

私は実際にはすべての項目を実行しますが、多くのスレッドが存在するため、すべての値の印刷が正しく機能していないと思います。

あなたはまた、カーネルの引数として整数の変数を追加し、次の操作を行うことができ、それが動作することを確認する:

__kernel void unprimed_grid_int(your_arguments, int test) { 

    if (get_global_id(0) == 734207) { 
     test = 10; // or any other value 
    } 
} 

その後、すべての項目が処理される場合は、カーネルが、実行された後、使用する番号は10かそれ以上でなければなりません。

+0

2560の上下の2つのグローバルid値に対してこれを試しました。どちらの場合も、テスト整数の値は決して変更されませんでした。 – user1139069

+0

@ user1139069あなたはclEnqueueReadBufferを使って値を読みましたか? – vgeclair

+0

私は 'cl_mem'オブジェクトとreranとしてテストを再実装しました。グローバルIDが5の場合、正しい値が返されます。グローバルIDが700000の場合、値は変更されません。 – user1139069

関連する問題