OpenCL won't run while debugging



  • Hi,
    i try to use the OpenCV library and got a strange exception if i run the program in debug mode and want to debug it.

    #include <QCoreApplication>
    #include <CL/cl.h>
    
    #define MAX_SOURCE_SIZE (0x100000)
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        // Create the two input vectors
        int i;
        const int LIST_SIZE = 1024;
        int *A = (int*)malloc(sizeof(int)*LIST_SIZE);
        int *B = (int*)malloc(sizeof(int)*LIST_SIZE);
        for(i = 0; i < LIST_SIZE; i++) {
            A[i] = i;
            B[i] = LIST_SIZE - i;
        }
    
        // Load the kernel source code into the array source_str
        FILE *fp;
        char *source_str;
        size_t source_size;
    
        fp = fopen("vector_add_kernel.cl", "r");
        if (!fp) {
            fprintf(stderr, "Failed to load kernel.\n");
            exit(1);
        }
        source_str = (char*)malloc(MAX_SOURCE_SIZE);
        source_size = fread( source_str, 1, MAX_SOURCE_SIZE, fp);
        fclose( fp );
    
        // Get platform and device information
        cl_platform_id platform_id = NULL;
        cl_device_id device_id = NULL;
        cl_uint ret_num_devices;
        cl_uint ret_num_platforms;
        cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
        ret = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_ALL, 1,
                &device_id, &ret_num_devices);
    
        // Create an OpenCL context
        cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret);
    
        // Create a command queue
        cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
    
        // Create memory buffers on the device for each vector
        cl_mem a_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY,
                LIST_SIZE * sizeof(int), NULL, &ret);
        cl_mem b_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY,
                LIST_SIZE * sizeof(int), NULL, &ret);
        cl_mem c_mem_obj = clCreateBuffer(context, CL_MEM_WRITE_ONLY,
                LIST_SIZE * sizeof(int), NULL, &ret);
    
        // Copy the lists A and B to their respective memory buffers
        ret = clEnqueueWriteBuffer(command_queue, a_mem_obj, CL_TRUE, 0,
                LIST_SIZE * sizeof(int), A, 0, NULL, NULL);
        ret = clEnqueueWriteBuffer(command_queue, b_mem_obj, CL_TRUE, 0,
                LIST_SIZE * sizeof(int), B, 0, NULL, NULL);
    
        // Create a program from the kernel source
        cl_program program = clCreateProgramWithSource(context, 1,
                (const char **)&source_str, (const size_t *)&source_size, &ret);
    
        // Build the program
        ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
    
        // Create the OpenCL kernel
        cl_kernel kernel = clCreateKernel(program, "vector_add", &ret);
    
        // Set the arguments of the kernel
        ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&a_mem_obj);
        ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&b_mem_obj);
        ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&c_mem_obj);
    
        // Execute the OpenCL kernel on the list
        size_t global_item_size = LIST_SIZE; // Process the entire lists
        size_t local_item_size = 64; // Process in groups of 64
        ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
                &global_item_size, &local_item_size, 0, NULL, NULL);
    
        // Read the memory buffer C on the device to the local variable C
        int *C = (int*)malloc(sizeof(int)*LIST_SIZE);
        ret = clEnqueueReadBuffer(command_queue, c_mem_obj, CL_TRUE, 0,
                LIST_SIZE * sizeof(int), C, 0, NULL, NULL);
    
        // Display the result to the screen
        for(i = 0; i < LIST_SIZE; i++)
            printf("%d + %d = %d\n", A[i], B[i], C[i]);
    
        // Clean up
        ret = clFlush(command_queue);
        ret = clFinish(command_queue);
        ret = clReleaseKernel(kernel);
        ret = clReleaseProgram(program);
        ret = clReleaseMemObject(a_mem_obj);
        ret = clReleaseMemObject(b_mem_obj);
        ret = clReleaseMemObject(c_mem_obj);
        ret = clReleaseCommandQueue(command_queue);
        ret = clReleaseContext(context);
        free(A);
        free(B);
        free(C);
    return 0;
    }
    

    The code runs fine in release mode and also in debug mode if i dont use a debugger (just run it with CTRL+R in Qt Creator).

    But when I want to debug it, it throws an exception at line 39:

    cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
    

    0_1556796440931_exc.PNG

    Win 10 x64, Qt 5.12.3, Qt Creator 4.9.0


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but since you are not using Qt anywhere, does it also happen if you remove your QCoreApplication.


  • Qt Champions 2017

    My C is rather rusty, but I think you're using the function incorrectly.

    static constexpr size_t maxPlatformsNumber = 30;
    
    cl_uint ret_num_platforms;
    cl_platform_id platform_id[maxPlatformsNumber];
    
    cl_int ret = clGetPlatformIDs(maxPlatformsNumber, platform_id, &ret_num_platforms);
    

    I assume there's some initialization that must be done to the platform_id array beforehand, though.

    PS.
    Something like:

    cl_platform_id platform_id[maxPlatformsNumber];
    for (size_t i = 0; i < maxPlatformsNumber; i++)
        platform_id[i] = ::malloc(sizeof(_cl_platform_id));
    

    may be necessary.



  • @SGaist x
    @kshegunov
    I'll try it!

    I have no experience with pure C. I've just copied from this tutorial: https://www.eriksmistad.no/getting-started-with-opencl-and-gpu-computing/

    If it's a problem with the code, why is it working in release mode?


  • Qt Champions 2018

    @beecksche unfortunately:

    If it's a problem with the code, why is it working in release mode?

    'it is working' does not necessarily mean it is correct. at least you have the problem in debug mode, so you should be able to investigate.



  • Both suggestions don't work.

    I don't think the code is incorrect, i found many other examples uses the same part of code. The docs also says, that the function will ignore the pointer if it's NULL.

    Unfortunetaly i'm not able to update my Intel Graphics Driver to the newest release. Maybe that's the reason.

    Nevertheless, I tried a lot of OpenCL kernels, which will work correctly in Release mode.

    I also can skip the exception in Debug mode by continue the debugging twice, and the functions return the correct result.

    In Visual Studio the same exception is caused in the ntdll.exe. But this is also not helpfull for me to find the problem.

    Keep searching.


Log in to reply