martinkunev
martinkunev

Reputation: 1405

OpenCL clFinish never returns

I'm looking to start learning OpenCL. I was looking for a "hello world" example in order to first verify that everything behaves as expected on my system. After trying multiple such examples, I'm unable to find (or to make) one that works.

The code below is blocking on the call to clFinish and appears to never return.

#include <math.h>
#ifdef __APPLE__
    #include <OpenCL/opencl.h>
#else
    #include <CL/cl.h>
#endif

const char *KernelSource = "\n" \
"__kernel void hello(             \n" \
"   __global char* a,         \n" \
"   __global char* b,         \n" \
"   __global char* c,         \n" \
"   const unsigned int count)  \n" \
"{                           \n" \
"   int i = get_global_id(0);  \n" \
"   if(i < count)             \n" \
"      c[i] = a[i] + b[i];   \n" \
"}                           \n" \
"\n";

#define DATA_SIZE (16)

int main(int argc, char** argv)
{
    int err;                         // error code returned from api calls
    cl_device_id device_id;          // compute device id 
    cl_context context;              // compute context
    cl_command_queue commands;       // compute command queue
    cl_program program;              // compute program
    cl_kernel kernel;                // compute kernel
    cl_mem input;                    // device memory used for the input array
    cl_mem input2;                   // device memory used for the input array
    cl_mem output;                   // device memory used for the output array
    size_t global;                   // global domain size for our calculation
    size_t local;                    // local domain size for our calculation
    
    int i;
    unsigned int count = DATA_SIZE;

    // Input data
    char a[DATA_SIZE] = "Hello \0\0\0\0\0\0";
    char b[DATA_SIZE] = {15, 10, 6, 0, -11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    // Output data
    char c[DATA_SIZE];
    
    cl_platform_id platform;
    unsigned int no_plat;
    err =  clGetPlatformIDs(1,&platform,&no_plat);

    // Where to run
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
    if (err != CL_SUCCESS) return -1;
    context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
    if (!context) return -1;
    commands = clCreateCommandQueue(context, device_id, 0, &err);
    if (!commands) return -1;
    
    // What to run
    program = clCreateProgramWithSource(context, 1, (const char **) & KernelSource, NULL, &err);
    if (!program) return -1;

    err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
   if (err != CL_SUCCESS) return -1;
    kernel = clCreateKernel(program, "hello", &err);
    if (!kernel || err != CL_SUCCESS) return -1;
    
    // Create space for data and copy a and b to device (note that we could also use clEnqueueWriteBuffer to upload)
    input = clCreateBuffer(context,  CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,  sizeof(char) * DATA_SIZE, a, NULL);
    input2 = clCreateBuffer(context,  CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,  sizeof(char) * DATA_SIZE, b, NULL);
    output = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(char) * DATA_SIZE, NULL, NULL);
    if (!input || !output) return -1;
    
    // Send data
    err  = clSetKernelArg(kernel, 0, sizeof(cl_mem), &input);
    err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &input2);
    err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &output);
    err |= clSetKernelArg(kernel, 3, sizeof(unsigned int), &count);
    if (err != CL_SUCCESS) return -1;
    
    local = DATA_SIZE;

    // Run kernel!
    global = DATA_SIZE; // count;
    err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, &global, &local, 0, NULL, NULL);
    if (err != CL_SUCCESS) return -1;

    clFinish(commands);

    // Read result
    err = clEnqueueReadBuffer( commands, output, CL_TRUE, 0, sizeof(char) * count, c, 0, NULL, NULL );  
    if (err != CL_SUCCESS) return -1;

    printf("%s\n", c);

    // Clean up
    clReleaseMemObject(input);
    clReleaseMemObject(output);
    clReleaseProgram(program);
    clReleaseKernel(kernel);
    clReleaseCommandQueue(commands);
    clReleaseContext(context);
    sleep(1); // Leopard pty bug workaround.
    return 0;
}

I have a Ryzen 5 3400G and I'm using Linux.

gcc (Debian 10.2.1-6) 10.2.1 20210110

During compilation I see a couple of warnings (I couldn't find an example that gives no warnings).

                 from world.c:11:
/usr/include/CL/cl_version.h:22:9: note: ‘#pragma message: cl_version.h: CL_TARGET_OPENCL_VERSION is not defined. Defaulting to 300 (OpenCL 3.0)’
   22 | #pragma message("cl_version.h: CL_TARGET_OPENCL_VERSION is not defined. Defaulting to 300 (OpenCL 3.0)")
      |         ^~~~~~~
world.c: In function ‘main’:
world.c:61:2: warning: ‘clCreateCommandQueue’ is deprecated [-Wdeprecated-declarations]
   61 |  commands = clCreateCommandQueue(context, device_id, 0, &err);
      |  ^~~~~~~~
In file included from world.c:11:
/usr/include/CL/cl.h:1906:1: note: declared here
 1906 | clCreateCommandQueue(cl_context                     context,
      | ^~~~~~~~~~~~~~~~~~~~

Am I doing something wrong or is the example wrong? In the latter case, where can I find a simple opencl program that works?


EDIT

I happened to restart the computer and clinfo works after the restart:

Number of platforms                               1
  Platform Name                                   Clover
  Platform Vendor                                 Mesa
  Platform Version                                OpenCL 1.1 Mesa 20.3.5
  Platform Profile                                FULL_PROFILE
  Platform Extensions                             cl_khr_icd
  Platform Extensions function suffix             MESA

  Platform Name                                   Clover
Number of devices                                 1
  Device Name                                     AMD Radeon(TM) Vega 11 Graphics (RAVEN, DRM 3.40.0, 4.19.0-12-amd64, LLVM 11.0.1)
  Device Vendor                                   AMD
  Device Vendor ID                                0x1002
  Device Version                                  OpenCL 1.1 Mesa 20.3.5
  Driver Version                                  20.3.5
  Device OpenCL C Version                         OpenCL C 1.1 
  Device Type                                     GPU
  Device Profile                                  FULL_PROFILE
  Device Available                                Yes
  Compiler Available                              Yes
  Max compute units                               11
  Max clock frequency                             1400MHz
  Max work item dimensions                        3
  Max work item sizes                             256x256x256
  Max work group size                             256
  Preferred work group size multiple (kernel)     64
  Preferred / native vector sizes                 
    char                                                16 / 16      
    short                                                8 / 8       
    int                                                  4 / 4       
    long                                                 2 / 2       
    half                                                 0 / 0        (n/a)
    float                                                4 / 4       
    double                                               2 / 2        (cl_khr_fp64)
  Half-precision Floating-point support           (n/a)
  Single-precision Floating-point support         (core)
    Denormals                                     No
    Infinity and NANs                             Yes
    Round to nearest                              Yes
    Round to zero                                 No
    Round to infinity                             No
    IEEE754-2008 fused multiply-add               No
    Support is emulated in software               No
    Correctly-rounded divide and sqrt operations  No
  Double-precision Floating-point support         (cl_khr_fp64)
    Denormals                                     Yes
    Infinity and NANs                             Yes
    Round to nearest                              Yes
    Round to zero                                 Yes
    Round to infinity                             Yes
    IEEE754-2008 fused multiply-add               Yes
    Support is emulated in software               No
  Address bits                                    64, Little-Endian
  Global memory size                              31611129856 (29.44GiB)
  Error Correction support                        No
  Max memory allocation                           22127790899 (20.61GiB)
  Unified memory for Host and Device              No
  Minimum alignment for any data type             128 bytes
  Alignment of base address                       32768 bits (4096 bytes)
  Global Memory cache type                        None
  Image support                                   No
  Local memory type                               Local
  Local memory size                               32768 (32KiB)
  Max number of constant args                     16
  Max constant buffer size                        67108864 (64MiB)
  Max size of kernel argument                     1024
  Queue properties                                
    Out-of-order execution                        No
    Profiling                                     Yes
  Profiling timer resolution                      0ns
  Execution capabilities                          
    Run OpenCL kernels                            Yes
    Run native kernels                            No
  Device Extensions                               cl_khr_byte_addressable_store 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_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_fp64

NULL platform behavior
  clGetPlatformInfo(NULL, CL_PLATFORM_NAME, ...)  No platform
  clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, ...)   No platform
  clCreateContext(NULL, ...) [default]            No platform
  clCreateContext(NULL, ...) [other]              Success [MESA]
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_DEFAULT)  Success (1)
    Platform Name                                 Clover
    Device Name                                   AMD Radeon(TM) Vega 11 Graphics (RAVEN, DRM 3.40.0, 4.19.0-12-amd64, LLVM 11.0.1)
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU)  No devices found in platform
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU)  Success (1)
    Platform Name                                 Clover
    Device Name                                   AMD Radeon(TM) Vega 11 Graphics (RAVEN, DRM 3.40.0, 4.19.0-12-amd64, LLVM 11.0.1)
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_ACCELERATOR)  No devices found in platform
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_CUSTOM)  No devices found in platform
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL)  Success (1)
    Platform Name                                 Clover
    Device Name                                   AMD Radeon(TM) Vega 11 Graphics (RAVEN, DRM 3.40.0, 4.19.0-12-amd64, LLVM 11.0.1)

Upvotes: 0

Views: 121

Answers (1)

ProjectPhysX
ProjectPhysX

Reputation: 5736

I checked the sample code, it executes properly. So there must be an issue with your OpenCL Runtime installation. Did a reboot fix it already? Are you on Windows or Linux?

Upvotes: 1

Related Questions