Intel performance libraries (oneAPI) provide cmake package configuration, how to best use it?
I've just started to test the latest Intel performance libraries, that are now available in the oneAPI base toolkit. I was positively surprised to see they provide cmake package configuration. I think this could significantly simplify detection and use of these libraries, i.e. MKL, that has been notoriously hard to detect reliably (see also #20479 (comment 720803)).
I can help with this issue, but I do not feel confident to decide what is the best way to proceed. There are seven performance libraries included in oneAPI. What is the best way to implement support for them in cmake? Even despite having the package configuration, it may be helpful if cmake had some (limited) understanding on the directory layout of oneAPI, to help users detect these libraries more easily. See i.e. the versioned subdirectories of ONEAPI_ROOT
below.
So my questions are:
- Should cmake provide find-scripts for the seven libraries? The find-scripts could just wrap the package configuration, but have some logic for the directory layout of oneAPI. And/or they could respect a variable like
ONEAPI_ROOT
, that points to the root of the oneAPI installation. - If cmake should not provide such find-scripts, what is the most convenient way to work with oneAPI?
Intel also provides a script setvars.sh
that sets environment variables for using oneAPI. However I would prefer to avoid this script if possible. This is on one side because the script directly modifies or sets platform-specific environment variables like LD_LIBRARY_PATH
, LIBRARY_PATH
, NLSPATH
, CPATH
etc. But also using such setup scripts is a lot more monolitic, i.e. they are typically set for the whole CI and are much less easily configurable than what cmake allows. For these reasons I would significantly prefer a pure cmake solution.
I can see that a number of libraries provide package configuration. Specifically I have:
dal/2021.4.0/lib/cmake/oneDAL/oneDALConfig.cmake
dnnl/2021.4.0/lib/cmake/dnnl/dnnl-config.cmake
ipp/2021.4.0/lib/cmake/ipp/ipp-config.cmake
ippcp/2021.4.0/lib/cmake/ippcp/ippcp-config.cmake
mkl/2021.4.0/lib/cmake/mkl/MKLConfig.cmake
tbb/2021.4.0/lib/cmake/tbb/TBBConfig.cmake
vpl/2021.6.0/lib/cmake/vpl/VPLConfig.cmake
A minor nuisance seems to be the use of the versioned subdirectory. On both Linux and Windows there are symbolic links named latest
that target the versioned subdirectory:
dal/latest/lib/cmake
dnnl/latest/lib/cmake
ippcp/latest/lib/cmake
ipp/latest/lib/cmake
mkl/latest/lib/cmake
tbb/latest/lib/cmake
vpl/latest/lib/cmake
But while this will certainly help on Unix-like platforms, I'm not sure how well directory symlinks are supported in cmake on Windows?
In any case, the package configuration seems to work nicely. In a first test, I could link against Intel MKL with a simple
list(APPEND CMAKE_MODULE_PATH "$ENV{ONEAPI_ROOT}/mkl/2021.4.0/lib/cmake/mkl")
find_package(MKL Required)
target_link_libraries(${PROJECT} MKL::MKL)
The package configuration for MKL supports the following variables for configuration:
"-DMKL_ARCH=intel64"
"-DMKL_LINK=static"
"-DMKL_THREADING=sequential"
"-DMKL_INTERFACE=lp64"