简体   繁体   English

等待内核完成OpenCL

[英]Wait for kernel to finish OpenCL

My OpenCL program doesn't always finish before further host (c++) code is executed. 在执行其他主机(c ++)代码之前,我的OpenCL程序并不总是完成。 The OpenCL code is only executed up to a certain point (which apperears to be random). OpenCL代码只能执行到特定点(看起来是随机的)。 The code is shortened a bit, so there may be a few things missing. 代码缩短了一点,因此可能缺少一些东西。

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() };

Version 1: 版本1:

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

Version 2: 版本2:

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

.

wait[0].wait();

queue.finish();

Version 1 just does not wait for the OpenCL program. 版本1只是不等待OpenCL程序。 Version 2 crashes the program (at queue.enqueueNDRangeKernel): 版本2使程序崩溃(位于queue.enqueueNDRangeKernel):

Exception thrown at 0x51D99D09 (nvopencl.dll) in foo.exe: 0xC0000005: Access violation reading location 0x0000002C. 在foo.exe中的0x51D99D09(nvopencl.dll)处引发了异常:0xC0000005:访问冲突读取位置0x0000002C。

How would one make the host wait for the GPU to finish here? 如何使主机在这里等待GPU完成?

EDIT: queue.enqueueNDRangeKernel returns -1000. 编辑:queue.enqueueNDRangeKernel返回-1000。 While it returns 0 on a rather small kernel 虽然在相当小的内核上返回0

Version 1 says to signal wait[0] when the kernel is finished - which is the right thing to do. 版本1表示在内核完成时发出wait[0]信号-这是正确的做法。

Version 2 is asking your clEnqueueNDRangeKernel() to wait for the events in wait before it starts that kernel [which clearly won't work]. 第2版问你clEnqueueNDRangeKernel()等待事件中的wait它启动的内核[这显然是行不通]之前。

On it's own, queue.finish() [or clFinish() ] should be enough to ensure that your kernel has completed. queue.finish() [或clFinish() ]应该足以确保您的内核已完成。

Since you haven'd done clCreateUserEvent , and you haven't passed it into anything else that initializes the event, the second variant doesn't work. 由于您没有完成clCreateUserEvent ,并且还没有将其传递给任何其他初始化事件的方法,因此第二种方法不起作用。

It is rather bad that it crashes [it should return "invalid event" or some such - but presumably the driver you are using doesn't have a way to check that the event hasn't been initialized]. 它崩溃很糟糕[它应该返回“无效事件”或类似的东西-但大概您正在使用的驱动程序没有办法检查事件是否未初始化]。 I'm reasonably sure the driver I work with will issue an error for this case - but I try to avoid getting it wrong... 我可以肯定地确定与我合作的驱动程序会在这种情况下发出错误-但我会尽量避免出错...

I have no idea where -1000 comes from - it is neither a valid error code, nor a reasonable return value from the CL C++ wrappers. 我不知道-1000的来源-它既不是有效的错误代码,也不是CL C ++包装程序的合理返回值。 Whether the kernel is small or large [and/or completes in short or long time] shouldn't affect the return value from the enqueue, since all that SHOULD do is to enqueue the work [with no guarantee that it starts until a queue.flush() or clFlush is performed]. 内核是小还是大[和/或在短期或长时间内完成]都不会影响queue.flush()的返回值,因为应该做的只是使工作入队[不保证它要等到queue.flush()开始queue.flush()clFlush执行]。 Waiting for it to finish should happen elsewhere. 等待它完成应该在其他地方发生。

I do most of my work via the raw OpenCL API, not the C++ wrappers, which is why I'm referring to what they do, rather than the C++ wrappers. 我的大部分工作都是通过原始的OpenCL API而不是C ++包装器完成的,这就是为什么我指的是它们的作用,而不是C ++包装器。

I faced a similar problem with OpenCL that some packages of a data stream we're not processed by OpenCL. 我在使用OpenCL时遇到了类似的问题,即OpenCL不处理某些数据流包。

I realized it just happens while the notebook is plugged into a docking station. 我意识到这只是在笔记本计算机插入扩展坞时发生的。

Maybe this helps so (No clFlush or clFinish calls) 也许有帮助(没有clFlush或clFinish调用)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM