Взаимодействие OpenCL / OpenGL с несколькими графическими процессорами

у меня возникли проблемы с использованием нескольких графических процессоров с OpenCL/OpenGL interop. Я пытаюсь написать приложение, которое отображает результат интенсивного вычисления. В конце концов он запустит задачу оптимизации, а затем, основываясь на результате, отобразит что-то на экране. В качестве тестового случая я начинаю с кода примера моделирования частиц из этого курса:http://web.engr.oregonstate.edu / ~mjb / sig13/

пример кода создает и контекст OpenGL, затем создает контекст OpenCL, который разделяет состояние, используя расширение cl_khr_gl_sharing. Все работает нормально, когда я использую один 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);
  }

далее в Примере создаются общие буферы CL/GL с помощью clCreateFromGLBuffer.

теперь я хотел бы создать контекст из двух устройств 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 привязки, для которого объекты context или share group были указанный.
    • более одного атрибута CL_CGL_SHAREGROUP_KHR, CL_EGL_DISPLAY_KHR, CL_GLX_DISPLAY_KHR, и CL_WGL_HDC_KHR это значение по умолчанию значение.
    • оба атрибута CL_CGL_SHAREGROUP_KHR и CL_GL_CONTEXT_KHR имеют значения не по умолчанию.
    • любого из устройств, указанных в аргументе не может объекты OpenCL поддержки которые делят хранилище данных OpenGL объект, как описано в разделе 9.12."

это описание, похоже, не подходит ни к одному из моих случаев. Невозможно ли выполнить взаимодействие OpenCL/OpenGL с несколькими графическими процессорами? Или у меня гетерогенное оборудование? Я распечатал несколько параметров из перечисленных устройств. Я только что взял два случайных графических процессора,которые я мог бы получить.

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.

обратите внимание, что если я создаю контекст без часть взаимодействия (такая, что массив реквизита выглядит ниже), то он успешно создает контекст, но, очевидно, не может совместно использовать буферы со стороной OpenGL приложения.

cl_context_properties props[ ] =
{
   CL_CONTEXT_PLATFORM, (cl_context_properties) Platform,
   0
};

2 ответов


когда вы вызываете эти две строки:

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

вызовы должны поступать изнутри нового потока с новым контекстом OpenGL. Обычно можно связать только один контекст OpenCL с одним контекстом OpenGL для одного устройства за раз в потоке.


несколько связанных вопросов и примеров

  • здесь по теме чистого подхода OpenGL к общему обработка между несколькими графическими процессорами
  • еще один чистый OpenGL multiple gpu вопрос
  • A пример производителя/потребителя использование нескольких графических процессоров см. исходный файл производителя для вызовов, чтобы сделать текущий (выглядит специфичным для windows, но поток будет похож в другом месте). Видеть glContext дополнительные сведения

    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 из памяти обмена уравнениями между графическими процессорами, как и ожидалось?