如果从二进制文件加载,OpenCL 会导致 CL_INVALID_COMMAND_QUEUE

OpenCL causes CL_INVALID_COMMAND_QUEUE if loaded from binary

我正在努力 saving/loading 二进制内核:如果我从源代码构建,程序运行良好。但是如果我编写内核并将其加载为二进制文件。我收到 CL_INVALID_COMMAND_QUEUE 呼叫 m_prog.getCommandQueues()[iDevice].enqueueNDRangeKernel。我的平台在这两种情况下都是(来自二进制,来自源)英特尔,我的设备在这两种情况下都是我的 CPU.

可能有用的附加信息:

  1. 在CL_INVALID_COMMAND_QUEUE之前没有抛出异常(定义了__CL_ENABLE_EXCEPTIONS)

  2. 程序引用计数 1

  3. 程序 num devs 1

  4. 程序 num devs 1

  5. 设备的程序构建状态 CL_BUILD_SUCCES

  6. 程序构建日志

    • 设备构建开始

    • 设备构建完成

    • 重新加载程序二进制对象。

.

/// write binaries to file
std::ofstream bfile(filenameGenerator(m_platform, fileName), std::ios::binary);
if (!bfile) return IT_CL_FILE_NOT_FOUND;

std::vector<size_t> sizes = m_prog.getInfo<CL_PROGRAM_BINARY_SIZES>();
std::vector<char*>  binaries = m_prog.getInfo<CL_PROGRAM_BINARIES>();

bfile.write((char*)&sizes[0], sizeof(size_t));
bfile.write(binaries[0], sizes[0]);
delete[] binaries[0];

/// ... somewhere else ...

///read binaries from file
ifstream bfile(filenameGenerator(platform, fileName), std::ios::binary);
size_t n;
std::vector<char> buf;

bfile.read((char*)&n, sizeof(size_t));
buf.resize(n);
bfile.read(buf.data(), n);

m_prog = cl::Program(context, devs, cl::Program::Binaries(
    1, std::make_pair(static_cast<const void*>(buf.data()), n)));
m_prog.build(devs);

/// later ...
m_prog.getCommandQueues()[iDevice].enqueueNDRangeKernel ///throws

编辑: 添加最后两行代码,以清除调用顺序

一个程序只有在为特定设备构建时才应该有一个关联的命令队列。

从二进制数据加载的程序还没有构建,不清楚是否有命令队列。

不建议调用 m_prog.getCommandQueues()[device],因为您无法确定是否会返回队列。你应该在外面创建自己的队列,然后把程序排在那里。

我自己找到了解决方案,我成功地没有初始化 vector<cl::CommandQueue> 并且只调整了 vector 的大小。