微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

索引访问器时,EXC_BAD_ACCESS代码= EXC_I386_GPFLT

如何解决索引访问器时,EXC_BAD_ACCESS代码= EXC_I386_GPFLT

我想运行一个并行的for循环来初始化带有随机值的二维缓冲区。但是我在内核的第一行中得到了EXC_BAD_ACCESS(code = EXC_I386_GPFLT)异常。

这是代码(Pixel结构来自PixelGameEngine库):

namespace olc
{
    struct Pixel
    {
        union
        {
            uint32_t n = nDefaultPixel;
            struct
            {
                uint8_t r;
                uint8_t g;
                uint8_t b;
                uint8_t a;
            };
        };

        enum Mode
        {
            norMAL,MASK,ALPHA,CUSTOM
        };

        Pixel()
        {
            r = 0;
            g = 0;
            b = 0;
            a = nDefaultAlpha;
        }

        Pixel(uint8_t red,uint8_t green,uint8_t blue,uint8_t alpha = nDefaultAlpha)
        {
            n = red | (green << 8) | (blue << 16) | (alpha << 24);
        }

        Pixel(uint32_t p) { n = p; }
    };
}

 int main()
{
    auto* screenBuffer = new olc::Pixel[256 * 240];

    cl::sycl::queue queue;
    {
        cl::sycl::buffer<olc::Pixel,2> b_screenBuffer(screenBuffer,cl::sycl::range<2>(256,240));

        queue.submit([&](cl::sycl::handler& cgh) {
            auto screenBuffer_acc = b_screenBuffer.get_access<cl::sycl::access::mode::write>(cgh);

            cgh.parallel_for(cl::sycl::range<2>(256,240),[&](cl::sycl::id<2> index) {
                screenBuffer_acc[index] = olc::Pixel(rand() % 256,//Here I get the exception 
                                                     rand() % 256,rand() % 256);
            });
        });
    }

    return 0;
}

我在带有Boost 1.74和C ++ 20的Mac OS Catalina上使用triSYCL 0.1.0。我试图将缓冲区的数据类型从old :: Pixel更改为float并使缓冲区成为1维,但是我总是遇到相同的异常。 有人知道我可以尝试什么吗?

解决方法

除了一个小问题,您的代码还不错:

cgh.parallel_for(cl::sycl::range<2>(256,240),[&](cl::sycl::id<2> index) {...}

在这里,您正在内核中通过引用捕获变量。永远不要这样做。 如果您以加速器(例如GPU)为目标,则捕获的变量将引用主机内存,并且在设备上访问时会崩溃。如果仅将CPU作为目标,则它仍然是不确定的行为,因为内核是异步执行的,并且在运行内核时捕获的变量可能不再存在。

因此,始终按值在内核lambda中捕获:

cgh.parallel_for(cl::sycl::range<2>(256,[=](cl::sycl::id<2> index) {...}

在命令组范围queue.submit([&](sycl::handler& cgh){...})的lambda中,通过引用捕获总是很好的,因为命令组范围总是在主机上同步评估。

我手头没有安装triSYCL,但是经过小小的修改后,您的代码就可以与hipSYCL一起正常运行(顺便说一下,该代码也可以在Mac上运行,以防您想通过两种实现来仔细检查代码)有时可能会有帮助)。 如果更改lambda捕获不能解决您的问题,则可能要在triSYCL的github存储库上打开一个问题。

,

我同意@illuhad。

我尝试过使用triSYCL,并在顶部添加了一些富有想象力的

#include "CL/sycl.hpp"
constexpr auto nDefaultPixel = 2;
constexpr auto nDefaultAlpha = 42;

进行编译(请发布一些完整的代码示例),并且可以正常工作。

之所以必须使用[=]而不是[&],是因为SYCL还针对没有直接从加速器访问主机存储器的体系结构。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。