提问人:Stimmer02 提问时间:10/21/2023 最后编辑:Stimmer02 更新时间:10/21/2023 访问量:53
在 Manjaro 下在 Intel 上使用 OpenGL 上下文时出现 OpenCL 内核 -44 编译错误
OpenCL kernel -44 compilation error while using OpenGL context on Intel under Manjaro
问:
最近我一直在尝试使用 OpenCL-OpenGL 互操作。经过一些反复试验,我发现我需要初始化 OpenCL 上下文,为其提供正确的属性。我在安装了 NVIDIA GPU、NVIDIA 驱动程序和 CUDA 的 Manjaro 下让它工作,但我在 Intel 设备上遇到了一些问题。
(问题仅在 Manjaro 和 Intel 下,我无法在 Windows 下在同一设备上测试它,因为没有我的)
问题是:要使用 OpenCL-OpenGL 互操作,我需要使用属性创建 OpenCL 上下文:
cl_context_properties properties[] = { //for Linux
CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
0
};
但是,如果我将其提供给上下文,那么在编译任何内核后,“buildCode”等于 -44 并返回 0 个字符串。
从 OpenCL 文档中,我知道“如果程序不是有效的程序对象”会返回 -44,但是在互联网上搜索了更多信息后,我发现了这一点,所以我的问题可能是开发人员未映射的任何内容。cl::Context context(default_device, properties);
int buildCode = program.build();
program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)
我发现我扔到内核代码中的内容真的无关紧要。它可能是这样的:
std::string kernel_code =
"not a valid kernel";
我会得到相同的 -44 构建代码。 在大多数这些设备上,在创建没有属性的 OpenCL 上下文后编译任何内核都没有问题。
我试过了:
- Manjaro 1st 与 NVIDIA GPU (GTX1070)- 工作
- 配备 AMD GPU (r9 380x) 的 Windows - 工作
- 配备 AMD GPU (radeon pro 450) 的 MacO - 工作;和英特尔 CPU (i7-6700HQ) - 工作
- 带有 Intel CPU 的 Manjaro 2nd (i5-3320M) - 错误 -44(无法创建没有属性的 OpenCL 上下文)
- 配备 Intel GPU (UHD Graphics 620) 的 Manjaro 3rd - 错误 -44
- Manjaro 4th with Intel GPU (UHD Graphics 620) - 错误 -44
编辑:
除了(带有 Intel CPU 的 Manjaro)之外,我测试过的每个设备都被正确识别并通过命令列出。
这是来自带有 Intel CPU 的 Manjaro:clinfo
clinfo
Number of platforms 1
Platform Name Intel(R) OpenCL
Platform Vendor Intel(R) Corporation
Platform Version OpenCL 1.2
Platform Profile FULL_PROFILE
Platform Extensions 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_depth_images cl_khr_3d_image_writes cl_intel_exec_by_local_thread cl_khr_spir cl_khr_fp64
Platform Extensions function suffix INTEL
Platform Name Intel(R) OpenCL
Number of devices 1
Device Name Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
Device Vendor Intel(R) Corporation
Device Vendor ID 0x8086
Device Version OpenCL 1.2 (Build 475)
Driver Version 1.2.0.475
Device OpenCL C Version OpenCL C 1.2
Device Type CPU
Device Profile FULL_PROFILE
Device Available Yes
Compiler Available Yes
Linker Available Yes
Max compute units 4
Max clock frequency 2600MHz
Device Partition (core)
Max number of sub-devices 4
Supported partition types by counts, equally, by names (Intel)
Supported affinity domains (n/a)
Max work item dimensions 3
Max work item sizes 8192x8192x8192
Max work group size 8192
zsh: segmentation fault (core dumped) clinfo
编辑结束
这是最简化的代码,具有正确的初始化,将重现此错误:
#define CL_HPP_TARGET_OPENCL_VERSION 200
#include <CL/opencl.hpp>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <GL/glx.h>
#include <vector>
#include <cstdio>
GLFWwindow* initializeGLFW(uint width, uint height);
char initializeGLEW();
cl::Device getDefaultClDevice();
cl::Program compileTestKernel(cl::Context context, cl::Device default_device);
int main(){
int width = 1024, height = 1024;
GLFWwindow* window = initializeGLFW(width, height);
if (window == nullptr){
return 1;
}
if (initializeGLEW()){
return 1;
}
cl::Device default_device = getDefaultClDevice();
if (!default_device()){
return 1;
}
cl_platform_id platform;
clGetPlatformIDs(1, &platform, NULL);
cl_context_properties properties[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
//if I comment any of properties above I get segmentatnion fault if trying to acces OpenGL memory on NVIDIA;
//if I comment both of those I get segmentatnion fault on Intel creating context;
//if I comment one or none I get -44 from program.build();
//only on Intel CPU I need this to create context;
CL_CONTEXT_PLATFORM, (cl_context_properties) platform,//this didn't influence resaults of my tests but everyone uses this in example so I guess it is important in some way;
0
};
cl::Context context(default_device, properties);
cl::Program program = compileTestKernel(context, default_device);
cl::CommandQueue queue(context, default_device);
cl::Kernel test(program, "test");
queue.enqueueNDRangeKernel(test, cl::NullRange, cl::NullRange, cl::NullRange);
queue.finish();
int error = glGetError();
if (error != GL_NO_ERROR) {
std::fprintf(stderr, "OpenGL error: %d\n", error);
}
glfwDestroyWindow(window);
return 0;
}
void glfwErrorCallback(int error, const char* description){
std::fprintf(stderr, "Error: %s\n", description);
}
GLFWwindow* initializeGLFW(uint width, uint height){
if (!glfwInit()){
std::fprintf(stderr, "Failed to initialize GLFW!\n");
return nullptr;
}
glfwSetErrorCallback(glfwErrorCallback);
GLFWwindow* window = glfwCreateWindow(width, height, "test", NULL, NULL);
if (!window){
std::fprintf(stderr, "Failed to create GLFW window!\n");
glfwTerminate();
return nullptr;
}
glfwMakeContextCurrent(window);
glViewport(0,0, width, height);
glfwSwapInterval(1);
return window;
}
char initializeGLEW(){
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::fprintf(stderr, "Failed to initialize GLEW!\n");
glfwTerminate();
return -1;
}
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
std::fprintf(stderr, "OpenGL error: %d\n", error);
}
const GLubyte* glVersion = glGetString(GL_VERSION);
const GLubyte* glVendor = glGetString(GL_VENDOR);
const GLubyte* glRenderer = glGetString(GL_RENDERER);
std::printf("GL version:\t%s\n", glVersion);
std::printf("GL vendor:\t%s\n", glVendor);
std::printf("GL renderer:\t%s\n\n", glRenderer);
return 0;
}
cl::Device getDefaultClDevice(){
std::vector<cl::Platform> all_platforms;
cl::Platform::get(&all_platforms);
if (all_platforms.empty()){
std::fprintf(stderr, "No platforms found. Check OpenCL installation!\n");
return cl::Device();
}
int selection=0;
cl::Platform default_platform = all_platforms[0];
std::printf("Using platform:\t%s\n", default_platform.getInfo<CL_PLATFORM_NAME>().c_str());
std::vector<cl::Device> all_devices;
default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
if (all_devices.size() == 0){
std::fprintf(stderr, "No devices found. Check OpenCL installation!\n");
return cl::Device();
}
cl::Device default_device = all_devices[0];
std::printf("Using device:\t%s\n", default_device.getInfo<CL_DEVICE_NAME>().c_str());
return default_device;
}
cl::Program compileTestKernel(cl::Context context, cl::Device default_device){
cl::Program::Sources sources;
std::string kernel_code =
" void kernel create_gradient(){}";
sources.push_back({kernel_code.c_str(), kernel_code.length()});
cl::Program program(context, sources);
int buildCode = program.build();
int error = glGetError();
if (error != GL_NO_ERROR) {
std::fprintf(stderr, "OpenGL error: %d\n", error);
}
if (buildCode != CL_SUCCESS) {
std::fprintf(stderr, "Error building (%d): %s\n", buildCode, program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device).c_str());
exit(1);
}
return program;
}
这些是我从我的设备收到的消息:
GL version: 4.6.0 NVIDIA 535.113.01
GL vendor: NVIDIA Corporation
GL renderer: NVIDIA GeForce GTX 1070/PCIe/SSE2
Using platform: NVIDIA CUDA
Using device: NVIDIA GeForce GTX 1070
和
GL version: 3.0 Mesa 21.3.9 Amber
GL vendor: Intel Open Source Technology Center
GL renderer: Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2)
Using platform: Intel(R) OpenCL
Using device: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
Error building (-44):
我是 OpenCL 或 OpenGL 的新手,所以可能我的问题可以很容易地由有更多经验的人来解释。如果您知道问题可能是什么,我将不胜感激地与我分享。 还请告诉我是否可以提供任何其他有用的信息,因为我一直在许多设备上进行测试。我不想用不相关的文本流淹没这个页面,而且我还必须让我的朋友为我做这件事(只有带有 NVIDIA 的 Manjaro 和带有 Intel CPU 的 Manjaro 是我的)。
答: 暂无答案
评论