J'essaie de compiler un programme openCL sur Ubuntu avec une carte NVIDIA qui fonctionnait une fois auparavant,
#include <CL/cl.h>
#include <iostream>
#include <vector>
using namespace std;
int main() {
cl_platform_id platform;
cl_device_id device;
cl_context context;
cl_command_queue command_queue;
cl_int error;
if(clGetPlatformIDs(1, &platform, NULL) != CL_SUCCESS) {
cout << "platform error" << endl;
}
if(clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL) != CL_SUCCESS) {
cout << "device error" << endl;
}
context = clCreateContext(NULL, 1, &device, NULL, NULL, &error);
if(error != CL_SUCCESS) {
cout << "context error" << endl;
}
command_queue = clCreateCommandQueue(context, device, 0, &error);
if(error != CL_SUCCESS) {
cout << "command queue error" << endl;
}
return 0;
}
Je le compile comme si,
g++ -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL opencl.cpp
et j'obtiens ce résultat
/tmp/ccAdS9ig.o: In function `main':
opencl.cpp:(.text+0x1a): undefined reference to `clGetPlatformIDs'
opencl.cpp:(.text+0x3d): undefined reference to `clGetDeviceIDs'
opencl.cpp:(.text+0x65): undefined reference to `clCreateContext'
opencl.cpp:(.text+0x85): undefined reference to `clCreateCommandQueue'
collect2: ld returned 1 exit status
mais nm -D /usr/lib/nvidia-current/libOpenCL.so
me dit que libOpenCL.so contient au moins clGetPlatformIDs
0000000000002400 T clGetKernelWorkGroupInfo
0000000000002140 T clGetMemObjectInfo
0000000000002e80 T clGetPlatformIDs
0000000000002de0 T clGetPlatformInfo
0000000000002310 T clGetProgramBuildInfo
00000000000022f0 T clGetProgramInfo
00000000000021f0 T clGetSamplerInfo
Est-ce que je manque quelque chose?.
De la page de manuel gcc
:
-llibrary
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o
-lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified
precisely by name.
Essayez donc de spécifier le -lOpenCL
après l'argument de fichier dans votre commande de compilation.
Vous recherchez également des symboles dans libOpenCL.so, qui est un fichier de bibliothèque partagée. Avec votre commande, vous liez votre programme à une bibliothèque statique, au format libOpenCL.a
.
lorsque vous créez un lien, l'ordre de vos bibliothèques et de vos fichiers source fait la différence. par exemple pour votre cas,
g ++ -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL opencl.cpp
les fonctions définies dans la bibliothèque OpenCL peuvent ne pas être chargées, car rien ne les a précédées pour demander une consultation. cependant si vous utilisez,
g++ opencl.cpp -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL
alors toutes les demandes de fonctions seront trouvées dans la bibliothèque OpenCL et elles seront chargées.
Vous pouvez également ajouter l'en-tête et le chemin de la bibliothèque à vos variables globales.
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/cuda/include
export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib/nvidia-current
Vous pouvez également essayer de définir
export PATH=$PATH:/usr/local/cuda/bin
Il devrait être possible de courir maintenant
g++ opencl.cpp