1

首先,这是我第一次真正感到有必要在 StackOverflow 上提出问题,但我解决了我的问题,同时对自己的 OpenCL 代码进行了修改和破解。然而,考虑到我在学习 OpenCL 的几个月中发现的有用且易于理解的调试信息很少,我认为写下来的努力可能会帮助我所在位置的其他人,因为我的问题的解决方案对于初学者来说并不明显。

上下文:我正在编写一个光线跟踪器,在我的 C 上具有约束,但允许在学校使用 OpenCL。我已经构建并调试了一个可以从简单内核调用的 OpenCL RNG 库,已经将一些算法移植到子函数中,但我仍在学习内存管理和将大型算法分解为有组织的内核序列以进行排队。

操作系统:Xubuntu 18.04 平台:NVIDIA CUDA | 设备:GeForce GTX 950M | 版本:OpenCL 1.2 CUDA

我的数据不连贯:printf() 告诉我,我的数据在我的第二个内核(发生问题的那个内核)中存在并且是连贯的;但它从未遇到过相应的“if”语句中的检查。更糟糕的是,它似乎清楚地读取了“错误”的 if 语句,并且考虑到 GPU 控制流的怪异,我不知所措。

互联网上的两个页面讨论的主题与我得到的最相似,但都不是我的问题(这可能是你的问题,这就是我添加它们的原因):

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 序列的第一个条件。

4

1 回答 1

0

我的错误是简单地缺少“return (result_pixel_color);”行 在我的 get_pixel_color() 子函数的末尾。是的,我很笨。

似乎 OpenCL 编译器不会像大多数 C 编译器那样警告您“控制流在返回之前到达非 void 函数的末尾”类型错误。在我的案例中,缺少返回的未定义行为采取了将函数中的任何返回作为控制流的一般返回的方法。如果这个错误可以滑动,OpenCL 编译器可能不会警告您其他经典错误:对您自己的代码更加挑剔!

这是一个更笼统的陈述,但我觉得它可能对在学习 OpenCL 时遇到一些晦涩的错误的人有用。我的问题是我高估了 OpenCL 编译器的帮助,尤其是考虑到我的代码大小。我们试图在带有 .cl.h 标头的不同 .cl 文件中包含许多子功能,以使其架构和注释清晰且模块化:这是一个团队项目,但我已经最了解 OpenCL... 似乎内核大多数情况下,编码实际上是关于使函数长达数百行,这对于 IMO 的可维护性和模块化确实是一个问题。每个文件超过 1 个内核,每个程序超过 1 个文件,您就会开始遇到问题,尤其是在编译时。

于 2019-02-14T20:18:37.443 回答