OpenCL.clSetKernelArg returns -51

1

I tried to make parallel bfs in openCL but I didn't have enough experience with c++. So this is probably memory error, but I really don't know how to fix it. I also can't find what does error value -51 means. As a result I got "Unhandled exception at 0x00007FFCFB06A549 (amdocl64.dll) in my project.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF" in next line.

main

    Graph G(AdjacencyList, Directed);
    int startVertex;
    vector<int> distance;
    vector<bool> visited;
    distance = vector<int>(G.numVertices);
    visited = vector<bool>(G.numVertices);
    bool done = false;
    const bool true_value = true;

    int level = 0;

    // Allocation on device
    const int size = G.numVertices * sizeof(int);
    const int adjacencySize = G.adjacencyList.size() * sizeof(int);


    //OpenCL
    cl_int status;
    cl_int ret;

    cl_platform_id platform_id;
    clGetPlatformIDs(1, &platform_id, NULL);

    cl_device_id device_id;
    ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);

    cl_context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &status);

    cl_command_queue command_queue = clCreateCommandQueueWithProperties(context, device_id, NULL, &status);
    cl_mem d_adjacencyList = clCreateBuffer(context, CL_MEM_READ_WRITE, adjacencySize, NULL, &status);
    cl_mem d_edgesOffset = clCreateBuffer(context, CL_MEM_READ_WRITE, size, NULL, &status);
    cl_mem d_edgesSize = clCreateBuffer(context, CL_MEM_READ_WRITE, size, NULL, &status);
    cl_mem d_distance = clCreateBuffer(context, CL_MEM_READ_WRITE, size, NULL, &status);
    cl_mem d_done = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(bool), NULL, &status);
    status = clEnqueueWriteBuffer(command_queue, d_adjacencyList, CL_TRUE, 0, adjacencySize, &G.adjacencyList[0], 0, NULL, NULL);
    status = clEnqueueWriteBuffer(command_queue, d_edgesOffset, CL_TRUE, 0, size, &G.edgesOffset[0], 0, NULL, NULL);
    status = clEnqueueWriteBuffer(command_queue, d_edgesSize, CL_TRUE, 0, size, &G.edgesSize[0], 0, NULL, NULL);
    
    distance = vector<int>(G.numVertices, INT_MAX);
    distance[start] = 0;
    status = clEnqueueWriteBuffer(command_queue, d_distance, CL_TRUE, 0, size, distance.data(), 0, NULL, NULL);
    char* source_str = NULL;
    size_t source_size;
    FILE* fp;


    fp = fopen("bfs.cl", "r");
    if (!fp)
    {
        cout << "Failed to load Kernel\n";
        exit(1);
    }
    source_str = (char*)malloc(MAX_SOURCE_SIZE);
    source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
    cl_program program = clCreateProgramWithSource(context, 1, (const char**)&source_str, (const size_t*)&source_size, &status);
    status = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

    cl_kernel kernel = clCreateKernel(program, "bfs", &status);
    
    status = clSetKernelArg(kernel, 0, sizeof(int), (void*)&G.numVertices);
    status = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void*)&d_adjacencyList);
    status = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void*)&d_edgesOffset);
    status = clSetKernelArg(kernel, 3, sizeof(cl_mem), (void*)&d_edgesOffset);
    status = clSetKernelArg(kernel, 4, sizeof(cl_mem), (void*)&d_edgesSize);
    status = clSetKernelArg(kernel, 5, sizeof(cl_mem), (void*)&d_distance); //here retirns -51
    status = clSetKernelArg(kernel, 6, sizeof(cl_mem), (void*)&level); 
    status = clSetKernelArg(kernel, 7, sizeof(cl_mem), (void*)&d_done);

kernel

__kernel void bfs(int n, __global int *adjacencyList,__global int *edgesOffset,__global int *edgesSize,__global int *distance, int level,__global bool *done) {
    int tid = get_global_id(0); 
    if (tid < n) {
        if (distance[tid] == level) {
            for (int i = edgesOffset[tid]; i < edgesOffset[tid] + edgesSize[tid]; ++i) {
                int v = adjacencyList[i];
                if (distance[v] == INT_MAX) {
                    *done = false;
                    distance[v] = level + 1;
                }
            }
        }
    }
}
c++
opencl
asked on Stack Overflow Apr 3, 2021 by Parrison

1 Answer

1

Hi @Parrison welcome to StackOverflow!

All the OpenCL error codes are defined in cl.h. In the latest (version 3) cl.h you will find the error codes defined between lines 194 and 270, where on line 241 you will find:

#define CL_INVALID_ARG_SIZE -51

So the OpenCL ICD reckons that you have passed the wrong variable size for distance.

However, I can see many other errors before this one. For example, you need to set the size of the OpenCL buffers based on the sizes of OpenCL variable not native variables, e.g.:

  • cl_int instead of int
  • cl_float instead of float
  • and especially cl_bool instead of bool.

There is no guarantee that an OpenCL cl_int is the same size a host int and an OpenCL cl_bool is defined as an unsigned int which is highly unlikely to be the same size as a bool!

Ensure that all the parameters to your OpenCL kernel are defined correctly and that you are creating the correct buffers and variables for them in the main program.

answered on Stack Overflow Apr 3, 2021 by kenba

User contributions licensed under CC BY-SA 3.0