I posted this question on stackoverflow, but got nothing.
Basically, I have a program that uses clAmdFft, and I want it to run on arbitrary machines, i.e. AMD GPUs, CPUs and nVidia GPUs. nVidia users will have a libOpenCL.so that doesn't come with version information for some reason, everything is tagged as "Base" there (as does Intel's library), AMD's library does come with version tags, and since libclAmdFft.Runtime.so is intended for use with AMDAPP-SDK, it explicitly requires a version.
But that would add a dependency on the AMDAPP-SDK for me, while it should be possible to use Khronos' OpenCL headers and the GPU-driver provided libOpenCL, and only depend on clAmdFft.
$ objdump -x libclAmdFft.Runtime.so
required from libOpenCL.so.1:
0x028568b0 0x00 05 OPENCL_1.0
On one machine, I'm using the AMD driver, which comes with a libOpenCL.so that includes version information, like this:
a$ objdump -T /opt/AMDAPP/lib/x86_64/libOpenCL.so
0000000000002610 g DF .text 0000000000000018 OPENCL_1.0 clGetSamplerInfo
00000000000032e0 g DF .text 0000000000000018 OPENCL_1.1 clSetEventCallback
0000000000002350 g DF .text 0000000000000018 OPENCL_1.2 clCreateSubDevices
Everything is fine on this machine.
On another machine, I'm using the nVidia driver, which comes with a libOpenCL.so that doesn't include version information, like this (same with Intel driver)
b$ objdump -T /usr/lib/libOpenCL.so # -> /usr/lib/nvidia-current/libOpenCL.so
00000000000021f0 g DF .text 0000000000000018 Base clGetSamplerInfo
0000000000002a40 g DF .text 0000000000000018 Base clSetEventCallback
Linking a program with
-llibOpenCL.so -llibclAmdFft.Runtime.so fails here, since clAmdFft wants to link to the tagged symbols:
libclAmdFftRuntime.so: undefinded reference to `clCreateBuffer@OPENCL_1.0`
The dynamic linker also generates this complaint:
b$ ldd libclAmdFft.Runtime.so
libclAmdFft.Runtime.so: …/libOpenCL.so.1: no version information available …
Since the nVidia driver implements OpenCL 1.1 and AmdFFT only needs 1.0, it should work, if I can convince it that
Base = OPENCL_1.0. Is that possible?
I can't force nVidia-users to install another version, since the libOpenCL is part of the driver, like libGL.
--unresolved-symbols=ignore-in-shared-libs succeeds, but the resulting binary doesn't find the FFT-library anymore.
Since OpenCL splits off the device-dependent parts into ICD libraries, it would work if I supplied the libOpenCL.so from the AMD driver, even on nVidia machines, where it dynamically loads the correct ICD from /etc/OpenCL/vendors/nvidia.icd, but I'm not sure if this is actually portable, the directory is hard-coded for example.
Thanks for posting your question here. Unfortunately, this seems to be a known issue with Intel and Nvidia not strictly conforming to the Khronos OpenCL standards in terms of versioning their symbols. They are aware of this, but we don't know if they will fix this in their future versions.
Using libOpenCL.so from the AMD driver is one way to go, as it can load any platform that correctly implemets the OpenCL ICD. This has been checked to work on such platforms.
BTW, how has been your experience using the FFT library on AMD GPUs? Any concerns, feedback?
When I ship AMD's libOpenCL.so, will there be a CPU device available on nVidia-Platforms as well? (i.e. is the GPU device a feature of the vendor-specific ICD or of the libOpenCL?)
That would be nice to have as a fallback, since for example clAmdFft fails (with invalid program) to create a 512x512 plan on a 128MB nVidia Quadro NVS 135M, I guess it doesn't support the number of instructions the FFT-kernels need.