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