0
デバイスのwhileループ内で乱数を生成するOpenCLカーネルを作成しました。受け入れ可能な乱数が得られると、カーネルはループを終了し、その結果をホストに返します。通常、作業項目あたりの反復数は 〜100-1000です。OpenCLカーネルで問題が発生するwhileループ:実行がハングアップする
問題は、whileループを有効にしても結果を返さないときにこのコードがハングすることです。 whileループを無効にした場合、つまり100sではなく1つの乱数しか生成しません。カーネルはうまく動作します。
誰が何が起こっているのかも知りません。カーネルコードは以下にあり、github repoでも利用可能です。 1つの可能性は、システム(私のケースではMacOS)がGPUが長い時間をかけてタスクを実行するのを防ぐことです。しかし、わかりません。
#include <clRNG/mrg31k3p.clh> // for random number generation
#include "exposure.clh" // defines function exposure
__kernel void cr(__global clrngMrg31k3pHostStream* streams, __global float* xa, __global float* ya, const int n) {
int i = get_global_id(0);
float x,y,sampling;
if (i<n) {
// Loop that produces individual CRs
while (1) {
clrngMrg31k3pStream private_stream_d; // This is not a pointer!
clrngMrg31k3pCopyOverStreamsFromGlobal(1, &private_stream_d, &streams[i]);
// random number between 0 and 360
x=360.*clrngMrg31k3pRandomU01(&private_stream_d);
// random number between 0 and 1
y=clrngMrg31k3pRandomU01(&private_stream_d);
// To avoid concentrations towards the poles, generates sin(delta)
// between -1 and +1, then converts to delta
y = asin((float)(2.*y-1.))*180./M_PI_F; // dec
// If sampling<exposure for a given CR, it is accepted
sampling=clrngMrg31k3pRandomU01(&private_stream_d);
if (sampling <= exposure(y)) {
xa[i]=x;
ya[i]=y;
break;
}
}
}
}
これをデバッガで実行できない場合は、デバッグするバージョンを作成することをお勧めします。ここでは、最大反復回数、たとえば最悪の場合の2倍の整数を渡すことができます。次に、デバッグバージョンは、テストされたが実際のブロックに入ることができなかったすべてのサンプリング値と露出値を返します。 – jeff6times7
私は同意します。これをデバッグするには上限を設定することをお勧めします。拒否された数字に 'printf()'もおそらく悪い考えではありません。おそらくどこかにバグがあり、*生成されたすべての数字が拒否されていると思われます。 – pmdj
ランダムストリームを何度も何度も再作成しています。たぶんそれは常に同じ出力を生成するので、あなたのwhileループは決して終了しません。ループの上からランダムなストリームを作成してみてください。 – Dithermaster