我在使用具有 OpenCL/OpenGL 互操作性的多个 GPU 时遇到问题。我正在尝试编写一个呈现密集计算结果的应用程序。最后它会运行一个优化问题,然后根据结果在屏幕上渲染一些东西。作为测试用例,我从本课程的粒子模拟示例代码开始:http ://web.engr.oregonstate.edu/~mjb/sig13/
示例代码创建 OpenGL 上下文,然后使用 cl_khr_gl_sharing 扩展创建共享状态的 OpenCL 上下文。当我使用单个 GPU 时,一切正常。创建上下文如下所示:
3. create an opencl context based on the opengl context:
cl_context_properties props[ ] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext( ),
CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay( ),
CL_CONTEXT_PLATFORM, (cl_context_properties) Platform,
0
};
cl_context Context = clCreateContext( props, 1, Device, NULL, NULL, &status );
if( status != CL_SUCCESS)
{
PrintCLError( status, "clCreateContext: " );
exit(1);
}
稍后,该示例使用 clCreateFromGLBuffer 创建共享 CL/GL 缓冲区。
现在,我想从两个 GPU 设备创建一个上下文:
cl_context Context = clCreateContext( props, 2, Device, NULL, NULL, &status );
我已经成功打开了这些设备,并且可以查询它们是否都支持 cl_khr_gl_sharing,并且都可以单独工作。但是,当尝试创建上述上下文时,我得到
CL_INVALID_OPERATION
这是 cl_khr_gl_sharing 扩展添加的错误代码。在扩展描述(上面链接)它说
CL_INVALID_OPERATION 如果为 CGL、EGL、GLX 或 WGL 之一指定了上下文或共享组对象,并且满足以下任何条件:
- OpenGL 实现不支持为其指定了上下文或共享组对象的窗口系统绑定 API。
- 多个属性 CL_CGL_SHAREGROUP_KHR、CL_EGL_DISPLAY_KHR、CL_GLX_DISPLAY_KHR 和 CL_WGL_HDC_KHR 设置为非默认值。
- 属性 CL_CGL_SHAREGROUP_KHR 和 CL_GL_CONTEXT_KHR 都设置为非默认值。
- 参数中指定的任何设备都不能支持共享 OpenGL 对象数据存储的 OpenCL 对象,如第 9.12 节所述。”
该描述似乎不完全适合我的任何情况。不能与多个 GPU 进行 OpenCL/OpenGL 互操作吗?还是我有异构硬件?我从枚举的设备中打印出一些参数。我刚刚使用了两个随机的 GPU,我可以拿到手。
PlatformID: 18483216
Num Devices: 2
-------- Device 00 ---------
CL_DEVICE_NAME: GeForce GTX 285
CL_DEVICE_VENDOR: NVIDIA Corporation
CL_DEVICE_VERSION: OpenCL 1.0 CUDA
CL_DRIVER_VERSION: 304.88
CL_DEVICE_MAX_COMPUTE_UNITS: 30
CL_DEVICE_MAX_CLOCK_FREQUENCY: 1476
CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU
-------- Device 01 ---------
CL_DEVICE_NAME: Quadro FX 580
CL_DEVICE_VENDOR: NVIDIA Corporation
CL_DEVICE_VERSION: OpenCL 1.0 CUDA
CL_DRIVER_VERSION: 304.88
CL_DEVICE_MAX_COMPUTE_UNITS: 4
CL_DEVICE_MAX_CLOCK_FREQUENCY: 1125
CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU
cl_khr_gl_sharing is supported on dev 0.
cl_khr_gl_sharing is supported on dev 1.
请注意,如果我创建没有互操作部分的上下文(例如 props 数组如下所示),那么它会成功创建上下文,但显然不能与应用程序的 OpenGL 端共享缓冲区。
cl_context_properties props[ ] =
{
CL_CONTEXT_PLATFORM, (cl_context_properties) Platform,
0
};