首先,这是我第一次真正感到有必要在StackOverflow上提问,但是我在研究和破解自己的OpenCL代码时解决了我的问题。但是,鉴于我在学习的几个月中发现的关于OpenCL的调试信息几乎没有用处,因此我认为将其写下来的努力可能会帮助其他人,因为解决了我的问题对于初学者来说并不明显。
上下文:我在我的C语言上写有约束的raytracer,但允许在学校使用OpenCL。我已经构建并调试了一个OpenCL RNG库,可以从简单的内核调用它,已经将一些算法移植到了子函数中,但是仍在学习内存管理和将大型算法分解为要排成队列的有组织的内核。
OS:Xubuntu 18.04 平台:NVIDIA CUDA |设备:GeForce GTX 950M |版本:OpenCL 1.2 CUDA
我的数据出现不一致的情况:printf()告诉我,我的数据存在于我的第二个内核(发生问题的那个内核)中并且是一致的;但从未遇到过相应的“ if”语句中的检查。更糟糕的是,似乎清楚地读取了是否为“假”的陈述,并且鉴于GPU控制流程的怪异,我感到茫然。
Internet上的两个页面讨论的主题与我所获得的内容最相似,但都不是我的问题(这可能是您的原因,为什么我要添加它们):
https://community.amd.com/thread/225707
https://computergraphics.stackexchange.com/questions/4115/gpu-branching-if-without-else
要调试,我在子函数中使用了以下代码片段,该代码片段将像素的颜色返回给主内核(称为内核)。
if (isequal((float)scene->camera.c_to_w.sF, (float)0.))
{
return ((float3)(0., 255., 0.));
}
else if (isequal((float)scene->camera.c_to_w.sF, (float)0.5))
{
return ((float3)(255., 0., 255.));
}
else //if (some other condition)
return ((float3)(255., 255., 0.));
没有此代码段的函数将返回黑屏。否则,它将根据以下行为返回一个if语句之一颜色的屏幕。 我发现分别注释“ else”语句并一起使用这些值,我发现:只要存在此代码段,就必须读取其中一个“ return(R,G,B)”;如果其中至少一个为真,则将其读取,否则行为始终是该可变长度if-else序列的第一个条件。
答案 0 :(得分:0)
我的错误是简单地缺少“ return(result_pixel_color);”行。在我的get_pixel_color()子函数的末尾。是的,我很傻。
似乎OpenCL编译器不会像大多数C编译器一样警告您“控制流在返回之前到达非void函数的末尾”类型错误。在我的案例中,缺少回报的不确定行为是采用将函数中的ANY回报作为控制流的一般回报的方法。 OpenCL编译器是否可能还会滑动,还可能会警告您其他经典错误:对您自己的代码更为挑剔!
这是一个比较笼统的陈述,但是我觉得这对于在学习OpenCL时遇到一些晦涩错误的人可能很有用。我的问题是我高估了OpenCL编译器的帮助程度,特别是考虑到我的代码大小。我们试图在带有.cl.h标头的不同.cl文件中包含许多子功能,以使其在结构和注释中清晰易懂且模块化:这是一个团队项目,但我已经最了解OpenCL了……看来内核大部分情况下,编码实际上是使函数长一百行,这对于IMO的可维护性和模块化确实是一个问题。每个文件有1个以上内核,每个程序有1个以上文件,您开始遇到问题,尤其是在编译时。对于像(双向/快速/等)路径跟踪这样的复杂算法,该算法需要对许多不同类型的大数据,加速结构和分类光线进行建模,以便以工作组一致的方式运行相交,因此您应该警惕编译器,而永远知道您的错误实际上是多么愚蠢/平凡。