C++ 等待内核完成OpenCL

C++ 等待内核完成OpenCL,c++,events,opencl,wait,C++,Events,Opencl,Wait,我的OpenCL程序并不总是在执行进一步的主机(c++)代码之前完成。OpenCL代码只执行到某一点(看起来是随机的)。代码缩短了一点,因此可能缺少一些内容 cl::Program::Sources sources; string code = ResourceLoader::loadFile(filename); sources.push_back({ code.c_str(),code.length() }); program = cl::Program(OpenCL::context,

我的OpenCL程序并不总是在执行进一步的主机(c++)代码之前完成。OpenCL代码只执行到某一点(看起来是随机的)。代码缩短了一点,因此可能缺少一些内容

cl::Program::Sources sources;
string code = ResourceLoader::loadFile(filename);
sources.push_back({ code.c_str(),code.length() });

program = cl::Program(OpenCL::context, sources);

if (program.build({ OpenCL::default_device }) != CL_SUCCESS)
{
    exit(-1);
}
queue = CommandQueue(OpenCL::context, OpenCL::default_device);
kernel = Kernel(program, "main");
Buffer b(OpenCL::context, CL_MEM_READ_WRITE, size);
queue.enqueueWriteBuffer(b, CL_TRUE, 0, size, arg);
buffers.push_back(b);
kernel.setArg(0, this->buffers[0]);

vector<Event> wait{ Event() };
第2版:

queue.enqueueNDRangeKernel(kernel, NDRange(), range, NullRange, &wait, NULL);

版本1只是不等待OpenCL程序。版本2使程序崩溃(位于queue.enqueueNDRangeKernel):

在foo.exe中的0x51D99D09(nvoncl.dll)处引发异常:0xC0000005:访问冲突读取位置0x0000002C

如何让主机在这里等待GPU完成


编辑:queue.enqueueNDRangeKernel返回-1000。当它在一个相当小的内核上返回0时,版本1会在内核完成时发出信号
wait[0]
,这是正确的做法

版本2要求您的
clEnqueueNDRangeKernel()
在启动该内核之前等待
wait
中的事件[这显然不起作用]

就其本身而言,
queue.finish()
[或
clFinish()
]应该足以确保内核已完成

由于您已经完成了
clCreateUserEvent
,并且没有将其传递到初始化事件的任何其他文件中,因此第二个变量不起作用

它崩溃是相当糟糕的[它应该返回“invalid event”或类似的消息-但您使用的驱动程序可能无法检查事件是否已初始化]。我有理由相信与我一起工作的驱动程序会在这种情况下发出错误-但我尽量避免出错

我不知道1000来自哪里——它既不是有效的错误代码,也不是CL C++包装的合理返回值。内核大小[和/或在短时间或长时间内完成]都不应该影响排队返回值,因为应该做的只是让工作排队[不保证它在执行

queue.flush()
clFlush
之前开始]。等待它完成应该发生在其他地方


<>我通过原始OpenCL API完成大部分工作,而不是C++包装,这就是为什么我要做的是他们所做的,而不是C++包装。

我也面临着OpenCL的类似问题,即一些数据流包我们没有被OpenCL处理。p> 我意识到这只发生在笔记本电脑插入扩展底座时

也许这对s.o.有帮助。 (无clFlush或clFinish调用)

queue.enqueueNDRangeKernel(kernel, NDRange(), range, NullRange, &wait, NULL);
wait[0].wait();

queue.finish();