Ошибка компиляции ядра OpenCL -44 при использовании контекста OpenGL на Intel под Manjaro ⇐ C++
Ошибка компиляции ядра OpenCL -44 при использовании контекста OpenGL на Intel под Manjaro
Недавно я пытался использовать взаимодействие OpenCL-OpenGL. После некоторых проб и ошибок я обнаружил, что мне нужно инициализировать контекст OpenCL, предоставив ему правильные свойства. У меня он работал под Manjaro с установленными графическим процессором NVIDIA, драйвером NVIDIA и CUDA, но у меня возникли некоторые проблемы на устройствах Intel.
(Проблема возникает только под Manjaro с Intel, и я не могу протестировать ее под Windows на тех же устройствах, потому что они не мои)
Проблема в том, что для использования взаимодействия OpenCL-OpenGL мне нужно создать контекст OpenCL, используя свойства:
cl_context_properties свойства[] = { //для Linux CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties) платформа, 0 }; но если я предоставлю это контексту cl::Context context(default_device, Properties);, то после компиляции любого ядра int buildCode = program.build(); 'buildCode' равен -44, а program.getBuildInfo(default_device) возвращает строку из 0 символов. Из документации OpenCL я знаю, что -44 возвращается, «если программа не является допустимым программным объектом», но после дополнительных поисков в Интернете я нашел это, поэтому моя проблема может заключаться в чем угодно, что не было отображено разработчиками.
Я обнаружил, что на самом деле не имеет значения, что я добавляю в код ядра. Это может быть что-то вроде этого:
std::string kernel_code = «недопустимое ядро»; и я получу тот же код сборки -44. На большинстве этих устройств нет проблем с компиляцией любого ядра после создания контекста OpenCL без свойств.
Я пробовал это на:
[*]Manjaro 1st с графическим процессором NVIDIA (GTX1070) — работает [*]Windows с графическим процессором AMD (r9 380x) — работает [*]MacO с графическим процессором AMD (radeon pro 450) — работает; и процессор Intel (i7-6700HQ) – работает [*]Manjaro 2nd с процессором Intel (i5-3320M) — ошибка -44 (невозможно создать контекст OpenCL без свойств) [*]Manjaro 3rd с графическим процессором Intel (UHD Graphics 620) – ошибка -44. [*]Manjaro 4-й с графическим процессором Intel (UHD Graphics 620) – ошибка -44.
РЕДАКТИРОВАТЬ:
Все устройства, кроме (Manjaro с процессором Intel), которые я тестировал, были правильно распознаны и перечислены командой clinfo. Это clinfo от Manjaro с процессором Intel:
Количество платформ 1 Название платформы Intel(R) OpenCL Поставщик платформы Intel(R) Corporation Версия платформы OpenCL 1.2 Профиль платформы FULL_PROFILE Расширения платформы cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_length_images cl_khr_3d_image_writes cl_intel_exec_by_ local_thread cl_khr_spir cl_khr_fp64 Суффикс функции расширения платформы INTEL Название платформы Intel(R) OpenCL Количество устройств 1 Имя устройства Процессор Intel(R) Core(TM) i5-3320M @ 2,60 ГГц Поставщик устройства Intel(R) Corporation Идентификатор поставщика устройства 0x8086 Версия устройства OpenCL 1.2 (сборка 475) Версия драйвера 1.2.0.475 Устройство OpenCL C Версия OpenCL C 1.2 Тип устройства ЦП Профиль устройства FULL_PROFILE Доступное устройство Да Доступен компилятор Да Линкер доступен Да Максимальное количество вычислительных блоков 4 Максимальная тактовая частота 2600 МГц Раздел устройства (ядро) Максимальное количество субустройств 4 Поддерживаемые типы разделов по количеству, а также по именам (Intel) Поддерживаемые родственные домены (нет данных) Макс. размеры рабочего элемента 3 Максимальный размер рабочего элемента: 8192x8192x8192. Максимальный размер рабочей группы 8192 zsh: ошибка сегментации (сброс ядра) clinfo КОНЕЦ РЕДАКТИРОВАНИЯ
Это наиболее упрощенный код с правильной инициализацией, который воспроизведет эту ошибку:
#define CL_HPP_TARGET_OPENCL_VERSION 200 #include #include #include #include #include #include GLFWwindow* инициализироватьGLFW(ширина uint, высота uint); символ инициализацииGLEW(); cl::Device getDefaultClDevice(); cl::Program compileTestKernel(cl::Context context, cl::Device default_device); интервал основной(){ int ширина = 1024, высота = 1024; Окно GLFWwindow* = инициализироватьGLFW(ширина, высота); если (окно == nullptr){ возврат 1; } если (инициализироватьGLEW()){ возврат 1; } cl::Device default_device = getDefaultClDevice(); если (!default_device()){ возврат 1; } платформа cl_platform_id; clGetPlatformIDs(1, &платформа, NULL); cl_context_properties свойства[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), //если я прокомментирую какое-либо из свойств выше, я получу ошибку сегментации при попытке доступа к памяти OpenGL на NVIDIA; //если я прокомментирую оба из них, я получу ошибку сегментации при создании контекста Intel; //если я прокомментирую один или ничего, я получу -44 от program.build(); //только на процессорах Intel, мне это нужно для создания контекста; CL_CONTEXT_PLATFORM, (cl_context_properties) платформа, // это не повлияло на результаты моих тестов, но все используют это в примерах, поэтому я думаю, что это в некотором роде важно; 0 }; cl::Контекст контекста (default_device, свойства); cl::Program program = compileTestKernel(context, default_device); cl::CommandQueue очередь (контекст, default_device); cl::Kernel test(программа, "тест"); очередь.enqueueNDRangeKernel(test, cl::NullRange, cl::NullRange, cl::NullRange); очередь.финиш(); ошибка int = glGetError(); если (ошибка!= GL_NO_ERROR) { std::fprintf(stderr, «Ошибка OpenGL: %d\n», error); } glfwDestroyWindow (окно); вернуть 0; } void glfwErrorCallback(int error, const char* описание){ std::fprintf(stderr, "Ошибка: %s\n", описание); } GLFWwindow* инициализироватьGLFW(ширина uint, высота uint){ если (!glfwInit()){ std::fprintf(stderr, «Не удалось инициализировать GLFW!\n»); вернуть нульптр; } glfwSetErrorCallback (glfwErrorCallback); Окно GLFWwindow* = glfwCreateWindow(ширина, высота, "тест", NULL, NULL); если (!окно){ std::fprintf(stderr, «Не удалось создать окно GLFW!\n»); glfwTerminate(); вернуть нульптр; } glfwMakeContextCurrent (окно); glViewport (0,0, ширина, высота); glfwSwapInterval (1); окно возврата; } символ инициализацииGLEW(){ glewExperimental = GL_TRUE; если (glewInit() != GLEW_OK) { std::fprintf(stderr, «Не удалось инициализировать GLEW!\n»); glfwTerminate(); вернуть -1; } Ошибка GLenum = glGetError(); если (ошибка!= GL_NO_ERROR) { std::fprintf(stderr, «Ошибка OpenGL: %d\n», error); } const GLubyte* glVersion = glGetString(GL_VERSION); const GLubyte* glVendor = glGetString(GL_VENDOR); const GLubyte* glRenderer = glGetString(GL_RENDERER); std::printf("Версия GL:\t%s\n", glVersion); std::printf("Поставщик GL:\t%s\n", glVendor); std::printf("GL-рендерер:\t%s\n\n", glRenderer); вернуть 0; } cl::Device getDefaultClDevice(){ std::vector all_platforms; cl::Platform::get(&all_platforms); если (all_platforms.empty()){ std::fprintf(stderr, "Платформы не найдены. Проверьте установку OpenCL!\n"); вернуть cl::Device(); } интервал выбора = 0; cl::Platform default_platform = all_platforms[0]; std::printf("Использование платформы:\t%s\n", default_platform.getInfo().c_str()); std::vector all_devices; default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices); если (all_devices.size() == 0){ std::fprintf(stderr, "Устройства не найдены. Проверьте установку OpenCL!\n"); вернуть cl::Device(); } cl::Device default_device = all_devices[0]; std::printf("Использование устройства:\t%s\n", default_device.getInfo().c_str()); вернуть default_device; } cl::Program compileTestKernel(cl::Context context, cl::Device default_device){ cl::Program::Источники источников; std::string kernel_code = " void kernel create_gradient(){}"; source.push_back({kernel_code.c_str(), kernel_code.length()}); cl::Программа программа(контекст, исходники); int buildCode = program.build(); ошибка int = glGetError(); если (ошибка!= GL_NO_ERROR) { std::fprintf(stderr, «Ошибка OpenGL: %d\n», error); } если (buildCode != CL_SUCCESS) { std::fprintf(stderr, "Ошибка сборки (%d): %s\n", buildCode, program.getBuildInfo(default_device).c_str()); выход (1); } программа возврата; } Это сообщения, которые я получил со своих устройств:
Версия GL: 4.6.0 NVIDIA 535.113.01 Поставщик GL: корпорация NVIDIA Рендеринг GL: NVIDIA GeForce GTX 1070/PCIe/SSE2 Используемая платформа: NVIDIA CUDA. Используемое устройство: NVIDIA GeForce GTX 1070. и
Версия GL: 3.0 Mesa 21.3.9 Янтарный Поставщик GL: Центр технологий Intel с открытым исходным кодом Рендерер GL: Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2) Использование платформы: Intel(R) OpenCL. Используемое устройство: процессор Intel(R) Core(TM) i5-3320M @ 2,60 ГГц. Ошибка построения (-44): Я новичок в OpenCL или OpenGL, поэтому, возможно, мою проблему сможет легко объяснить кто-то более опытный. Если у вас есть какие-либо идеи о том, в чем может быть проблема, я был бы признателен, если бы поделился ею со мной. Также сообщите мне, могу ли я предоставить дополнительную полезную информацию, поскольку я тестировал это на многих устройствах. Я не хочу заполнять эту страницу потоком ненужного текста, а также мне придется просить друзей сделать это за меня (мои только Manjaro с NVIDIA и Manjaro с процессором Intel).
Недавно я пытался использовать взаимодействие OpenCL-OpenGL. После некоторых проб и ошибок я обнаружил, что мне нужно инициализировать контекст OpenCL, предоставив ему правильные свойства. У меня он работал под Manjaro с установленными графическим процессором NVIDIA, драйвером NVIDIA и CUDA, но у меня возникли некоторые проблемы на устройствах Intel.
(Проблема возникает только под Manjaro с Intel, и я не могу протестировать ее под Windows на тех же устройствах, потому что они не мои)
Проблема в том, что для использования взаимодействия OpenCL-OpenGL мне нужно создать контекст OpenCL, используя свойства:
cl_context_properties свойства[] = { //для Linux CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties) платформа, 0 }; но если я предоставлю это контексту cl::Context context(default_device, Properties);, то после компиляции любого ядра int buildCode = program.build(); 'buildCode' равен -44, а program.getBuildInfo(default_device) возвращает строку из 0 символов. Из документации OpenCL я знаю, что -44 возвращается, «если программа не является допустимым программным объектом», но после дополнительных поисков в Интернете я нашел это, поэтому моя проблема может заключаться в чем угодно, что не было отображено разработчиками.
Я обнаружил, что на самом деле не имеет значения, что я добавляю в код ядра. Это может быть что-то вроде этого:
std::string kernel_code = «недопустимое ядро»; и я получу тот же код сборки -44. На большинстве этих устройств нет проблем с компиляцией любого ядра после создания контекста OpenCL без свойств.
Я пробовал это на:
[*]Manjaro 1st с графическим процессором NVIDIA (GTX1070) — работает [*]Windows с графическим процессором AMD (r9 380x) — работает [*]MacO с графическим процессором AMD (radeon pro 450) — работает; и процессор Intel (i7-6700HQ) – работает [*]Manjaro 2nd с процессором Intel (i5-3320M) — ошибка -44 (невозможно создать контекст OpenCL без свойств) [*]Manjaro 3rd с графическим процессором Intel (UHD Graphics 620) – ошибка -44. [*]Manjaro 4-й с графическим процессором Intel (UHD Graphics 620) – ошибка -44.
РЕДАКТИРОВАТЬ:
Все устройства, кроме (Manjaro с процессором Intel), которые я тестировал, были правильно распознаны и перечислены командой clinfo. Это clinfo от Manjaro с процессором Intel:
Количество платформ 1 Название платформы Intel(R) OpenCL Поставщик платформы Intel(R) Corporation Версия платформы OpenCL 1.2 Профиль платформы FULL_PROFILE Расширения платформы cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_length_images cl_khr_3d_image_writes cl_intel_exec_by_ local_thread cl_khr_spir cl_khr_fp64 Суффикс функции расширения платформы INTEL Название платформы Intel(R) OpenCL Количество устройств 1 Имя устройства Процессор Intel(R) Core(TM) i5-3320M @ 2,60 ГГц Поставщик устройства Intel(R) Corporation Идентификатор поставщика устройства 0x8086 Версия устройства OpenCL 1.2 (сборка 475) Версия драйвера 1.2.0.475 Устройство OpenCL C Версия OpenCL C 1.2 Тип устройства ЦП Профиль устройства FULL_PROFILE Доступное устройство Да Доступен компилятор Да Линкер доступен Да Максимальное количество вычислительных блоков 4 Максимальная тактовая частота 2600 МГц Раздел устройства (ядро) Максимальное количество субустройств 4 Поддерживаемые типы разделов по количеству, а также по именам (Intel) Поддерживаемые родственные домены (нет данных) Макс. размеры рабочего элемента 3 Максимальный размер рабочего элемента: 8192x8192x8192. Максимальный размер рабочей группы 8192 zsh: ошибка сегментации (сброс ядра) clinfo КОНЕЦ РЕДАКТИРОВАНИЯ
Это наиболее упрощенный код с правильной инициализацией, который воспроизведет эту ошибку:
#define CL_HPP_TARGET_OPENCL_VERSION 200 #include #include #include #include #include #include GLFWwindow* инициализироватьGLFW(ширина uint, высота uint); символ инициализацииGLEW(); cl::Device getDefaultClDevice(); cl::Program compileTestKernel(cl::Context context, cl::Device default_device); интервал основной(){ int ширина = 1024, высота = 1024; Окно GLFWwindow* = инициализироватьGLFW(ширина, высота); если (окно == nullptr){ возврат 1; } если (инициализироватьGLEW()){ возврат 1; } cl::Device default_device = getDefaultClDevice(); если (!default_device()){ возврат 1; } платформа cl_platform_id; clGetPlatformIDs(1, &платформа, NULL); cl_context_properties свойства[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), //если я прокомментирую какое-либо из свойств выше, я получу ошибку сегментации при попытке доступа к памяти OpenGL на NVIDIA; //если я прокомментирую оба из них, я получу ошибку сегментации при создании контекста Intel; //если я прокомментирую один или ничего, я получу -44 от program.build(); //только на процессорах Intel, мне это нужно для создания контекста; CL_CONTEXT_PLATFORM, (cl_context_properties) платформа, // это не повлияло на результаты моих тестов, но все используют это в примерах, поэтому я думаю, что это в некотором роде важно; 0 }; cl::Контекст контекста (default_device, свойства); cl::Program program = compileTestKernel(context, default_device); cl::CommandQueue очередь (контекст, default_device); cl::Kernel test(программа, "тест"); очередь.enqueueNDRangeKernel(test, cl::NullRange, cl::NullRange, cl::NullRange); очередь.финиш(); ошибка int = glGetError(); если (ошибка!= GL_NO_ERROR) { std::fprintf(stderr, «Ошибка OpenGL: %d\n», error); } glfwDestroyWindow (окно); вернуть 0; } void glfwErrorCallback(int error, const char* описание){ std::fprintf(stderr, "Ошибка: %s\n", описание); } GLFWwindow* инициализироватьGLFW(ширина uint, высота uint){ если (!glfwInit()){ std::fprintf(stderr, «Не удалось инициализировать GLFW!\n»); вернуть нульптр; } glfwSetErrorCallback (glfwErrorCallback); Окно GLFWwindow* = glfwCreateWindow(ширина, высота, "тест", NULL, NULL); если (!окно){ std::fprintf(stderr, «Не удалось создать окно GLFW!\n»); glfwTerminate(); вернуть нульптр; } glfwMakeContextCurrent (окно); glViewport (0,0, ширина, высота); glfwSwapInterval (1); окно возврата; } символ инициализацииGLEW(){ glewExperimental = GL_TRUE; если (glewInit() != GLEW_OK) { std::fprintf(stderr, «Не удалось инициализировать GLEW!\n»); glfwTerminate(); вернуть -1; } Ошибка GLenum = glGetError(); если (ошибка!= GL_NO_ERROR) { std::fprintf(stderr, «Ошибка OpenGL: %d\n», error); } const GLubyte* glVersion = glGetString(GL_VERSION); const GLubyte* glVendor = glGetString(GL_VENDOR); const GLubyte* glRenderer = glGetString(GL_RENDERER); std::printf("Версия GL:\t%s\n", glVersion); std::printf("Поставщик GL:\t%s\n", glVendor); std::printf("GL-рендерер:\t%s\n\n", glRenderer); вернуть 0; } cl::Device getDefaultClDevice(){ std::vector all_platforms; cl::Platform::get(&all_platforms); если (all_platforms.empty()){ std::fprintf(stderr, "Платформы не найдены. Проверьте установку OpenCL!\n"); вернуть cl::Device(); } интервал выбора = 0; cl::Platform default_platform = all_platforms[0]; std::printf("Использование платформы:\t%s\n", default_platform.getInfo().c_str()); std::vector all_devices; default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices); если (all_devices.size() == 0){ std::fprintf(stderr, "Устройства не найдены. Проверьте установку OpenCL!\n"); вернуть cl::Device(); } cl::Device default_device = all_devices[0]; std::printf("Использование устройства:\t%s\n", default_device.getInfo().c_str()); вернуть default_device; } cl::Program compileTestKernel(cl::Context context, cl::Device default_device){ cl::Program::Источники источников; std::string kernel_code = " void kernel create_gradient(){}"; source.push_back({kernel_code.c_str(), kernel_code.length()}); cl::Программа программа(контекст, исходники); int buildCode = program.build(); ошибка int = glGetError(); если (ошибка!= GL_NO_ERROR) { std::fprintf(stderr, «Ошибка OpenGL: %d\n», error); } если (buildCode != CL_SUCCESS) { std::fprintf(stderr, "Ошибка сборки (%d): %s\n", buildCode, program.getBuildInfo(default_device).c_str()); выход (1); } программа возврата; } Это сообщения, которые я получил со своих устройств:
Версия GL: 4.6.0 NVIDIA 535.113.01 Поставщик GL: корпорация NVIDIA Рендеринг GL: NVIDIA GeForce GTX 1070/PCIe/SSE2 Используемая платформа: NVIDIA CUDA. Используемое устройство: NVIDIA GeForce GTX 1070. и
Версия GL: 3.0 Mesa 21.3.9 Янтарный Поставщик GL: Центр технологий Intel с открытым исходным кодом Рендерер GL: Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2) Использование платформы: Intel(R) OpenCL. Используемое устройство: процессор Intel(R) Core(TM) i5-3320M @ 2,60 ГГц. Ошибка построения (-44): Я новичок в OpenCL или OpenGL, поэтому, возможно, мою проблему сможет легко объяснить кто-то более опытный. Если у вас есть какие-либо идеи о том, в чем может быть проблема, я был бы признателен, если бы поделился ею со мной. Также сообщите мне, могу ли я предоставить дополнительную полезную информацию, поскольку я тестировал это на многих устройствах. Я не хочу заполнять эту страницу потоком ненужного текста, а также мне придется просить друзей сделать это за меня (мои только Manjaro с NVIDIA и Manjaro с процессором Intel).
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение