【发布时间】:2022-06-16 05:19:59
【问题描述】:
我正在尝试使用多个 GPU 来处理问题域。主要问题是我必须以某种方式找到一种在 GPU 之间有效传递缓冲区的方法。需要传递的缓冲区是每个 GPU 分配到的数组的边界值,因此一旦这些值在每个时间步更新,整个过程就可以在下一个时间步重复。
通过互联网搜索,我发现clEnqueueMigrateMemObects 就是为此目的。但是,我找不到任何有关跨 GPU 缓冲区传输的示例。我发现只有一种解释是this 帖子。我无法理解的部分是这部分(我放箭头的地方)
设备 1 上的命令队列:
- 迁移内存缓冲区1
- 将处理此缓冲区的内核排入队列
- ==> 保存与缓冲区 1 处理相关的最后一个事件 <==
设备 2 上的命令队列:
- 迁移内存缓冲区 1 - 使用队列 1 产生的事件来同步迁移。
- 将处理此缓冲区的内核排入队列
那么,示例代码如下所示? (假设我有两个 OpenCL 设备使用相同的平台和相同的上下文......)
... cl_context context = clCreateContext(NULL, numDevices, devices, NULL, NULL, &status); cl_command_queue cmdq_dev0, cmdq_dev1; cmdq_dev0 = clCreateCommandQueue(context, devices[0], 0, &status); cmdq_dev1 = clCreateCommandQueue(context, devices[1], 0, &status); cl_mem dev0_buf, dev1_buf, common_buf; dev0_buf = clCreateBuffer(context, CL_MEM_READ_WRITE, some_siz, NULL, &status); dev1_buf = clCreateBuffer(context, CL_MEM_READ_WRITE, some_siz, NULL, &status); common_buf = clCreateBuffer(context, CL_MEM_READ_WRITE, some_siz, NULL, &status); status = clEnqueueWriteBuffer(cmdq_dev0, buf_arr , CL_TRUE, 0, some_siz, dev0_arr, 0, NULL, NULL); status = clEnqueueWriteBuffer(cmdq_dev0, common_buf, CL_TRUE, 0, common_siz, common_arr, 0, NULL, NULL); status = clEnqueueWriteBuffer(cmdq_dev1, buf_arr , CL_TRUE, 0, some_siz, dev1_arr, 0, NULL, NULL); status = clEnqueueWriteBuffer(cmdq_dev1, common_buf, CL_TRUE, 0, common_siz, common_arr, 0, NULL, NULL); /* build some opencl program */ cl_kernel kernel0, kernel1 kernel0 = clCreateKernel(program, \"kernel0\", &status); kernel1 = clCreateKernel(program, \"kernel1\", &status); status = clSetKernelArg(kernel0, 0, sizeof(cl_int), &dev0_arr ); status = clSetKernelArg(kernel0, 1, sizeof(cl_int), &common_arr ); status = clSetKernelArg(kernel1, 0, sizeof(cl_int), &dev1_arr ); status = clSetKernelArg(kernel1, 1, sizeof(cl_int), &common_arr ); /* part where kernels are executed */ status = clEnqueueNDRangeKernel(cmdq_dev0, kernel0, 3, NULL, something, NULL, 0, NULL, NULL); status = clEnqueueMigrateMemObjects(cmdq_dev0, 1, &common_buf, CL_MIGRATE_MEM_OBJECT_HOST,0,NULL,NULL); status = clEnqueueNDRangeKernel(cmdq_dev1, kernel0, 3, NULL, something, NULL, 0, NULL, NULL); status = clEnqueueMigrateMemObjects(cmdq_dev1, 1, &common_buf, CL_MIGRATE_MEM_OBJECT_HOST,0,NULL,NULL); ...此外,在将
common_buf缓冲区对象从设备0 传递到设备1 时,我应该在函数clEnqueueMigrateMemObjects中指定命令队列,反之亦然。谢谢。
标签: opencl