How to choose OpenCL implementation with CMake? - cmake

I have a Windows OpenCL application that uses some of the AMD extensions. Additionally, my application has some optional CUDA components. When building the visual studio solution with CMake, the FindOpenCL module picks the Nvidia OpenCL implementation instead of AMD's. Is there an easy way to make CMake use the AMD version?
I tried commenting the Nvidia sections in the FindOpenCL module code, but that did not work. Is there some registry setting I can modify? I installed CUDA after installing AMD's SDK. Would the installation order make a difference?

In the end, what worked was to remove the NVIDIA environment variables from the PATHS suggestions in the find_library and find_path commands and adding the NO_DEFAULT_PATH. The issue was that, even though I removed the suggestions, CMake was adding the default path which included NVIDIA's OpenCL implementation. Both commands ended up like shown below:
find_path(OpenCL_INCLUDE_DIR
NAMES
CL/cl.h OpenCL/cl.h
NO_DEFAULT_PATH
PATHS
ENV "PROGRAMFILES(X86)"
ENV AMDAPPSDKROOT
ENV ATISTREAMSDKROOT
PATH_SUFFIXES
include
OpenCL/common/inc
"AMD APP/include")
find_library(OpenCL_LIBRARY
NAMES OpenCL
NO_DEFAULT_PATH
PATHS
ENV "PROGRAMFILES(X86)"
ENV AMDAPPSDKROOT
ENV ATISTREAMSDKROOT
PATH_SUFFIXES
"AMD APP/lib/x86_64"
lib/x86_64
lib/x64
OpenCL/common/lib/x64)

Related

Libtorch only has cmake config file but needs to build with meson

I'm trying to make a cpp project that uses libtorch (C++ distributions of pytorch) using meson build.
It has one simple cpp file of about 50 lines that runs deep learning on images.
First, I confirmed that my project runs well in two environments.
Since meson uses the pkg-config file, I made a simple pkg-config file for libtorch, and it works for a project running on the CPU.
libtorch provides a TorchConfig.cmake file, so I used cmake to confirm that my project runs on the GPU version.
However, I don't know how to build the GPU version of the project using meson.
The TorchConfig.cmake file is more complicated than I thought, so it was very difficult to make it manually with the pkg-config file.
(TorchConfig.cmake file references many cmake files in libtorch directories.)
I also tried to use libtorch_dep = dependency('Torch', method : 'cmake'), but it only found libtorch.so among many libtorch libraries that are for GPU APIs.
So, how can I build the project using libtorch with only cmake config file like this with meson?
Or is there a way to utilize the cmake config file to write a pkg-config file?
Any comments or suggestions would be appreciated.
operating system: Ubuntu 18.04
meson version: 0.54.0
cmake version: 3.22.1
libtorch version: 1.8.0
I tried to leverage “method: cmake” in meson, but it fails.
So, I wrote pkg-config file for libtorch manually and it works now.

CMake can't find non-default Eigen installation

I'm on Lubuntu 20.04. I have libeigen3-devinstalled with apt, which is version 3.3.7. However, for a project, I need 3.4.0.
I downloaded Eigen in a separate folder under $HOME/Libs/eigen-3.4.0, and I'm trying to get CMake to find it. I am using:
find_package(Eigen3 3.4.0 REQUIRED)
include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR})
However, CMake seems to be only able to find the systemwide install, and constantly complains that it cannot fulfill the version requirement. I have tried all combinations I could of both CMAKE_PREFIX_PATH and Eigen3_DIR to no avail.
How exactly should I call CMake to make it see the folder in my home?

Finding the nVIDIA Toolkit Extensions library with CMake

I'm using CMake 3.13, with inherent support for CUDA as a language, to build a project. This project requires the nVIDIA Toolkit Extensions library. On a previous system, I had it under /usr/local/cuda/lib64. I used a find_library() command which I thought should be sufficient, and all was well. But - it isn't, and it wasn't: On a system in which CUDA is installed using OS distribution packages, under /usr directly, my command doesn't work.
To be more specific, I'm using:
find_library(CUDA_NVTX_LIBRARY
NAMES nvToolsExt nvTools nvtoolsext nvtools nvtx NVTX
PATHS ${CUDA_TOOLKIT_ROOT_DIR} ENV LD_LIBRARY_PATH
PATH_SUFFIXES "lib64" "common/lib64" "common/lib" "lib"
DOC "Location of the CUDA Toolkit Extension (NVTX) library"
NO_DEFAULT_PATH
)
and this is missing /usr/lib/x86_64-linux-gnu/libnvToolsExt.so.
Questions:
How should I alter my find_library command not to miss such target-platform-specific folders?
Am I looking for the NVTX library the wrong way? Can I somehow rely on what CMake finds internally instead?
Notes:
I have basically the same issue with libOpenCL.so, nVIDIA's OpenCL layer.
(This answer regards CMake versions earlier than 3.17; you should really switch to a newer version of CMake, which makes your life much easier.)
CMake does figure out the paths of a lot of other CUDA-related libraries, e.g.:
CUDA_CUDART_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcudart.so
CUDA_CUDA_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcuda.so
CUDA_cublas_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcublas.so
CUDA_cudadevrt_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcudadevrt.a
CUDA_cudart_static_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcudart_static.a
CUDA_cufft_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcufft.so
CUDA_cupti_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcupti.so
CUDA_curand_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcurand.so
CUDA_cusolver_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcusolver.so
CUDA_cusparse_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcusparse.so
CUDA_nppc_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppc.so
CUDA_nppial_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppial.so
CUDA_nppicc_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppicc.so
CUDA_nppicom_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppicom.so
CUDA_nppidei_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppidei.so
CUDA_nppif_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppif.so
CUDA_nppig_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppig.so
CUDA_nppim_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppim.so
CUDA_nppist_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppist.so
CUDA_nppisu_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppisu.so
CUDA_nppitc_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnppitc.so
CUDA_npps_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libnpps.so
CUDA_rt_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/librt.so
I think it's actually a bug that it doesn't do so for the NVTX and OpenCL libraries. Still, we can take the paths it finds for other libraries - perhaps the main one, CUDA_CUDART_LIBRARY, and use it as a search hint.
The result is even uglier than what I had before, but it does seems to work:
get_filename_component(CUDA_CUDART_LIBRARY_DIR "${CUDA_CUDART_LIBRARY}" PATH CACHE)
find_library(CUDA_OPENCL_LIBRARY
NAMES OpenCL opencl
PATHS "${CUDA_CUDART_LIBRARY_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}" ENV LD_LIBRARY_PATH
PATH_SUFFIXES "lib64" "lib"
DOC "Location of the CUDA OpenCL support library"
NO_DEFAULT_PATH
)
find_library(CUDA_NVTX_LIBRARY
NAMES nvToolsExt nvTools nvtoolsext nvtools nvtx NVTX
PATHS "${CUDA_CUDART_LIBRARY_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}" ENV LD_LIBRARY_PATH
PATH_SUFFIXES "lib64" "common/lib64" "common/lib" "lib"
DOC "Location of the CUDA Toolkit Extension (NVTX) library"
NO_DEFAULT_PATH
)
You may try CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES (suggested here), which worked for me:
project(theproject LANGUAGES CUDA)
find_library(LIBNVTOOLSEXT nvToolsExt PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})

cmake setting for cuda&visual studio

How to set up custom CUDA directory for enable_language(CUDA)?
From cmake version 3.8~ ,I can use enable_language(CUDA) command.
In my custom cmake file, I set CUDA_TOOLKIT_ROOT_DIR same as cuda custom directory(not an default directory).
But when enable_language(CUDA)command is called, cmake default modules are trying to find CUDA in default directory(somewhere in c:\progrmafiles).
I don't want make my teammate install CUDA toolkit separately.
So i want to include all necessary component and tools for using CUDA in custom directory.
How can i make it done?
Target Environment Info
OS windows 7 x64 (only)
IDE visual studio 2013
cmake version 3.11.4
CUDA version 9.2
If I look at CMakeDetermineCUDACompiler.cmake you can select a specific compiler for enable_language(CUDA) via:
The environment variable CUDACXX (for non-"Visual Studio" environments)
> cmake -E env CUDACXX="<your CUDA path here>" cmake ..
Simply set global variable CMAKE_CUDA_COMPILER
> cmake -D CMAKE_CUDA_COMPILER:FILEPATH="<your CUDA path here>" ..
or in your CMakeLists.txt before your project() or enable_language()
call
if (NOT CMAKE_CUDA_COMPILER)
set(CMAKE_CUDA_COMPILER "${CMAKE_SOURCE_DIR}/<your CUDA relative path here>")
endif()

How to cross compile CMake for ARM with CMake

In short I'm trying to cross compile CMake with CMake, and I don't think I'm linking libraries correctly. What I want to do may not be possible, but I'd at least like to know why it isn't possible if that's the case.
System: The host is a Linux box with a Cavium ARM9 CPU. It's currently running version 2.6.24.4 of the Linux kernel and Debian 5.0 (Lenny). My workstation is a Core i5 running Ubuntu 12.04 LTS (Precise Pangolin).
My overall goal is to get ROS running on the Linux box. I have to compile from source rather than use apt since Debian 6.0 (Squeeze) binaries require thumb support that the Cavium does not give, and not many of the needed packages are available for Debian 5.0 (Lenny). I'd made progress installing the various libraries needed, but when I got to step 1.3.1 and tried to run CMake, I got the error
CMake 2.8 or higher is required. You are running version 2.6.0
Next I tried to download and build CMake 2.8.8 on the Linux box itself, but it was too much for the system. When that failed, I downloaded the toolchain suggested on the manufacturer's website and used the cross-compiling guide at [www.cmake.org/Wiki/CMake_Cross_Compiling] to build the CMake executables. Here is my toolchain file:
# This one is important
SET(CMAKE_SYSTEM_NAME Linux)
# Specify the cross compiler
SET(CMAKE_C_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/arm-unknown-linux-gnu)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
However, use of the binary on the Linux box gives the error
cmake: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by cmake)
Sure enough, the library is not there:
prompt# strings /usr/lib/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBC_2.3
GLIBC_2.0
GLIBC_2.3.2
GLIBC_2.1
GLIBC_2.1.3
GLIBC_2.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
I've never cross-compiled before, but I can see one of two scenarios happening: either the binary got created with a link to a higher version of glibcxx on the host machine or the manufacturer's toolchain is more modern than their image. I don't know how to check which is happening or if something else is happening that I don't know about.
My last effort involved trying to statically cross-compile CMake to hopefully get rid of the linking error with
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-technologic.cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS_RELEASE="-static" ..
I got build errors, and that binary didn't work either. I got:
FATAL: kernel too old
Segmentation fault
I'd try installing glibcxx 3.4.14 on the Linux box, but it doesn't look like it's available for this processor.
I've tried searching for CMake dependencies or system requirements and can't find anything. I've also searched on how to build CMake, but most searches turn up how to build other things with CMake rather than building CMake itself.
I do cross-compile a lot for ARM9 devices using CMake, and indeed this looks like you're not linking to the same libs you have on your target device. You shouldn't need to build CMake yourself to get this done, since it does have good support for cross-compiling since version 2.6. Just make sure you set the CMAKE_FIND_ROOT_PATH variable to a path where you have an exact copy of the root filesystem you have on your target device (with libraries and binaries pre-compiled for the target processor). That should solve your problems.
As a sidenote, I like to use crosstool-ng for building my cross-compilers. It is a really nice tool which helps you to build them from scratch, so I try to match the compiler version and glibc to the ones originally used to build the root filesystem (I usually start with a ready made root filesystem from ARMedslack, since I use Slackware for my development box and ARMedslack for my ARM targets).