内核没有'不要等待事件的发生
Kernel doesn't wait for events
我的内核调用有问题。我的代码如下:
std::vector<cl::Event> events;
...
queue.enqueueWriteBuffer(arrayFirst, CL_FALSE, 0, sizeOfArray, NULL, NULL, &arrayEvent);
events.push_back(arrayEvent);
queue.enqueueWriteBuffer(arraySecond, CL_FALSE, 0, sizeOfArraySecond, this->arraySecond, NULL, &arraySecondEvent);
events.push_back(arraySecondEvent);
kernel(cl::EnqueueArgs(queue, events, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond);
当我运行它时,它不会进入内核代码,但当我将"make_kernel"调用更改为:
kernel(cl::EnqueueArgs(queue, arraySecondEvent, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond);
它进入内核内部,但我不能保证"arrayFirst"的内存分配正确,我查看了OpenCl1.2 Wrapper的文档,发现调用应该是这样的:
cl::EnqueueArgs::EnqueueArgs(CommandQueue &queue,
const VECTOR_CLASS<Event> &events, NDRange offset, NDRange global,
NDRange local) //page 42
但是,当我试图传递事件向量的地址时,我会出现编译错误,即没有合适的方法带有以下参数。。
错误:
error: no instance of constructor "cl::EnqueueArgs::EnqueueArgs" matches the argument list
argument types are: (cl::CommandQueue, std::vector<cl::Event, std::allocator<cl::Event>> *, cl::NDRange, cl::NDRange)
valueOfImageKernel(cl::EnqueueArgs(valueOfImageQueue, &events, cl::NDRange(512), cl::NDRange(128)),
有人知道我做错了什么吗?
您不需要的下一行似乎给您带来了麻烦:queue.enqueueWriteBuffer(arrayFirst, CL_FALSE, 0, sizeOfArray, NULL, NULL, &arrayEvent);
当您实际上有东西要写时,您需要调用以写入缓冲区,而这里的情况并非如此。
下面是在PHI上测试的完整工作示例(只是为了清楚起见,省略了错误处理):
#include <iostream>
#include <vector>
#include <string>
#include <CL/cl.hpp>
int main()
{
const char *kernel_str{
"kernel void k1(global int *data1, global int *data2){"
" int local_id = get_local_id(0);"
" data1[local_id] = data2[local_id] + data2[local_id];"
"}" };
cl_int err = CL_SUCCESS;
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
cl::Platform plat;
for (auto &p : platforms)
{
std::vector<cl::Device> devices;
p.getDevices(CL_DEVICE_TYPE_ACCELERATOR, &devices);
if (!devices.empty())
{
plat = p;
break;
}
}
if (plat() == 0)
{
std::cout << "No OpenCL platform found.";
return -1;
}
cl_context_properties properties[] =
{ CL_CONTEXT_PLATFORM, (cl_context_properties)(plat)(), 0 };
cl::Context context(CL_DEVICE_TYPE_ACCELERATOR, properties);
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
cl::Program::Sources source(1, std::make_pair(kernel_str, strlen(kernel_str)));
cl::Program program = cl::Program(context, source);
err = program.build(devices);
cl::CommandQueue queue(context, devices[0], 0, &err);
size_t sizeOfArray = 512, sizeOfArraySecond = 512;
std::vector<int> varrayFirst(sizeOfArray);
std::vector<int> varraySecond(sizeOfArraySecond);
for (size_t x = 0; x < sizeOfArraySecond; ++x)
varraySecond[x] = x;
cl::Buffer arrayFirst(context, CL_MEM_WRITE_ONLY, sizeOfArray*sizeof(varrayFirst[0]));
cl::Buffer arraySecond(context, CL_MEM_READ_ONLY, sizeOfArraySecond*sizeof(varraySecond[0]));
cl::Event arraySecondEvent;
std::vector<cl::Event> events;
err = queue.enqueueWriteBuffer(arraySecond, CL_FALSE, 0, sizeOfArraySecond*sizeof(varraySecond[0]), &varraySecond[0], NULL, &arraySecondEvent);
events.push_back(arraySecondEvent);
cl::make_kernel<cl::Buffer&, cl::Buffer&> kernel(program, "k1");
cl::Event ev = kernel(cl::EnqueueArgs(queue, events, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond);
std::vector<cl::Event> evs(1, ev);
err = queue.enqueueReadBuffer(arrayFirst, CL_TRUE, 0, sizeOfArray*sizeof(varrayFirst[0]), &varrayFirst[0], &evs); // final blocking read
std::cout << "Outputting first 10 values: " << std::endl;
for (int x = 0; x < 10; ++x)
std::cout << varrayFirst[x] << ", ";
std::cout << std::endl;
return 0;
}
输出:
Outputting first 10 values:
0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
您的事件集合是正确的,内核调用也是正确的。现在的问题是…你确定内核被阻塞了吗?起步可能很慢。
我会用event.finish()
到内核事件来检查它。如果你的应用程序死锁,那么这就是事件的问题。
否则,您的可执行文件可能在内核运行之前就完成了(因为它正在等待第一个缓冲区副本,这需要很长时间)。所以你不会看到任何日志,因为当内核打印fs时,应用程序已经在清理了。
此外,如果您可以添加事件的所有代码,那么调试可能会很有用。因为我们没有看到事件数组的完整生命周期。
相关文章:
- 等待 WaitForMultipleObjects 窗口中的事件数量可变
- 一个线程等待多个线程事件
- C++11 - 可以等待多个不同事件的线程?
- 如何等待密钥事件,直到进程在 QT 中完成
- 了解如何在不冻结事件循环的情况下在 QThread 中休眠/等待
- 等待事件循环为空 /等到QT5小部件关闭
- 如何在C 中等待一组线程或其他事件
- Windows C++ UWP:等待 XX 毫秒,直到事件发生
- 在C++中等待带有OpenEvent方法的事件的正确方法是什么
- 我可以在 QP(量子平台)活动对象中等待 Windows 事件(WaitForMultipleObjects)吗?
- 我可以在事件和具有输入的IOCompletionPort上等待MultipleObjects吗
- 如何同时等待 I/O 完成端口和事件
- 如何使我的C++程序永远等待传感器事件而不终止
- Qt创建一个等待网络事件的对话框
- 快板:为什么要等待一个事件或直到60毫秒结束
- 使用boost::asio和strands的事件队列:等待新事件
- 内核没有'不要等待事件的发生
- 等待句柄/事件异步或回调在同一线程内
- 等待事件关闭窗口
- 为已经发出信号的事件等待singleobject