0
我试图运行一个执行OpenCL内核的多线程Java应用程序。我想在内核完成时通知其中一个线程,所以我尝试使用clSetEventCallback方法。直到另一个内核启动才调用JOCL eventCallback
对于我制备的方法
void runKernel(
cl_program program,
String functionName,
Object... params,
long[] globalWorkSize,
long[] localWorkSize
){
System.out.println(System.currentTimeMillis() +": Preparing Kernel "+kernel+);
int[] errCode = new int[1];
int errno;
cl_kernel kernel = CL.clCreateKernel(program, functionName, errCode);
/******INSERT ALL THE PARAMS******/
System.out.println(System.currentTimeMillis() +": Enqueueing Kernel "+kernel+);
cl_event event = new cl_event();
CL.clEnqueueNDRangeKernel(this.queue, kernel, 1, null, globalWorkSize, localWorkSize, 0, null, event);
CL.clSetEventCallback(event, CL_COMPLETE, new EventCallbackFunction() {
@Override
public void function(cl_event event, int command_exec_callback_type, Object user_data) {
System.out.println(System.currentTimeMillis() +": Finished kernel " + user_data);
}
}, kernel);
}
我调用该函数以用5个secongs间隙其间执行三个不同的内核。代码运行良好,我得到了预期的结果。但是,当我查看应用程序输出时,回调方法不会在实际的内核完成时执行,但一旦程序再次调用run方法。最后执行的内核的回调从不执行(由于得到的结果是正确的,内核被执行)。
1475085785924: Prepared Kernel cl_kernel[0x7f8b28098c90]
1475085785924: Enqueueing Kernel cl_kernel[0x7f8b28098c90]
1475085790925: Prepared Kernel cl_kernel[0x7f8b284fbd50]
1475085790925: Enqueueing Kernel cl_kernel[0x7f8b284fbd50]
1475085790925: Finished kernel cl_kernel[0x7f8b28098c90]
1475085795926: Prepared Kernel cl_kernel[0x7f8b2851abd0]
1475085795926: Enqueueing Kernel cl_kernel[0x7f8b2851abd0]
1475085795926: Finished kernel cl_kernel[0x7f8b284fbd50]
我的代码有什么问题,所以直到下一个内核入队才执行回调吗?我错过了什么?或者JOCL/OpenCL库没有正确地通知内核结束?
你确定它是由底层OpenCL实现后引起?无论如何,我会尽力重现这一点(我不能在接下来的几天内做到这一点,但尽量做到这一点)。不得不排队一个空内核看起来像一个可疑的解决方法... – Marco13
这是opencl实现上的东西。我检查了它使用相同的JOCL版本运行相同的程序,它在我的手机上工作,所以...这是我的笔记本电脑的libOpenCL.so库。我使用的是intel i7和集成GPU的ubuntu 16.04。任何建议? –
(我只是问,因为JOCL是我的图书馆之一,**如果**问题是由JOCL引起的,我会仔细看看这个)。所以GPU也来自英特尔(不是AMD或NVIDIA)?这个问题也可能与司机有关,所以这个信息可能是相关的。毫无疑问,在供应商的支持论坛上询问也是值得一试的(尽管他们可能期望用C语言编写一个[MCVE],以便他们可以轻松地再现问题) – Marco13