MacOS上的OpenCL:使用AMD Radeon 555作为CL设备时,发布版本中为SIGABRT,调试版本中为libdispatch中的EXC_BAD_INSTRUCTION

时间:2019-04-12 09:19:47

标签: c++ macos opencl libdispatch

在基于OpenCL的应用程序中,我在MacOS上遇到了难以追踪的错误。在一个发行版本中,我的代码有时会因SIGABRT而崩溃,在一个发行版本中,我在线程上得到一个EXC_BAD_INSTRUCTION显然是在管理某些lib派发/ GCD内容(com.apple.libdispatch-manager)。请注意,我自己没有调用任何与GCD相关的东西,因此我认为这是由Apple OpenCL运行时在后台完成的。

上下文是一个基准测试应用程序,用于测量CL命令排队和接收CL_COMPLETE回调以各种方式访问​​CL缓冲区之间的延迟。您将在下面找到代码。仅对我的MacBook Pro(AMD Radeon Pro 555计算引擎)中的三个可用CL设备之一发生错误。

代码的相关部分:

nlohmann::json performTestUseHostPtr()
{
    nlohmann::json results;

    std::vector<cl::Event> inputBufferEvent  (1);
    std::vector<cl::Event> outputBufferEvent (1);
    std::vector<cl::Event> kernelEvent       (1);

    for (auto size : testSizes)
    {
        std::vector<float> inputBufferHost  (size);
        std::vector<float> outputBufferHost (size);

        cl::Buffer inputBuffer  (context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY,  size * sizeof (float), inputBufferHost.data());
        cl::Buffer outputBuffer (context, CL_MEM_USE_HOST_PTR | CL_MEM_WRITE_ONLY, size * sizeof (float), outputBufferHost.data());

        void* inputBufferMapped = queue.enqueueMapBuffer (inputBuffer, CL_TRUE, CL_MAP_WRITE_INVALIDATE_REGION, 0, size * sizeof (float));
        std::memcpy (inputBufferMapped, testData.data(), size * sizeof (float));

        kernel.setArg (0, inputBuffer);
        kernel.setArg (1, outputBuffer);

        for (int i = 0; i < numTests; ++i)
        {
            startTimes[i] = my::HighResolutionTimer::now();

            queue.enqueueUnmapMemObject (inputBuffer, inputBufferMapped, nullptr, &inputBufferEvent[0]);
            inputBufferEvent[0].setCallback (CL_COMPLETE, setTimestampCallback, &unmapCompletedTimes[i]);

            queue.enqueueNDRangeKernel (kernel, cl::NullRange, cl::NDRange (size), cl::NullRange, &inputBufferEvent, &kernelEvent[0]);
            kernelEvent[0].setCallback (CL_COMPLETE, setTimestampCallback, &kernelCompletedTimes[i]);

            void* outputBufferMapped = queue.enqueueMapBuffer (outputBuffer, CL_FALSE, CL_MAP_READ, 0, size * sizeof (float), &kernelEvent, &outputBufferEvent[0]);
            outputBufferEvent[0].setCallback (CL_COMPLETE, setTimestampCallback, &mapCompletedTimes[i]);

            inputBufferMapped = queue.enqueueMapBuffer (inputBuffer, CL_TRUE, CL_MAP_WRITE_INVALIDATE_REGION, 0, size * sizeof (float), &kernelEvent, nullptr);

            // --- Release build error seems to happen somewhere here ---

            queue.finish();

            std::memcpy (inputBufferMapped, outputBufferMapped, size * sizeof (float));

            queue.enqueueUnmapMemObject (outputBuffer, outputBufferMapped);
            queue.finish();
        }

        queue.enqueueUnmapMemObject (inputBuffer, inputBufferMapped);

        results["vecSize=" + std::to_string (size)] = calculateTimes();

        queue.finish();
    }

    return results;
}

注释:

我检查了所有CL调用的错误代码,所有错误代码都返回CL_SUCCESS,只是在上面的代码中将它们删除了,以便进行更好的概述。 我标记了我大致假定会发生错误的行,这是基于在release版本中插入打印语句并观察错误发生之前代码的哪些点已完成。此外,在queue.finish();语句上方插入打印语句会使该错误消失,因此这可能与计时有关。

更新

在我以为发生错误的行中插入短暂睡眠并运行调试版本时,它现在还会触发SIGABRT。另外,我可以在控制台上找到以下打印件:

OpenCLLatencyTests(17903,0x10012a5c0) malloc: tiny_free_list_remove_ptr: Internal invariant broken (next ptr of prev): ptr=0x1003052d0, prev_next=0x0
OpenCLLatencyTests(17903,0x10012a5c0) malloc: *** set a breakpoint in malloc_error_break to debug
Signal: SIGABRT (signal SIGABRT)
E0412 11:55:02.898913 233472000 ProtobufClient.cpp:63] No such process

问题:

  • 有人可以在我的代码中发现明显的错误吗?
  • 如果不是,那么Apple OpenCL实施中是否存在任何已知错误可能导致此类错误?

0 个答案:

没有答案