【发布时间】:2017-12-19 21:56:28
【问题描述】:
我编写了一个 OpenCL 内核,它在设备的 while 循环内生成随机数。一旦获得可接受的随机数,内核应该退出循环并将结果返回给主机。通常情况下, 每个工作项的迭代次数约为 100-1000。
问题是,当我启用 while 循环并且从不返回结果时,此代码挂起。如果我只是禁用 while 循环——即只生成一个随机数而不是 100 个——内核工作正常。
有人知道会发生什么吗?内核代码如下,也可在此github repo 获得。一种可能性是系统(在我的情况下是 MacOS)阻止 GPU 花费很长时间执行任务as described here,但我不确定。
#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;
}
}
}
}
【问题讨论】:
-
如果您无法在调试器中运行它,我建议您创建一个调试版本,您可以在其中传递一个整数以获得最大迭代次数,例如,您期望的最坏情况的两倍.然后调试版本会返回所有经过测试但未能进入真实区块的采样值和曝光值。
-
我同意,设置上限是调试它的好主意。
printf()在被拒绝的号码上可能也不是一个坏主意。我怀疑您可能在某个地方遇到了一个错误,导致 所有 生成的数字被拒绝。 -
您一遍又一遍地重新创建随机流;也许它总是创建相同的输出,这就是为什么你的 while 循环永远不会终止的原因。尝试在循环上方创建从中提取的随机流。
-
亲爱的@Dithermaster,这解决了问题!非常感谢您的快速反馈。
-
为了以后的访问者,我会把它作为答案。
标签: c opencl gpu gpgpu numerical