Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCL 1.2 C++ Wrapper - undefined reference to clReleaseDevice

Tags:

nvidia

opencl

I am trying to use the OpenCL C++ wrapper API for the following program :

#define __CL_ENABLE_EXCEPTIONS


#include <CL/cl.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>

 const char helloStr []  = "__kernel void "
                          "hello(void) "
                          "{ "
                          "  "
                          "} ";

 int
 main(void)
 {
    cl_int err = CL_SUCCESS;
    try {

      std::vector<cl::Platform> platforms;
      cl::Platform::get(&platforms);
      if (platforms.size() == 0) {
          std::cout << "Platform size 0\n";
          return -1;
      }

      cl_context_properties properties[] =
         { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};
      cl::Context context(CL_DEVICE_TYPE_CPU, properties);

      std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();

      cl::Program::Sources source(1,
          std::make_pair(helloStr,strlen(helloStr)));
      cl::Program program_ = cl::Program(context, source);
      program_.build(devices);

      cl::Kernel kernel(program_, "hello", &err);

      cl::Event event;
      cl::CommandQueue queue(context, devices[0], 0, &err);
      queue.enqueueNDRangeKernel(
          kernel,
          cl::NullRange,
          cl::NDRange(4,4),
          cl::NullRange,
          NULL,
          &event);

      event.wait();
    }
    catch (cl::Error err) {
       std::cerr
          << "ERROR: "
          << err.what()
          << "("
          << err.err()
          << ")"
          << std::endl;
    }

   return EXIT_SUCCESS;
 }

I use the same kernel file from that blog post, anyways that is not the issue since I can't get past compilation.

I'm compiling the program with the following command :

g++ example.cpp -o example -l OpenCL

and I get the following error message :

/tmp/ccbUf7dB.o: In function `cl::detail::ReferenceHandler<_cl_device_id*>::release(_cl_device_id*)':
example.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP13_cl_device_idE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP13_cl_device_idE7releaseES3_]+0x14): undefined reference to `clReleaseDevice'
collect2: error: ld returned 1 exit status

I've read stuff about clReleaseDevice not working for legacy devices (see for example this question), but my graphics card is pretty recent (NVidia GTX 660 Ti, supports OpenCL 1.2). Where can I go from there?

I am running this on Ubuntu 13.04 x64 with nvidia-opencl-dev and opencl-headers installed from ubuntu repositories.

like image 713
levesque Avatar asked Apr 06 '13 20:04

levesque


1 Answers

The root cause

The problem is that the OpenCL library that you are linking against does not support OpenCL 1.2. Speaking generically, until an OpenCL implementation supporting the version you want to use becomes available for a specific platform, you will have this problem when linking against the OpenCL shared library provided with it. There are two solutions:

  • Download the version of cl.hpp from Khronos that matches the OpenCL version provided by your chosen hardware and continue using the library provided by your device's manufacturer.
  • Link against an OpenCL shared library that implements the latest OpenCL standard, but write multiple code paths - one for each OpenCL version, ensuring that each code path only uses OpenCL functions that are supported by that version. This route is harder and I have no idea how you can do it with the C++ wrapper. If you try to call an OpenCL 1.2 function on a platform that doesn't support OpenCL 1.2 you will get a segfault, that's why different code paths are needed.

Nvidia specific

Nvidia has been very slow in delivering OpenCL 1.2 support. As a result, their OpenCL library did not provide the OpenCL 1.2 functions the linker was looking for, resulting in the errors.

At the end of May 2015 Nvidia released drivers that support OpenCL 1.2, see the comments by Z Boson below. Updating your drivers should resolve the linker error. GeForce GTX 6xx and later cards (except for rebrands of earlier generations) support OpenCL 1.2. You can check the conformant products list on the Khronos OpenCL site to make sure. The GTX 660 Ti is listed so you're in luck.

like image 95
chippies Avatar answered Nov 15 '22 08:11

chippies