OpenCL kernel -44 compilation error while using OpenGL context on Intel under Manjaro

78 Views Asked by At

Recently I've been trying to use OpenCL-OpenGL interop. After some trial and error I've found that I need to initialize OpenCL context providing it correct properties. I got it working under Manjaro with NVIDIA GPU, NVIDIA driver and CUDA installed but I got some problems on Intel devices.

(Problem is only under Manjaro with Intel and I am not able to test it under Windows on same devices because there are not mine)

The problem is: to use OpenCL-OpenGL interop I need to create OpenCL context using properties:

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
};

but if I provide this to context cl::Context context(default_device, properties); then after compilation of any kernel int buildCode = program.build(); 'buildCode' is equal to -44 and program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device) returns 0 character string. From OpenCL documentation I know that -44 is returned "if program is a not a valid program object" but after searching more on the internet I have found this so my problem could be anything that was unmapped by developers.

I have found that it really des not matter what I throw into the kernel code. It could be something like this:

std::string kernel_code =
        "not a valid kernel";

and I will get the same -44 build code. On most of those devices there is no problem compiling any kernel after creating OpenCL context without properties.

I've tried It on:

  1. Manjaro 1st with NVIDIA GPU (GTX1070)- working
  2. Windows with AMD GPU (r9 380x) - working
  3. MacOs with AMD GPU (radeon pro 450) - working; and Intel CPU (i7-6700HQ) - working
  4. Manjaro 2nd with Intel CPU (i5-3320M)- error -44 (cannot create OpenCL context without properties)
  5. Manjaro 3rd with Intel GPU (UHD Graphics 620) - error -44
  6. Manjaro 4th with Intel GPU (UHD Graphics 620) - error -44

EDIT:

Every single device but (Manjaro with Intel CPU) I have tested was properly recognized and listed by clinfo command. This is clinfo from Manjaro with Intel CPU:

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

END OF EDIT

This is most simplified code with proper initialization that will reproduce this error:

#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;
}

Those are messages That I got from my devices:

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

and

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):

I am new to either OpenCL or OpenGL so probably my problem could be easily explained by someone with more experience. If you have any idea of what the problem could be I would appreciate sharing it with me. Please also tell me if there is any additional useful info that I can provide because there are many devices I've been testing this on. I don't wanna flood this page with irrelevant stream of text and also I would have to ask my friends to do this for me (only Manjaro with NVIDIA and Manjaro with Intel CPU are mine).

0

There are 0 best solutions below