OpenCL not finding platforms?
Solution 1
My sincerest thanks to @pasternak for helping me troubleshoot this problem. To solve it however I ended up needing to avoid essentially all ubuntu apt-get
calls for install and just use the cuda run file for the full installation. Here is what fixed the problem.
- Purge existing nvidia and cuda implementations (
sudo apt-get purge cuda* nvidia-*
) - Download cuda-6.5 toolkit from the CUDA toolkit archive
- Reboot computer
- Switch to ttyl (Ctrl-Alt-F1)
- Stop the X server (sudo stop lightdm)
- Run the cuda run file (
sh cuda_6.5.14_linux_64.run
) - Select 'yes' and accept all defaults
- Required reboot
- Switch to ttyl, stop X server and run the cuda run file again and select 'yes' and default for everything (including the driver again)
- Update
PATH
to include/usr/local/cuda-6.5/bin
andLD_LIBRARY_PATH
to include/usr/local/cuda-6.5/lib64
- Reboot again
- Compile main.c program (
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
) - Verify works with
./vectorAddition
C++ API
- Download
cl.hpp
file from Khronos here noting that it is version 1.1 - Place cl.hpp file in
/usr/local/cuda-6.5/include/CL
with other cl headers. - Compile main.cpp (
g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
) - Verify it works (
./vectorAddition_cpp
)
All output from both programs show the correct output for addition between vectors.
I personally find it interesting the Ubuntu's nvidia drivers don't seem to play well with the cuda toolkits. Possibly just for the older versions but still very unexpected.
Solution 2
It is hard to say without running the specific code on your machine but looking at the difference between the example C code you said was working and the cl.hpp might give us a clue. In particular, notice that the C example uses the following line to simply read a single platform ID:
cl_platform_id platform_id = NULL;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
Notice that is passes 1 as its first argument. This assumes that at least one OpenCL platform exists and requests that the first one found is placed in platform_id. Additionally, note that even though the return code is assigned to "ret" is it not used to actually check if an error is returned.
Now if we look at the implementation of the static method used to queue the set of platforms in cl.hpp, i.e. cl::Platform::get:
static cl_int get(
VECTOR_CLASS<Platform>* platforms)
{
cl_uint n = 0;
cl_int err = ::clGetPlatformIDs(0, NULL, &n);
if (err != CL_SUCCESS) {
return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
}
cl_platform_id* ids = (cl_platform_id*) alloca(
n * sizeof(cl_platform_id));
err = ::clGetPlatformIDs(n, ids, NULL);
if (err != CL_SUCCESS) {
return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
}
platforms->assign(&ids[0], &ids[n]);
return CL_SUCCESS;
}
we see that it first calls
::clGetPlatformIDs(0, NULL, &n);
notice that the first parameter is 0, which tells the OpenCL runtime to return the number of platforms in "n". If this is successful it then goes on to request the actual "n" platform IDs.
So the difference here is that the C version is not checking that there is at least one platform and simply assuming that one exists, while the cl.hpp variant is and as such maybe it is this call that is failing.
The most likely reason for all this is that the ICD is not correctly installed. You can see this thread for an example of how to fix this issue:
ERROR: clGetPlatformIDs -1001 when running OpenCL code (Linux)
I hope this helps.
cdeterman
Data scientist interested in bioinformatics, machine learning, and multivariate analysis. Primarily R and Python programmer but familiar with many languages.
Updated on June 22, 2022Comments
-
cdeterman almost 2 years
I am trying to utilize the C++ API for OpenCL. I have installed my NVIDIA drivers and I have tested that I can run the simple vector addition program provided here. I can compile this program with following gcc call and the program runs without problem.
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
However, I would very much prefer to use the C++ API as opposed the very verbose host files needed for C.
I downloaded the C++ bindings from Khronos from here and placed the
cl.hpp
file in the same location as my othercl.h
file. The code uses some C++11 so I can compile the code with:g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
but when I try to run the program I get the error:
clGetPlatformIDs(-1001)
I also tried the example provided here as well which gave a more helpful error message.
No platforms found. Check OpenCL installation!
The particular code which provides this error is this:
std::vector<cl::Platform> all_platforms; cl::Platform::get(&all_platforms); if(all_platforms.size()==0){ std::cout<<" No platforms found. Check OpenCL installation!\n"; exit(1); }
This seems so strange given that the C implementation runs without problem. Any insights would be sincerely appreciated.
EDIT
The C implementation actually isn't running correctly. Each addition is printed to equal zero. Checking the
ret_num_platforms
also returns 0. For some reason my setup is failing to find my GPU. What could I have missed? My install consists of the nvidia-340 driver and cuda-6.5 installed viaapt-get
and the.run
file respectively. -
cdeterman about 9 yearsThank you for your answer, however I already have a
nvidia.icd
present in/etc/OpenCL/vendors/nvidia.icd
. Curiously, there is no such file in/usr/share/nvidia-334/
, only anvidia-346.grub
file andnvidia-application-profiles
. -
pasternak about 9 yearsIn your example C code I would have a look at "ret" from: cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms); in a debugger and also check the value of "ret_num_platforms" if they are 0 (CL_SUCCESS) and 1, respectively, then take a look at similar values in the cl.hpp implementation of get.
-
cdeterman about 9 yearsI checked
ret_num_platforms
and it was 0 in my C code. I just did a clean install with my nvidia-340 driver and cuda-6.5 but this code tells me I have no platforms available. Did you have any other thoughts as to why the code cannot find the platform? -
pasternak about 9 yearsDoes the C code still work with the new install, i.e. when it does not check the return code or the number of platforms?
-
cdeterman about 9 yearsIt actually doesn't appear to be working. The output shows each addition as equaling 0. Any thoughts on how to help the code find the platforms?