OpenCL/OpenGL Interop с несколькими GPU

У меня возникли проблемы с использованием нескольких графических процессоров с использованием OpenCL/OpenGL. Я пытаюсь написать приложение, которое дает результат интенсивного вычисления. В итоге он будет запускать задачу оптимизации, а затем, основываясь на результате, отобразит что-то на экране. В качестве тестового примера я начинаю с кода примера моделирования частиц из этого курса: 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 привязки, для которого объекты контекста или группы разделов были указано.
    • Более одного из атрибутов 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 с несколькими GPU? Или я имею гетерогенное оборудование? Я распечатал несколько параметров из моих перечисленных устройств. Я только что взял два случайных 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.

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

cl_context_properties props[ ] =
{
   CL_CONTEXT_PLATFORM, (cl_context_properties) Platform,
   0
};
+9
30 июл. '13 в 20:33
источник поделиться
2 ответа

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

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

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

+1
16 мар. '15 в 14:30
источник

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


    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 будет использовать это устройство для записи. Однако, если вы затем используете буфер в очереди (deviceB) в том же контексте, OpenCL будет распознавать, что deviceA имеет самые последние данные и переместит их на deviceB перед его использованием. Короче говоря, до тех пор, пока вы используете события, чтобы гарантировать, что ни одно из двух устройств не пытается одновременно получить доступ к одному и тому же объекту памяти, OpenCL гарантирует, что каждое использование объекта памяти имеет самые последние данные, независимо от того, какое устройство использовало его в последний раз".

Я предполагаю, что если вы выберете OpenGL из памяти обмена данными между gpus, как и ожидалось?

+2
02 мая '14 в 13:55
источник

Посмотрите другие вопросы по меткам или Задайте вопрос