9

我在使用具有 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
};
4

2 回答 2

2

几个相关的问题和例子


    bool stageProducer::preExecution() 
    {
        if(!glContext::getInstance().makeCurrent(_rc))
        {
            window::getInstance().messageBoxWithLastError("wglMakeCurrent");
            return false;
        }
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fboID);
        return true;
    }

OpenCL 特定,但与此问题相关

“如果您对 queueA(deviceA) 上的缓冲区进行写入排队,那么 OpenCL 将使用该设备进行写入。但是,如果您随后在同一上下文中使用 queueB(deviceB) 上的缓冲区,OpenCL 将识别出 deviceA 具有最新的数据,在使用前会将其移到 deviceB 上。简而言之,只要你使用事件来确保没有两个设备同时试图访问同一个内存对象,OpenCL 会确保每次使用内存对象拥有最新的数据,无论最后使用的是哪个设备。”

我假设当您将 OpenGL 排除在 gpus 之间共享内存的等式时会按预期工作吗?

于 2014-05-02T13:55:12.213 回答
1

当您调用这两行时:

CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext( ), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay( ),

调用需要来自具有新 OpenGL 上下文的新线程内部。通常每个线程一次只能将一个 OpenCL 上下文与一个设备关联到一个 OpenGL 上下文。

于 2015-03-16T14:30:29.207 回答