From 60278b15ef6b75f8bf15ab8cff9b78913070d523 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 13:24:07 +0100 Subject: [PATCH 1/4] Update DPC++, MKL, DPL, TBB cmake configs with the latest 2025.3 release --- .../cmake/Modules/IntelSYCLConfig.cmake | 153 ++- dpnp/backend/cmake/Modules/MKLConfig.cmake | 1212 ++++++++++++----- dpnp/backend/cmake/Modules/TBBConfig.cmake | 131 +- dpnp/backend/cmake/Modules/oneDPLConfig.cmake | 116 +- 4 files changed, 1103 insertions(+), 509 deletions(-) diff --git a/dpnp/backend/cmake/Modules/IntelSYCLConfig.cmake b/dpnp/backend/cmake/Modules/IntelSYCLConfig.cmake index c67ef96a785d..31ad2ef60272 100644 --- a/dpnp/backend/cmake/Modules/IntelSYCLConfig.cmake +++ b/dpnp/backend/cmake/Modules/IntelSYCLConfig.cmake @@ -1,5 +1,5 @@ # -# Modifications, Copyright (c) 2023-2025 Intel Corporation +# Modifications, Copyright (C) 2024 Intel Corporation # # This software and the related documents are Intel copyrighted materials, and # your use of them is governed by the express license under which they were @@ -28,10 +28,16 @@ This will define the following variables: ``IntelSYCL_FOUND`` True if the system has the SYCL library. +``SYCL_COMPILER`` + The resolved SYCL compiler. ``SYCL_LANGUAGE_VERSION`` The SYCL language spec version by Compiler. +``SYCL_COMPILER_VERSION`` + The SYCL version of the supported Compiler. ``SYCL_INCLUDE_DIR`` Include directories needed to use SYCL. +``SYCL_INCLUDE_SYCL_DIR`` + Include directories needed to use SYCL. ``SYCL_IMPLEMENTATION_ID`` The SYCL compiler variant. ``SYCL_FLAGS`` @@ -50,6 +56,11 @@ The following cache variable may also be set: ``SYCL_LANGUAGE_VERSION`` The SYCL language spec version by Compiler. +``SYCL_COMPILER_VERSION`` + The SYCL version of the supported Compiler. + +``SYCL_COMPILER`` + The supported SYCL Compiler. .. Note:: @@ -73,6 +84,11 @@ The following cache variable may also be set: #]=======================================================================] +if(__INTEL_SYCL_CONFIG) + return() +endif() +set(__INTEL_SYCL_CONFIG 1) + include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) find_package(PkgConfig QUIET) @@ -88,10 +104,18 @@ endif() string(COMPARE EQUAL "${CMAKE_CXX_COMPILER}" "" nocmplr) if(nocmplr) set(IntelSYCL_FOUND False) - set(SYCL_REASON_FAILURE "SYCL: CMAKE_CXX_COMPILER not set!!") + set(SYCL_REASON_FAILURE "CMAKE_CXX_COMPILER not set!!") set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}") endif() +if(NOT "x${SYCL_HOST_COMPILER}" STREQUAL "x") + set(sycl_host_compiler "-fsycl-host-compiler=${SYCL_HOST_COMPILER}") +else() + set(sycl_host_compiler "") +endif() + +message(VERBOSE "SYCL_HOST_COMPILER = ${SYCL_HOST_COMPILER}") + # Check if a Compiler ID is being set. project() should be set prior to find_package() if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "x") @@ -106,15 +130,68 @@ endif() if( NOT "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" AND NOT "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM") set(IntelSYCL_FOUND False) - set(SYCL_REASON_FAILURE "Unsupported compiler family ${CMAKE_CXX_COMPILER_ID} and compiler ${CMAKE_CXX_COMPILER}!!") - set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}") - return() + set(SYCL_REASON_FAILURE "Unsupported compiler family ${CMAKE_CXX_COMPILER_ID} and compiler ${CMAKE_CXX_COMPILER}. Also default Intel SYCL compiler not found in the environment!!") + + #find_program(INTEL_SYCL_COMPILER NAMES icpx icx icx-cc icx-cl) + if(WIN32 AND + (NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "GNU")) + find_program(INTEL_SYCL_COMPILER NAMES icx icx-cl) + else() + find_program(INTEL_SYCL_COMPILER icpx) + endif() + + if(NOT INTEL_SYCL_COMPILER) + message(FATAL_ERROR "Intel SYCL Compiler not found.") + set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}") + return() + else() + # Remove trailing semicolon if present + string(STRIP "${INTEL_SYCL_COMPILER};" INTEL_SYCL_COMPILER) + message(STATUS "Setting SYCL Compiler to default ${INTEL_SYCL_COMPILER}.") + set(SYCL_COMPILER ${INTEL_SYCL_COMPILER}) + set(IntelSYCL_FOUND True) + endif() +else() + # Assume that CXX Compiler supports SYCL and then test to verify. + set(SYCL_COMPILER ${CMAKE_CXX_COMPILER}) endif() -# Assume that CXX Compiler supports SYCL and then test to verify. -set(SYCL_COMPILER ${CMAKE_CXX_COMPILER}) - # Function to write a test case to verify SYCL features. +function(parse_compiler_version compiler_name version_number) + execute_process( + COMMAND ${compiler_name} --version + OUTPUT_VARIABLE COMPILER_VERSION_STRING + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Intel Compiler Regex + string(REGEX MATCH "Intel\\(R\\) (.*) Compiler ([0-9]+\\.[0-9]+\\.[0-9]+) (.*)" + INTEL_VERSION_STRING ${COMPILER_VERSION_STRING}) + + if(INTEL_VERSION_STRING) + # Parse Intel Compiler Version + string(REGEX REPLACE "Intel\\(R\\) (.*) Compiler ([0-9]+\\.[0-9]+\\.[0-9]+) (.*)" "\\2" + SYCL_VERSION_STRING_MATCH ${INTEL_VERSION_STRING}) + string(REPLACE "." ";" SYCL_VERSION_LIST ${SYCL_VERSION_STRING_MATCH}) + list(GET SYCL_VERSION_LIST 0 VERSION_MAJOR) + list(GET SYCL_VERSION_LIST 1 VERSION_MINOR) + list(GET SYCL_VERSION_LIST 2 VERSION_PATCH) + math(EXPR VERSION_NUMBER_MATCH "${VERSION_MAJOR} * 10000 + ${VERSION_MINOR} * 100 + ${VERSION_PATCH}") + endif() + set(${version_number} "${VERSION_NUMBER_MATCH}" PARENT_SCOPE) +endfunction() + +parse_compiler_version(${SYCL_COMPILER} SYCL_COMPILER_VERSION) + +if(NOT SYCL_COMPILER_VERSION) + set(SYCL_FOUND False) + set(SYCL_REASON_FAILURE "Cannot parse sycl compiler version to get SYCL_COMPILER_VERSION!") + set(SYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}") + return() +endif() + +#set(SYCL_COMPILER_VERSION ${COMPILER_VERSION}) +message(STATUS "SYCL Compiler version: ${SYCL_COMPILER_VERSION}") function(SYCL_FEATURE_TEST_WRITE src) @@ -143,7 +220,7 @@ function(SYCL_FEATURE_TEST_BUILD TEST_SRC_FILE TEST_EXE) # Convert CXX Flag string to list set(SYCL_CXX_FLAGS_LIST "${SYCL_CXX_FLAGS}") - separate_arguments(SYCL_CXX_FLAGS_LIST) + separate_arguments(SYCL_CXX_FLAGS_LIST NATIVE_COMMAND ${SYCL_CXX_FLAGS_LIST}) # Spawn a process to build the test case. execute_process( @@ -157,6 +234,7 @@ function(SYCL_FEATURE_TEST_BUILD TEST_SRC_FILE TEST_EXE) OUTPUT_FILE ${SYCL_TEST_DIR}/Compile.log RESULT_VARIABLE result TIMEOUT 60 + #COMMAND_ECHO STDOUT ) # Verify if test case build properly. @@ -230,6 +308,17 @@ if(SYCL_COMPILER) NO_DEFAULT_PATH ) + # Find include/sycl path from include path. + find_file( + SYCL_INCLUDE_SYCL_DIR + NAMES sycl + HINTS + ${SYCL_PACKAGE_DIR} $ENV{SYCL_INCLUDE_DIR_HINT} + PATH_SUFFIXES include + NO_DEFAULT_PATH + ) + message(STATUS "SYCL_INCLUDE_DIR: ${SYCL_INCLUDE_DIR}") + # Find Library directory find_file(SYCL_LIBRARY_DIR NAMES @@ -238,7 +327,22 @@ if(SYCL_COMPILER) ${SYCL_PACKAGE_DIR} $ENV{SYCL_LIBRARY_DIR_HINT} NO_DEFAULT_PATH ) - + #TODO Make an input file to configure and update the lib current version + if(WIN32) + set(sycl_lib_suffix "8") + else() + set(sycl_lib_suffix "") + endif() + if(NOT "x${SYCL_LIB_SUFFIX}" STREQUAL "x") + set(sycl_lib_suffix "${SYCL_LIB_SUFFIX}") + endif() + find_library( + SYCL_LIBRARY + NAMES "sycl${sycl_lib_suffix}" + HINTS ${SYCL_LIBRARY_DIR} + NO_DEFAULT_PATH + ) + message(STATUS "SYCL_LIBRARY=${SYCL_LIBRARY}") endif() @@ -247,7 +351,7 @@ set(SYCL_LINK_FLAGS "") # Based on Compiler ID, add support for SYCL if( "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" OR - "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM") + "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM" OR IntelSYCL_FOUND) list(APPEND SYCL_FLAGS "-fsycl") list(APPEND SYCL_LINK_FLAGS "-fsycl") endif() @@ -258,7 +362,9 @@ if(WIN32) list(APPEND SYCL_FLAGS "/EHsc") endif() -set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SYCL_FLAGS}") +list(JOIN SYCL_FLAGS " " SYCL_FLAGS_STRING) +message(DEBUG "SYCL_FLAGS_STRING: ${SYCL_FLAGS_STRING}") +set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SYCL_FLAGS_STRING}") # And now test the assumptions. @@ -286,10 +392,15 @@ SYCL_FEATURE_TEST_EXTRACT(${test_output}) string(COMPARE EQUAL "${SYCL_LANGUAGE_VERSION}" "" nosycllang) if(nosycllang) set(IntelSYCL_FOUND False) - set(SYCL_REASON_FAILURE "SYCL: It appears that the ${CMAKE_CXX_COMPILER} does not support SYCL") + set(SYCL_REASON_FAILURE "SYCL: It appears that the ${SYCL_COMPILER} does not support SYCL") set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}") endif() +if(NOT "x${sycl_host_compiler}" STREQUAL "x") + list(APPEND SYCL_FLAGS ${sycl_host_compiler}) + list(APPEND SYCL_CXX_FLAGS ${sycl_host_compiler}) +endif() + # Placeholder for identifying various implementations of SYCL compilers. # for now, set to the CMAKE_CXX_COMPILER_ID set(SYCL_IMPLEMENTATION_ID "${CMAKE_CXX_COMPILER_ID}") @@ -307,16 +418,24 @@ set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SYCL_INCLUDE_DIR}) set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY INTERFACE_LINK_DIRECTORIES ${SYCL_LIBRARY_DIR}) +set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY + INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY}) find_package_handle_standard_args( IntelSYCL FOUND_VAR IntelSYCL_FOUND - REQUIRED_VARS SYCL_INCLUDE_DIR SYCL_LIBRARY_DIR SYCL_FLAGS + REQUIRED_VARS SYCL_INCLUDE_DIR SYCL_LIBRARY_DIR SYCL_FLAGS SYCL_COMPILER_VERSION SYCL_COMPILER SYCL_LIBRARY VERSION_VAR SYCL_LANGUAGE_VERSION REASON_FAILURE_MESSAGE "${SYCL_REASON_FAILURE}") # Include in Cache set(SYCL_LANGUAGE_VERSION "${SYCL_LANGUAGE_VERSION}" CACHE STRING "SYCL Language version") +set(SYCL_COMPILER_VERSION "${SYCL_COMPILER_VERSION}" CACHE STRING "SYCL Compiler version") +set(SYCL_COMPILER "${SYCL_COMPILER}" CACHE STRING "SYCL Compiler") +set(SYCL_INCLUDE_DIR "${SYCL_INCLUDE_DIR}" CACHE STRING "SYCL Include Dir ") +set(SYCL_INCLUDE_SYCL_DIR "${SYCL_INCLUDE_SYCL_DIR}" CACHE STRING "SYCL Include SYCL Dir ") +set(SYCL_LIBRARY_DIR "${SYCL_LIBRARY_DIR}" CACHE STRING "SYCL Library Dir") +set(SYCL_LIBRARY "${SYCL_LIBRARY}" CACHE STRING "SYCL Library") function(add_sycl_to_target) @@ -340,6 +459,10 @@ Adding sycl to all sources but that may effect compilation times") set(SYCL_TARGET ${ARGV}) endif() + if(NOT SYCL_TARGET) + message(FATAL_ERROR "add_sycl_to_target() requires a TARGET argument, but none was passed.") + endif() + if(NOT SYCL_SOURCES) message(WARNING "add_sycl_to_target() does not have sources specified.. Adding sycl to all sources but that may effect compilation times") target_compile_options(${SYCL_TARGET} PUBLIC ${__sycl_cxx_options}) @@ -353,7 +476,7 @@ Adding sycl to all sources but that may effect compilation times") get_target_property(__sycl_link_options IntelSYCL::SYCL_CXX INTERFACE_LINK_OPTIONS) - target_link_options(${SYCL_TARGET} PRIVATE "${__sycl_link_options}") + target_link_options(${SYCL_TARGET} PUBLIC "${__sycl_link_options}") get_target_property(__sycl_link_directories IntelSYCL::SYCL_CXX INTERFACE_LINK_DIRECTORIES) target_link_directories(${SYCL_TARGET} PUBLIC "${__sycl_link_directories}") diff --git a/dpnp/backend/cmake/Modules/MKLConfig.cmake b/dpnp/backend/cmake/Modules/MKLConfig.cmake index 54bb586295c3..7e513c5f3ab7 100644 --- a/dpnp/backend/cmake/Modules/MKLConfig.cmake +++ b/dpnp/backend/cmake/Modules/MKLConfig.cmake @@ -1,5 +1,5 @@ #=============================================================================== -# Copyright (c) 2021-2025 Intel Corporation. +# Copyright (C) 2021 Intel Corporation # # This software and the related documents are Intel copyrighted materials, and # your use of them is governed by the express license under which they were @@ -24,22 +24,18 @@ #------------- # MKL_ROOT: oneMKL root directory (May be required for non-standard install locations. Optional otherwise.) # Default: use location from MKLROOT environment variable or /../../../ if MKLROOT is not defined -# MKL_ARCH -# Values: ia32 intel64 -# Default: intel64 # MKL_LINK # Values: static, dynamic, sdl # Default: dynamic -# Exceptions:- DPC++ doesn't support sdl +# Exceptions: SYCL doesn't support sdl # MKL_THREADING # Values: sequential, # intel_thread (Intel OpenMP), # gnu_thread (GNU OpenMP), -# pgi_thread (PGI OpenMP), # tbb_thread # Default: intel_thread -# Exceptions:- DPC++ defaults to tbb, PGI compiler on Windows defaults to pgi_thread -# MKL_INTERFACE (for MKL_ARCH=intel64 only) +# Exceptions: SYCL defaults to oneTBB +# MKL_INTERFACE # Values: lp64, ilp64 # GNU or INTEL interface will be selected based on Compiler. # Default: ilp64 @@ -49,13 +45,18 @@ #----------------------------------- # Special options (OFF by default) #----------------------------------- -# ENABLE_BLAS95: Enables BLAS Fortran95 API -# ENABLE_LAPACK95: Enables LAPACK Fortran95 API -# ENABLE_BLACS: Enables cluster BLAS library -# ENABLE_CDFT: Enables cluster DFT library -# ENABLE_CPARDISO: Enables cluster PARDISO functionality -# ENABLE_SCALAPACK: Enables cluster LAPACK library -# ENABLE_OMP_OFFLOAD: Enables OpenMP Offload functionality +# ENABLE_BLAS95: Enables BLAS Fortran95 API in MKL::MKL +# ENABLE_LAPACK95: Enables LAPACK Fortran95 API in MKL::MKL +# ENABLE_BLACS: Enables cluster BLAS library in MKL::MKL +# ENABLE_CDFT: Enables cluster DFT library in MKL::MKL +# ENABLE_SCALAPACK: Enables cluster LAPACK library in MKL::MKL +# ENABLE_OMP_OFFLOAD: Enables OpenMP Offload functionality in MKL::MKL +# ENABLE_TRY_SYCL_COMPILE: Enables compiling a test program that calls a oneMKL SYCL API +#----------------------------------- +# Special options (AUTO by default) +#----------------------------------- +# ENABLE_SYCL_COMPILER: Enables or disables treating the C++ compiler as a SYCL compiler. +# By default, the compiler will be checked if it is a SYCL compiler. # #================== # Output parameters @@ -70,34 +71,51 @@ # Provides all environment variables based on input parameters. # Currently useful for mkl_rt linking and BLACS on Windows. # Must be set as an ENVIRONMENT property. -# Example: +# Example: # add_test(NAME mytest COMMAND myexe) # if(MKL_ENV) # set_tests_properties(mytest PROPERTIES ENVIRONMENT "${MKL_ENV}") # endif() # # MKL:: -# IMPORTED targets to link MKL libraries individually or when using a custom link-line. +# IMPORTED targets to link oneMKL libraries individually or when using a custom link-line. # mkl_core and mkl_rt have INTERFACE_* properties set to them. # Please refer to Intel(R) oneMKL Link Line Advisor for help with linking. # # Below INTERFACE targets provide full link-lines for direct use. # Example: -# target_link_options( PUBLIC $) +# target_link_options( PUBLIC MKL::MKL) # # MKL::MKL # Link line for C and Fortran API -# MKL::MKL_DPCPP -# Link line for DPC++ API +# MKL::MKL_SYCL +# Link line for SYCL API +# MKL::MKL_SYCL:: +# Link line for specific domain SYCL API +# Where could be: BLAS, LAPACK, DFT, SPARSE, RNG, STATS, VM, DATA_FITTING (experimental) +# MKL::MKL_CDFT +# Link line for CDFT and Cluster FFTW API (includes MKL::MKL and MKL::MKL_BLACS) +# !IMPORTANT!: Because of specific link order it must not be used together +# with any other oneMKL targets in case of MKL_LINK=static on Linux +# MKL::MKL_SCALAPACK +# Link line for ScaLAPACK and PBLAS API (includes MKL::MKL and MKL::MKL_BLACS) +# MKL::MKL_BLACS +# Link line for BLACS and CPARDISO API (includes MKL::MKL) +# MKL::MKL_SYCL_DISTRIBUTED_DFT +# Link line for SYCL Distributed DFT library (includes MKL::MKL_SYCL::DFT, Linux only) # # Note: For Device API, library linking is not required. -# Compile options can be added from the INTERFACE_COMPILE_OPTIONS property on MKL::MKL_DPCPP -# Include directories can be added from the INTERFACE_INCLUDE_DIRECTORIES property on MKL::MKL_DPCPP +# Compile options can be added from the INTERFACE_COMPILE_OPTIONS property on MKL::MKL_SYCL +# Include directories can be added from the INTERFACE_INCLUDE_DIRECTORIES property on MKL::MKL_SYCL # # Note: Output parameters' and targets' availability can change # based on Input parameters and application project languages. #=============================================================================== +include_guard() + +if(NOT TARGET MKL::MKL) + function(mkl_message MSG_MODE MSG_TEXT) if(MSG_MODE STREQUAL "FATAL_ERROR") message(${MSG_MODE} ${MSG_TEXT}) @@ -108,14 +126,15 @@ function(mkl_message MSG_MODE MSG_TEXT) endif() endfunction() -if(${CMAKE_VERSION} VERSION_LESS "3.13") - mkl_message(FATAL_ERROR "The minimum supported CMake version is 3.13. You are running version ${CMAKE_VERSION}") -endif() - -include_guard() -include(FindPackageHandleStandardArgs) +macro(mkl_not_found_and_return NOT_FOUND_MSG) + set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${NOT_FOUND_MSG}") + set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE) + return() +endmacro() -if(NOT MKL_LIBRARIES) +if(CMAKE_VERSION VERSION_LESS "3.13") + mkl_not_found_and_return("The minimum supported CMake version is 3.13. You are running version ${CMAKE_VERSION}.") +endif() # Set CMake policies for well-defined behavior across CMake versions cmake_policy(SET CMP0011 NEW) @@ -131,16 +150,19 @@ foreach(lang ${languages}) endforeach() list(REMOVE_DUPLICATES CURR_LANGS) -option(ENABLE_BLAS95 "Enables BLAS Fortran95 API" OFF) -option(ENABLE_LAPACK95 "Enables LAPACK Fortran95 API" OFF) -option(ENABLE_BLACS "Enables cluster BLAS library" OFF) -option(ENABLE_CDFT "Enables cluster DFT library" OFF) -option(ENABLE_CPARDISO "Enables cluster PARDISO functionality" OFF) -option(ENABLE_SCALAPACK "Enables cluster LAPACK library" OFF) -option(ENABLE_OMP_OFFLOAD "Enables OpenMP Offload functionality" OFF) +option(ENABLE_BLAS95 "Enables BLAS Fortran95 API" OFF) +option(ENABLE_LAPACK95 "Enables LAPACK Fortran95 API" OFF) +option(ENABLE_BLACS "Enables cluster BLAS library" OFF) +option(ENABLE_CDFT "Enables cluster DFT library" OFF) +option(ENABLE_SCALAPACK "Enables cluster LAPACK library" OFF) +option(ENABLE_OMP_OFFLOAD "Enables OpenMP Offload functionality" OFF) +option(ENABLE_TRY_SYCL_COMPILE "Enables compiling a oneMKL SYCL test program" OFF) + +set(ENABLE_SYCL_COMPILER AUTO CACHE STRING "Enable SYCL compiler support") +set_property(CACHE ENABLE_SYCL_COMPILER PROPERTY STRINGS AUTO ON OFF) # Use MPI if any of these are enabled -if(ENABLE_BLACS OR ENABLE_CDFT OR ENABLE_SCALAPACK OR ENABLE_CPARDISO) +if(ENABLE_BLACS OR ENABLE_CDFT OR ENABLE_SCALAPACK) set(USE_MPI ON) endif() @@ -165,7 +187,13 @@ function(define_param TARGET_PARAM DEFAULT_PARAM SUPPORTED_LIST) foreach(opt ${${SUPPORTED_LIST}}) set(STR_LIST "${STR_LIST} ${opt}") endforeach() - mkl_message(FATAL_ERROR "Invalid ${TARGET_PARAM} `${${TARGET_PARAM}}`, options are: ${STR_LIST}") + if(${ARGC} EQUAL 3) + mkl_message(WARNING "Invalid ${TARGET_PARAM} `${${TARGET_PARAM}}`, options are: ${STR_LIST}") + set(${TARGET_PARAM} "${${TARGET_PARAM}}_MKL_INVALID_PARAM" PARENT_SCOPE) + elseif(${ARGC} EQUAL 4) + mkl_message(${ARGV3} "Invalid ${TARGET_PARAM} `${${TARGET_PARAM}}`, options are: ${STR_LIST}") + set(${TARGET_PARAM} "" PARENT_SCOPE) + endif() else() mkl_message(STATUS "${TARGET_PARAM}: ${${TARGET_PARAM}}") endif() @@ -174,6 +202,17 @@ function(define_param TARGET_PARAM DEFAULT_PARAM SUPPORTED_LIST) endif() endfunction() +macro(check_required_vars) + foreach(var IN ITEMS ${ARGV}) + if(NOT ${var}) + mkl_not_found_and_return("The required variable ${var} has an invalid value \"${${var}}\".") + elseif(${${var}} MATCHES "_MKL_INVALID_PARAM$") + string(REPLACE "_MKL_INVALID_PARAM" "" INVALID_PARAM ${${var}}) + mkl_not_found_and_return("The required variable ${var} has an invalid value \"${INVALID_PARAM}\".") + endif() + endforeach() +endmacro() + #================ # Compiler checks #================ @@ -189,26 +228,76 @@ if(CMAKE_Fortran_COMPILER) endif() # Determine Compiler Family -if(CXX_COMPILER_NAME STREQUAL "dpcpp" OR CXX_COMPILER_NAME STREQUAL "dpcpp.exe" - OR CXX_COMPILER_NAME STREQUAL "icpx" OR CXX_COMPILER_NAME STREQUAL "icx.exe") - set(DPCPP_COMPILER ON) -endif() -if(C_COMPILER_NAME MATCHES "^clang") +if(ENABLE_SYCL_COMPILER STREQUAL "AUTO") # default + # Check Intel oneAPI Compiler binary name for SYCL support + if(CXX_COMPILER_NAME STREQUAL "dpcpp" OR CXX_COMPILER_NAME STREQUAL "dpcpp.exe" + OR CXX_COMPILER_NAME STREQUAL "icpx" OR CXX_COMPILER_NAME STREQUAL "icx.exe" + OR CXX_COMPILER_NAME STREQUAL "mpiicpx" OR CXX_COMPILER_NAME STREQUAL "mpiicx.bat") + set(SYCL_COMPILER ON) + else() # Non-Intel oneAPI Compilers + # Slower but robust check for SYCL support in non-Intel oneAPI compilers + if("CXX" IN_LIST CURR_LANGS AND + (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")) + include(CheckCXXCompilerFlag) + include(CheckIncludeFileCXX) + # Check SYCL flag support by the compiler + check_cxx_compiler_flag("-fsycl" COMPILER_FSYCL_SUPPORT) + if(COMPILER_FSYCL_SUPPORT) + # Check SYCL header support by the compiler + CHECK_INCLUDE_FILE_CXX("sycl/sycl.hpp" SYCL_SYCL_HPP "-fsycl") + if(NOT SYCL_SYCL_HPP) + CHECK_INCLUDE_FILE_CXX("CL/sycl.hpp" SYCL_CL_HPP "-fsycl") + endif() + if(SYCL_SYCL_HPP OR SYCL_CL_HPP) + set(SYCL_COMPILER ON) + endif() + endif() # COMPILER_FSYCL_SUPPORT + endif() # CXX IN_LIST CURR_LANGS + endif() # CXX_COMPILER_NAME +elseif(ENABLE_SYCL_COMPILER) + # Using the "ON" option with a non-SYCL compiler may lead to unexpected behavior. + set(SYCL_COMPILER ON) +else() + set(SYCL_COMPILER OFF) +endif() # ENABLE_SYCL_COMPILER +if(C_COMPILER_NAME MATCHES "^clang" OR CXX_COMPILER_NAME MATCHES "^clang") set(CLANG_COMPILER ON) endif() -if(CMAKE_C_COMPILER_ID STREQUAL "PGI" OR CMAKE_Fortran_COMPILER_ID STREQUAL "PGI") - set(PGI_COMPILER ON) -elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" - OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM" OR CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM") +if(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_CXX_COMPILER_ID STREQUAL "Intel" OR CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" + OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM" OR CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM") set(INTEL_COMPILER ON) else() - if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(GNU_C_COMPILER ON) endif() if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") set(GNU_Fortran_COMPILER ON) endif() endif() +# CMake identifies IntelLLVM compilers only after 3.20 +if(NOT INTEL_COMPILER) + if(C_COMPILER_NAME STREQUAL "icx" OR C_COMPILER_NAME STREQUAL "icx.exe" + OR CXX_COMPILER_NAME STREQUAL "icpx" OR CXX_COMPILER_NAME STREQUAL "icx.exe" + OR Fortran_COMPILER_NAME STREQUAL "ifx" OR Fortran_COMPILER_NAME STREQUAL "ifx.exe") + set(INTEL_COMPILER ON) + endif() +endif() +# CMake supports IntelLLVM compilers only after 3.25.2 +if(CMAKE_VERSION VERSION_LESS "3.25.2") + if(C_COMPILER_NAME STREQUAL "icx" OR C_COMPILER_NAME STREQUAL "icx.exe" OR CXX_COMPILER_NAME STREQUAL "icx.exe") + list(APPEND INTEL_LLVM_COMPILERS_IN_USE "icx") + endif() + if(CXX_COMPILER_NAME STREQUAL "icpx") + list(APPEND INTEL_LLVM_COMPILERS_IN_USE "icpx") + endif() + if(Fortran_COMPILER_NAME STREQUAL "ifx" OR Fortran_COMPILER_NAME STREQUAL "ifx.exe") + list(APPEND INTEL_LLVM_COMPILERS_IN_USE "ifx") + endif() + if(INTEL_LLVM_COMPILERS_IN_USE) + list(JOIN INTEL_LLVM_COMPILERS_IN_USE ", " INTEL_LLVM_COMPILERS_IN_USE_COMMA) + mkl_message(STATUS "Upgrade to CMake version 3.25.2 or later for native support of Intel compiler(s) ${INTEL_LLVM_COMPILERS_IN_USE_COMMA}. You are running version ${CMAKE_VERSION}.") + endif() +endif() if(USE_MPI AND (C_COMPILER_NAME MATCHES "^mpi" OR Fortran_COMPILER_NAME MATCHES "^mpi")) set(USE_MPI_SCRIPT ON) @@ -221,13 +310,12 @@ endif() #================ # Extensions +set(SO_VER "2") +set(SYCL_SO_VER "5") if(UNIX) set(LIB_PREFIX "lib") set(LIB_EXT ".a") set(DLL_EXT ".so") - if(APPLE) - set(DLL_EXT ".dylib") - endif() set(LINK_PREFIX "-l") set(LINK_SUFFIX "") else() @@ -238,146 +326,194 @@ else() set(LINK_SUFFIX ".lib") endif() -# Set target system architecture -set(DEFAULT_MKL_ARCH intel64) -if(DPCPP_COMPILER OR PGI_COMPILER OR ENABLE_OMP_OFFLOAD OR USE_MPI) - set(MKL_ARCH_LIST intel64) -else() - set(MKL_ARCH_LIST ia32 intel64) -endif() -define_param(MKL_ARCH DEFAULT_MKL_ARCH MKL_ARCH_LIST) - #================ -#========== -# Setup MKL -#========== +#============= +# Setup oneMKL +#============= # Set MKL_ROOT directory if(NOT DEFINED MKL_ROOT) if(DEFINED ENV{MKLROOT}) set(MKL_ROOT $ENV{MKLROOT}) + # Verify that the version in MKL_ROOT is the same as MKL_VERSION + find_file(MKL_VERSION_H mkl_version.h + HINTS ${MKL_ROOT} + PATH_SUFFIXES include + NO_DEFAULT_PATH) + check_required_vars(MKL_VERSION_H) + file(READ ${MKL_VERSION_H} MKL_VERSION_H_CONTENT) + string(REGEX MATCH "__INTEL_MKL__ +([0-9]+)" MKL_VERSION_INFO ${MKL_VERSION_H_CONTENT}) + set(MKL_ROOT_MAJOR_VERSION ${CMAKE_MATCH_1}) + string(REGEX MATCH "__INTEL_MKL_UPDATE__ +([0-9]+)" MKL_VERSION_INFO ${MKL_VERSION_H_CONTENT}) + set(MKL_ROOT_UPDATE_VERSION ${CMAKE_MATCH_1}) + string(REGEX MATCH "__INTEL_MKL_PATCH__ +([0-9]+)" MKL_VERSION_INFO ${MKL_VERSION_H_CONTENT}) + set(MKL_ROOT_PATCH_VERSION ${CMAKE_MATCH_1}) + set(MKL_ROOT_VERSION ${MKL_ROOT_MAJOR_VERSION}.${MKL_ROOT_UPDATE_VERSION}.${MKL_ROOT_PATCH_VERSION}) + if(NOT MKL_ROOT_VERSION VERSION_EQUAL ${CMAKE_FIND_PACKAGE_NAME}_VERSION) + mkl_not_found_and_return("oneMKL ${MKL_ROOT_VERSION} specified by the environment variable MKLROOT \ + mismatches the found version ${${CMAKE_FIND_PACKAGE_NAME}_VERSION} \ + indicated by ${CMAKE_CURRENT_LIST_DIR}/MKLConfigVersion.cmake") + endif() else() get_filename_component(MKL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}" REALPATH) get_filename_component(MKL_ROOT "${MKL_CMAKE_PATH}/../../../" ABSOLUTE) - mkl_message(STATUS "MKL_ROOT ${MKL_ROOT}") endif() endif() string(REPLACE "\\" "/" MKL_ROOT ${MKL_ROOT}) +check_required_vars(MKL_ROOT) +mkl_message(STATUS "${CMAKE_FIND_PACKAGE_NAME}_VERSION: ${${CMAKE_FIND_PACKAGE_NAME}_VERSION}") +mkl_message(STATUS "MKL_ROOT: ${MKL_ROOT}") + +set(DEFAULT_MKL_ARCH intel64) +set(MKL_ARCH_LIST intel64) +if(NOT DEFINED MKL_ARCH) + set(MKL_ARCH intel64) +endif() +define_param(MKL_ARCH DEFAULT_MKL_ARCH MKL_ARCH_LIST) +check_required_vars(MKL_ARCH) # Define MKL_LINK +if(SYCL_COMPILER) + set(DEFAULT_MKL_SYCL_LINK dynamic) + set(MKL_SYCL_LINK_LIST static dynamic) + if(NOT DEFINED MKL_SYCL_LINK) + set(MKL_SYCL_LINK ${MKL_LINK}) + endif() + define_param(MKL_SYCL_LINK DEFAULT_MKL_SYCL_LINK MKL_SYCL_LINK_LIST STATUS) + if(NOT MKL_SYCL_LINK) + set(SYCL_COMPILER OFF) + mkl_message(STATUS "MKL::MKL_SYCL target will not be available.") + endif() +endif() set(DEFAULT_MKL_LINK dynamic) -if(DPCPP_COMPILER OR USE_MPI) +if(USE_MPI) set(MKL_LINK_LIST static dynamic) else() set(MKL_LINK_LIST static dynamic sdl) endif() define_param(MKL_LINK DEFAULT_MKL_LINK MKL_LINK_LIST) +check_required_vars(MKL_LINK) + +if(MKL_LINK STREQUAL "static" AND ENABLE_OMP_OFFLOAD) + mkl_message(WARNING "oneMKL SYCL static library is deprecated and will be removed in the oneMKL 2026.0 release") +elseif(MKL_SYCL_LINK AND MKL_SYCL_LINK STREQUAL "static") + mkl_message(STATUS "oneMKL SYCL static library is deprecated and will be removed in the oneMKL 2026.0 release") + add_custom_target(MKL_SYCL_STATIC_MESSAGE + COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red + "Warning: oneMKL SYCL static library is deprecated and will be removed in the oneMKL 2026.0 release") +endif() # Define MKL_INTERFACE -if(MKL_ARCH STREQUAL "intel64") - set(IFACE_TYPE intel) - if(GNU_Fortran_COMPILER) - set(IFACE_TYPE gf) +if(SYCL_COMPILER) + if(MKL_INTERFACE AND NOT DEFINED MKL_SYCL_INTERFACE_FULL) + set(MKL_SYCL_INTERFACE_FULL intel_${MKL_INTERFACE}) endif() - if(DPCPP_COMPILER) - if(MKL_INTERFACE) - set(MKL_INTERFACE_FULL intel_${MKL_INTERFACE}) - endif() - set(DEFAULT_MKL_INTERFACE intel_ilp64) - set(MKL_INTERFACE_LIST intel_ilp64) - else() - if(MKL_INTERFACE) - set(MKL_INTERFACE_FULL ${IFACE_TYPE}_${MKL_INTERFACE}) - endif() - set(DEFAULT_MKL_INTERFACE ${IFACE_TYPE}_ilp64) - set(MKL_INTERFACE_LIST ${IFACE_TYPE}_ilp64 ${IFACE_TYPE}_lp64) - endif() - define_param(MKL_INTERFACE_FULL DEFAULT_MKL_INTERFACE MKL_INTERFACE_LIST) -else() - if(WIN32) - set(MKL_INTERFACE_FULL intel_c) - elseif(NOT APPLE) - if(GNU_Fortran_COMPILER) - set(MKL_INTERFACE_FULL gf) - else() - set(MKL_INTERFACE_FULL intel) - endif() - else() - mkl_message(FATAL_ERROR "OSX does not support MKL_ARCH ia32.") + set(DEFAULT_MKL_SYCL_INTERFACE intel_ilp64) + set(MKL_SYCL_INTERFACE_LIST intel_lp64 intel_ilp64) + define_param(MKL_SYCL_INTERFACE_FULL DEFAULT_MKL_SYCL_INTERFACE MKL_SYCL_INTERFACE_LIST STATUS) + if(NOT MKL_SYCL_INTERFACE_FULL) + set(SYCL_COMPILER OFF) + mkl_message(STATUS "MKL::MKL_SYCL target will not be available.") endif() endif() + +set(IFACE_TYPE intel) +if(GNU_Fortran_COMPILER) + set(IFACE_TYPE gf) +endif() +if(MKL_INTERFACE) + set(MKL_INTERFACE_FULL ${IFACE_TYPE}_${MKL_INTERFACE}) +endif() +set(DEFAULT_MKL_INTERFACE ${IFACE_TYPE}_ilp64) +set(MKL_INTERFACE_LIST ${IFACE_TYPE}_ilp64 ${IFACE_TYPE}_lp64) +define_param(MKL_INTERFACE_FULL DEFAULT_MKL_INTERFACE MKL_INTERFACE_LIST) + +check_required_vars(MKL_INTERFACE_FULL) if(MKL_INTERFACE_FULL MATCHES "ilp64") set(MKL_INTERFACE "ilp64") else() set(MKL_INTERFACE "lp64") endif() -# Define MKL headers -find_path(MKL_H mkl.h +# Define oneMKL headers +find_path(MKL_INCLUDE mkl.h HINTS ${MKL_ROOT} - PATH_SUFFIXES include) -list(APPEND MKL_INCLUDE ${MKL_H}) + PATH_SUFFIXES include + NO_DEFAULT_PATH) +check_required_vars(MKL_INCLUDE) # Add pre-built F95 Interface Modules if(INTEL_COMPILER AND (ENABLE_BLAS95 OR ENABLE_LAPACK95)) - if(MKL_ARCH STREQUAL "intel64") - list(APPEND MKL_INCLUDE "${MKL_ROOT}/include/${MKL_ARCH}/${MKL_INTERFACE}") - else() - list(APPEND MKL_INCLUDE "${MKL_ROOT}/include/${MKL_ARCH}") - endif() + list(APPEND MKL_INCLUDE "${MKL_ROOT}/include/mkl/${MKL_ARCH}/${MKL_INTERFACE}") endif() # Define MKL_THREADING # All APIs support sequential threading +# SYCL API supports oneTBB and OpenMP threadings +if(SYCL_COMPILER) + set(MKL_SYCL_THREADING_LIST "sequential" "intel_thread" "tbb_thread") + set(DEFAULT_MKL_SYCL_THREADING tbb_thread) + if(NOT DEFINED MKL_SYCL_THREADING) + set(MKL_SYCL_THREADING ${MKL_THREADING}) + endif() + define_param(MKL_SYCL_THREADING DEFAULT_MKL_SYCL_THREADING MKL_SYCL_THREADING_LIST STATUS) + if(NOT MKL_SYCL_THREADING) + set(SYCL_COMPILER OFF) + mkl_message(STATUS "MKL::MKL_SYCL target will not be available.") + endif() +endif() +# C, Fortran API set(MKL_THREADING_LIST "sequential" "intel_thread" "tbb_thread") set(DEFAULT_MKL_THREADING intel_thread) -# DPC++ API supports TBB threading, but not OpenMP threading -if(DPCPP_COMPILER) - set(DEFAULT_MKL_THREADING tbb_thread) - list(REMOVE_ITEM MKL_THREADING_LIST intel_thread) -# C, Fortran API -elseif(PGI_COMPILER) - # PGI compiler supports PGI OpenMP threading, additionally - list(APPEND MKL_THREADING_LIST pgi_thread) - # PGI compiler does not support TBB threading - list(REMOVE_ITEM MKL_THREADING_LIST tbb_thread) - if(WIN32) - # PGI 19.10 and 20.1 on Windows, do not support Intel OpenMP threading - list(REMOVE_ITEM MKL_THREADING_LIST intel_thread) - set(DEFAULT_MKL_THREADING pgi_thread) - endif() -elseif(GNU_C_COMPILER OR GNU_Fortran_COMPILER OR CLANG_COMPILER) +if(GNU_C_COMPILER OR GNU_Fortran_COMPILER OR CLANG_COMPILER) list(APPEND MKL_THREADING_LIST gnu_thread) else() # Intel and Microsoft compilers # Nothing to do, only for completeness endif() define_param(MKL_THREADING DEFAULT_MKL_THREADING MKL_THREADING_LIST) +check_required_vars(MKL_THREADING) + +if(MKL_THREADING STREQUAL "sequential") + set(MKL_SDL_THREAD_ENV "SEQUENTIAL") +elseif(MKL_THREADING STREQUAL "intel_thread") + set(MKL_SDL_THREAD_ENV "INTEL") +elseif(MKL_THREADING STREQUAL "tbb_thread") + set(MKL_SDL_THREAD_ENV "TBB") +elseif(MKL_THREADING STREQUAL "gnu_thread") + set(MKL_SDL_THREAD_ENV "GNU") +endif() # Define MKL_MPI -set(DEFAULT_MKL_MPI intelmpi) -if(UNIX) - if(APPLE) - # Override defaults for OSX - set(DEFAULT_MKL_MPI mpich) - set(MKL_MPI_LIST mpich) - else() +if(SYCL_COMPILER) + set(MKL_SYCL_MPI_LIST intelmpi) + set(DEFAULT_MKL_SYCL_MPI intelmpi) + if(NOT DEFINED MKL_SYCL_MPI) + set(MKL_SYCL_MPI ${MKL_MPI}) + endif() + define_param(MKL_SYCL_MPI DEFAULT_MKL_SYCL_MPI MKL_SYCL_MPI_LIST STATUS) + if(NOT MKL_SYCL_MPI) + mkl_message(STATUS "MKL::MKL_SYCL_DISTRIBUTED_DFT target will not be available.") + endif() +endif() +if(NOT MKL_LINK STREQUAL "sdl") + set(DEFAULT_MKL_MPI intelmpi) + if(UNIX) set(MKL_MPI_LIST intelmpi openmpi mpich mpich2) + else() + # Windows + set(MKL_MPI_LIST intelmpi mshpc msmpi) + endif() + define_param(MKL_MPI DEFAULT_MKL_MPI MKL_MPI_LIST) + # MSMPI is now called MSHPC. MSMPI option exists for backward compatibility. + if(MKL_MPI STREQUAL "mshpc") + set(MKL_MPI msmpi) endif() + check_required_vars(MKL_MPI) else() - # Windows - set(MKL_MPI_LIST intelmpi mshpc msmpi) -endif() -define_param(MKL_MPI DEFAULT_MKL_MPI MKL_MPI_LIST) -# MSMPI is now called MSHPC. MSMPI option exists for backward compatibility. -if(MKL_MPI STREQUAL "mshpc") - set(MKL_MPI msmpi) + mkl_message(STATUS "MKL_MPI: Selected configuration is not supported by oneMKL cluster components") endif() -find_package_handle_standard_args(MKL REQUIRED_VARS MKL_MPI) - -# Checkpoint - Verify if required options are defined -find_package_handle_standard_args(MKL REQUIRED_VARS MKL_ROOT MKL_ARCH MKL_INCLUDE MKL_LINK MKL_THREADING MKL_INTERFACE_FULL) # Provides a list of IMPORTED targets for the project if(NOT DEFINED MKL_IMPORTED_TARGETS) @@ -389,57 +525,64 @@ set(MKL_C_COPT "") set(MKL_F_COPT "") set(MKL_SDL_COPT "") set(MKL_CXX_COPT "") -set(MKL_DPCPP_COPT "") -set(MKL_DPCPP_LOPT "") +set(MKL_SYCL_COPT "") +set(MKL_SYCL_LOPT "") set(MKL_OFFLOAD_COPT "") set(MKL_OFFLOAD_LOPT "") -set(MKL_SUPP_LINK "") # Other link options. Usually at the end of the link-line. -set(MKL_LINK_LINE) # For MPI only -set(MKL_ENV_PATH "") # Temporary variable to work with PATH -set(MKL_ENV "") # Exported environment variables +set(MKL_SUPP_LINK "") # Other link options. Usually at the end of the link-line. +set(MKL_SYCL_SUPP_LINK "") +set(MKL_LINK_LINE "") +set(MKL_SYCL_LINK_LINE "") +set(MKL_ENV_PATH "") # Temporary variable to work with PATH +set(MKL_ENV "") # Exported environment variables # Modify PATH variable to make it CMake-friendly set(OLD_PATH $ENV{PATH}) string(REPLACE ";" "\;" OLD_PATH "${OLD_PATH}") +# Modify LIBRARY_PATH variable to make it CMake-friendly +set(ENV_LIBRARY_PATH $ENV{LIBRARY_PATH}) +string(REPLACE ":" ";" ENV_LIBRARY_PATH "${ENV_LIBRARY_PATH}") # Compiler options if(GNU_C_COMPILER OR GNU_Fortran_COMPILER) - if(MKL_ARCH STREQUAL "ia32") - list(APPEND MKL_C_COPT -m32) - list(APPEND MKL_F_COPT -m32) - else() - list(APPEND MKL_C_COPT -m64) - list(APPEND MKL_F_COPT -m64) - endif() + list(APPEND MKL_C_COPT -m64) + list(APPEND MKL_CXX_COPT -m64) + list(APPEND MKL_F_COPT -m64) endif() # Additional compiler & linker options -if(CXX_COMPILER_NAME STREQUAL "icpx" OR CXX_COMPILER_NAME STREQUAL "icx.exe") - list(APPEND MKL_DPCPP_COPT "-fsycl") - list(APPEND MKL_DPCPP_LOPT "-fsycl") +if(SYCL_COMPILER) + list(APPEND MKL_SYCL_COPT "-fsycl") + list(APPEND MKL_SYCL_LOPT "-fsycl") + if(MKL_SYCL_LINK STREQUAL "static") + if(WIN32) + list(APPEND MKL_SYCL_LOPT "-fsycl-device-code-split:per_kernel") + else() + list(APPEND MKL_SYCL_LOPT "-fsycl-device-code-split=per_kernel") + endif() + endif() endif() -if(DPCPP_COMPILER OR ENABLE_OMP_OFFLOAD) +if(ENABLE_OMP_OFFLOAD) if(MKL_LINK STREQUAL "static") - list(APPEND MKL_DPCPP_LOPT "-fsycl-device-code-split=per_kernel") - list(APPEND MKL_OFFLOAD_LOPT "-fsycl-device-code-split=per_kernel") + if(WIN32) + list(APPEND MKL_OFFLOAD_LOPT "-fsycl-device-code-split:per_kernel") + else() + list(APPEND MKL_OFFLOAD_LOPT "-fsycl-device-code-split=per_kernel") + endif() endif() endif() # For OpenMP Offload if(ENABLE_OMP_OFFLOAD) if(WIN32) - if(OPENMP_VERSION VERSION_GREATER_EQUAL "5.1") - if("Fortran" IN_LIST CURR_LANGS) - list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64 -DONEMKL_USE_OPENMP_VERSION=202011) - else() - list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64 -Qopenmp-version:51 -DONEMKL_USE_OPENMP_VERSION=202011) - endif() - else() + if("Fortran" IN_LIST CURR_LANGS) list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64) + else() + list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64 -Qopenmp-version:51) endif() - # -MD and -MDd are manually added here because offload functionality uses DPC++ runtime. - if(CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo") + # -MD and -MDd are manually added here because offload functionality uses SYCL runtime. + if(CMAKE_BUILD_TYPE MATCHES "Debug") list(APPEND MKL_OFFLOAD_COPT -MDd) else() list(APPEND MKL_OFFLOAD_COPT -MD) @@ -447,14 +590,10 @@ if(ENABLE_OMP_OFFLOAD) list(APPEND MKL_OFFLOAD_LOPT -Qiopenmp -Qopenmp-targets:spir64 -fsycl) set(SKIP_LIBPATH ON) else() - if(OPENMP_VERSION VERSION_GREATER_EQUAL "5.1") - if("Fortran" IN_LIST CURR_LANGS) - list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64 -DONEMKL_USE_OPENMP_VERSION=202011) - else() - list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64 -fopenmp-version=51 -DONEMKL_USE_OPENMP_VERSION=202011) - endif() - else () + if("Fortran" IN_LIST CURR_LANGS) list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64) + else() + list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64 -fopenmp-version=51) endif() list(APPEND MKL_OFFLOAD_LOPT -fiopenmp -fopenmp-targets=spir64 -fsycl) if(APPLE) @@ -466,68 +605,92 @@ if(ENABLE_OMP_OFFLOAD) endif() # For selected Interface +if(SYCL_COMPILER) + if(MKL_INTERFACE STREQUAL "ilp64") + list(INSERT MKL_SYCL_COPT 0 "-DMKL_ILP64") + else() + mkl_message(STATUS "Experimental oneMKL Data Fitting SYCL API does not support LP64 on CPU") + endif() +endif() + if(MKL_INTERFACE_FULL) - if(MKL_ARCH STREQUAL "ia32") - if(GNU_Fortran_COMPILER) - set(MKL_SDL_IFACE_ENV "GNU") - endif() + if(GNU_Fortran_COMPILER) + set(MKL_SDL_IFACE_ENV "GNU,${MKL_INTERFACE}") else() - if(GNU_Fortran_COMPILER) - set(MKL_SDL_IFACE_ENV "GNU,${MKL_INTERFACE}") - else() - set(MKL_SDL_IFACE_ENV "${MKL_INTERFACE}") - endif() - if(MKL_INTERFACE STREQUAL "ilp64") - if("Fortran" IN_LIST CURR_LANGS) - if(INTEL_COMPILER) - if(WIN32) - list(APPEND MKL_F_COPT "-4I8") - else() - list(APPEND MKL_F_COPT "-i8") - endif() - elseif(GNU_Fortran_COMPILER) - list(APPEND MKL_F_COPT "-fdefault-integer-8") - elseif(PGI_COMPILER) + set(MKL_SDL_IFACE_ENV "${MKL_INTERFACE}") + endif() + if(MKL_INTERFACE STREQUAL "ilp64") + if("Fortran" IN_LIST CURR_LANGS) + if(INTEL_COMPILER) + if(WIN32) + list(APPEND MKL_F_COPT "-4I8") + else() list(APPEND MKL_F_COPT "-i8") endif() + elseif(GNU_Fortran_COMPILER) + list(APPEND MKL_F_COPT "-fdefault-integer-8") endif() - list(INSERT MKL_C_COPT 0 "-DMKL_ILP64") - list(INSERT MKL_SDL_COPT 0 "-DMKL_ILP64") - list(INSERT MKL_CXX_COPT 0 "-DMKL_ILP64") - list(INSERT MKL_OFFLOAD_COPT 0 "-DMKL_ILP64") - else() - # lp64 endif() + list(INSERT MKL_C_COPT 0 "-DMKL_ILP64") + list(INSERT MKL_SDL_COPT 0 "-DMKL_ILP64") + list(INSERT MKL_CXX_COPT 0 "-DMKL_ILP64") + list(INSERT MKL_OFFLOAD_COPT 0 "-DMKL_ILP64") + else() + # lp64 endif() if(MKL_SDL_IFACE_ENV) string(TOUPPER ${MKL_SDL_IFACE_ENV} MKL_SDL_IFACE_ENV) endif() endif() # MKL_INTERFACE_FULL -# All MKL Libraries -if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo") - set(MKL_SYCL mkl_sycld) -else() - set(MKL_SYCL mkl_sycl) +# All oneMKL Libraries +if(SYCL_COMPILER) + set(MKL_SYCL_IFACE_LIB mkl_${MKL_SYCL_INTERFACE_FULL}) + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug" AND MKL_SYCL_THREADING STREQUAL "tbb_thread") + set(MKL_SYCL_THREAD mkl_tbb_threadd) + else() + set(MKL_SYCL_THREAD mkl_${MKL_SYCL_THREADING}) + endif() endif() -set(MKL_IFACE_LIB mkl_${MKL_INTERFACE_FULL}) -set(MKL_CORE mkl_core) -if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo" AND MKL_THREADING STREQUAL "tbb_thread") - set(MKL_THREAD mkl_tbb_threadd) +set(MKL_SYCL) +set(MKL_SYCL_LIBS) +list(APPEND MKL_SYCL_LIBS mkl_sycl_blas) +list(APPEND MKL_SYCL_LIBS mkl_sycl_lapack) +list(APPEND MKL_SYCL_LIBS mkl_sycl_dft) +list(APPEND MKL_SYCL_LIBS mkl_sycl_sparse) +list(APPEND MKL_SYCL_LIBS mkl_sycl_data_fitting) +list(APPEND MKL_SYCL_LIBS mkl_sycl_rng) +list(APPEND MKL_SYCL_LIBS mkl_sycl_stats) +list(APPEND MKL_SYCL_LIBS mkl_sycl_vm) +if(NOT MKL_LINK STREQUAL "static") + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug") + list(TRANSFORM MKL_SYCL_LIBS APPEND "d") + endif() + list(APPEND MKL_SYCL ${MKL_SYCL_LIBS}) + # List for tracking incomplete onemKL package + set(MISSED_MKL_SYCL_LIBS) else() - set(MKL_THREAD mkl_${MKL_THREADING}) + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug") + set(MKL_SYCL mkl_sycld) + else() + set(MKL_SYCL mkl_sycl) + endif() endif() -set(MKL_SDL mkl_rt) -if(MKL_ARCH STREQUAL "ia32") - set(MKL_BLAS95 mkl_blas95) - set(MKL_LAPACK95 mkl_lapack95) +set(MKL_SYCL_DISTRIBUTED_DFT mkl_sycl_distributed_dft) + +set(MKL_IFACE_LIB mkl_${MKL_INTERFACE_FULL}) +set(MKL_CORE mkl_core) +if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug" AND MKL_THREADING STREQUAL "tbb_thread") + set(MKL_THREAD mkl_tbb_threadd) else() - set(MKL_BLAS95 mkl_blas95_${MKL_INTERFACE}) - set(MKL_LAPACK95 mkl_lapack95_${MKL_INTERFACE}) + set(MKL_THREAD mkl_${MKL_THREADING}) endif() +set(MKL_SDL mkl_rt) +set(MKL_BLAS95 mkl_blas95_${MKL_INTERFACE}) +set(MKL_LAPACK95 mkl_lapack95_${MKL_INTERFACE}) # BLACS set(MKL_BLACS mkl_blacs_${MKL_MPI}_${MKL_INTERFACE}) -if(UNIX AND NOT APPLE AND MKL_MPI MATCHES "mpich") +if(UNIX AND MKL_MPI MATCHES "mpich") # MPICH is compatible with INTELMPI Wrappers on Linux set(MKL_BLACS mkl_blacs_intelmpi_${MKL_INTERFACE}) endif() @@ -547,34 +710,51 @@ if(WIN32) set(MKL_BLACS_ENV INTELMPI) endif() endif() + # CDFT & SCALAPACK set(MKL_CDFT mkl_cdft_core) set(MKL_SCALAPACK mkl_scalapack_${MKL_INTERFACE}) - -if (UNIX) - if(NOT APPLE) - if(MKL_LINK STREQUAL "static") - set(START_GROUP "-Wl,--start-group") - set(END_GROUP "-Wl,--end-group") - if(DPCPP_COMPILER OR ENABLE_OMP_OFFLOAD) - set(EXPORT_DYNAMIC "-Wl,-export-dynamic") - endif() - elseif(MKL_LINK STREQUAL "dynamic") - set(MKL_RPATH "-Wl,-rpath=$") - if((GNU_Fortran_COMPILER OR PGI_COMPILER) AND "Fortran" IN_LIST CURR_LANGS) - set(NO_AS_NEEDED -Wl,--no-as-needed) - endif() - else() - set(MKL_RPATH "-Wl,-rpath=$") +if(UNIX) + if(MKL_LINK STREQUAL "static" OR MKL_SYCL_LINK STREQUAL "static") + set(START_GROUP "-Wl,--start-group") + set(END_GROUP "-Wl,--end-group") + if(SYCL_COMPILER) + set(SYCL_EXPORT_DYNAMIC "-Wl,-export-dynamic") + endif() + if(ENABLE_OMP_OFFLOAD) + set(EXPORT_DYNAMIC "-Wl,-export-dynamic") endif() endif() + if(MKL_LINK STREQUAL "dynamic") + set(MKL_RPATH "-Wl,-rpath=$") + if(GNU_Fortran_COMPILER AND "Fortran" IN_LIST CURR_LANGS) + set(NO_AS_NEEDED -Wl,--no-as-needed) + endif() + endif() + if(MKL_SYCL_LINK STREQUAL "dynamic") + set(MKL_SYCL_RPATH "-Wl,-rpath=$") + endif() + if(MKL_LINK STREQUAL "sdl") + set(MKL_RPATH "-Wl,-rpath=$") + endif() endif() # Create a list of requested libraries, based on input options (MKL_LIBRARIES) # Create full link-line in MKL_LINK_LINE +if(SYCL_COMPILER) + if(UNIX) + # SYCL MPI domain libraries + list(APPEND MKL_SYCL_LIBRARIES ${MKL_SYCL_DISTRIBUTED_DFT}) + endif() + # Main SYCL libraries + list(APPEND MKL_SYCL_LIBRARIES ${MKL_SYCL} ${MKL_SYCL_IFACE_LIB} ${MKL_SYCL_THREAD} ${MKL_CORE}) + list(TRANSFORM MKL_SYCL PREPEND MKL:: OUTPUT_VARIABLE MKL_SYCL_T) + list(APPEND MKL_SYCL_LINK_LINE ${MKL_SYCL_LOPT} ${SYCL_EXPORT_DYNAMIC} ${NO_AS_NEEDED} ${MKL_SYCL_RPATH} + ${MKL_SYCL_T} ${START_GROUP} MKL::${MKL_SYCL_IFACE_LIB} MKL::${MKL_SYCL_THREAD} MKL::${MKL_CORE} ${END_GROUP}) +endif() list(APPEND MKL_LINK_LINE $,${MKL_OFFLOAD_LOPT},> - $,${MKL_DPCPP_LOPT},> ${EXPORT_DYNAMIC} ${NO_AS_NEEDED} ${MKL_RPATH}) + ${EXPORT_DYNAMIC} ${NO_AS_NEEDED} ${MKL_RPATH}) if(ENABLE_BLAS95) list(APPEND MKL_LIBRARIES ${MKL_BLAS95}) list(APPEND MKL_LINK_LINE MKL::${MKL_BLAS95}) @@ -583,18 +763,23 @@ if(ENABLE_LAPACK95) list(APPEND MKL_LIBRARIES ${MKL_LAPACK95}) list(APPEND MKL_LINK_LINE MKL::${MKL_LAPACK95}) endif() -if(ENABLE_SCALAPACK) +if(NOT MKL_LINK STREQUAL "sdl") list(APPEND MKL_LIBRARIES ${MKL_SCALAPACK}) - list(APPEND MKL_LINK_LINE MKL::${MKL_SCALAPACK}) + if(ENABLE_SCALAPACK) + list(APPEND MKL_LINK_LINE MKL::${MKL_SCALAPACK}) + endif() endif() -if(DPCPP_COMPILER OR (ENABLE_OMP_OFFLOAD AND NOT MKL_LINK STREQUAL "sdl")) +if(ENABLE_OMP_OFFLOAD AND NOT MKL_LINK STREQUAL "sdl") list(APPEND MKL_LIBRARIES ${MKL_SYCL}) - list(APPEND MKL_LINK_LINE MKL::${MKL_SYCL}) + list(TRANSFORM MKL_SYCL PREPEND MKL:: OUTPUT_VARIABLE MKL_SYCL_T) + list(APPEND MKL_LINK_LINE ${MKL_SYCL_T}) endif() list(APPEND MKL_LINK_LINE ${START_GROUP}) -if(ENABLE_CDFT) +if(NOT MKL_LINK STREQUAL "sdl") list(APPEND MKL_LIBRARIES ${MKL_CDFT}) - list(APPEND MKL_LINK_LINE MKL::${MKL_CDFT}) + if(ENABLE_CDFT) + list(APPEND MKL_LINK_LINE MKL::${MKL_CDFT}) + endif() endif() if(MKL_LINK STREQUAL "sdl") list(APPEND MKL_LIBRARIES ${MKL_SDL}) @@ -603,27 +788,74 @@ else() list(APPEND MKL_LIBRARIES ${MKL_IFACE_LIB} ${MKL_THREAD} ${MKL_CORE}) list(APPEND MKL_LINK_LINE MKL::${MKL_IFACE_LIB} MKL::${MKL_THREAD} MKL::${MKL_CORE}) endif() -if(USE_MPI) +if(NOT MKL_LINK STREQUAL "sdl") list(APPEND MKL_LIBRARIES ${MKL_BLACS}) - list(APPEND MKL_LINK_LINE MKL::${MKL_BLACS}) + if(USE_MPI) + list(APPEND MKL_LINK_LINE MKL::${MKL_BLACS}) + endif() endif() list(APPEND MKL_LINK_LINE ${END_GROUP}) # Find all requested libraries -foreach(lib ${MKL_LIBRARIES}) +list(APPEND MKL_REQUESTED_LIBRARIES ${MKL_LIBRARIES}) +if(SYCL_COMPILER) + # If SYCL_COMPILER is still ON, MKL_SYCL_LINK and MKL_SYCL_IFACE_LIB are the same as MKL_LINK and MKL_IFACE_LIB. + # Hence we can combine the libraries and find them in the following for loop. + # Note that MKL_SYCL_THREADING and MKL_THREADING could be different because of the default value. + list(APPEND MKL_REQUESTED_LIBRARIES ${MKL_SYCL_LIBRARIES}) + list(REMOVE_DUPLICATES MKL_REQUESTED_LIBRARIES) +endif() +foreach(lib ${MKL_REQUESTED_LIBRARIES}) unset(${lib}_file CACHE) if(MKL_LINK STREQUAL "static" AND NOT ${lib} STREQUAL ${MKL_SDL}) find_library(${lib}_file ${LIB_PREFIX}${lib}${LIB_EXT} PATHS ${MKL_ROOT} - PATH_SUFFIXES "lib" "lib/${MKL_ARCH}") + PATH_SUFFIXES "lib" + NO_DEFAULT_PATH) add_library(MKL::${lib} STATIC IMPORTED) else() - find_library(${lib}_file NAMES ${LIB_PREFIX}${lib}${DLL_EXT} ${lib} + find_library(${lib}_file NAMES ${LIB_PREFIX}${lib}${DLL_EXT} + ${LIB_PREFIX}${lib}${DLL_EXT}.${SO_VER} + ${LIB_PREFIX}${lib}${DLL_EXT}.${SYCL_SO_VER} + ${lib} PATHS ${MKL_ROOT} - PATH_SUFFIXES "lib" "lib/${MKL_ARCH}") + PATH_SUFFIXES "lib" + NO_DEFAULT_PATH) add_library(MKL::${lib} SHARED IMPORTED) endif() - find_package_handle_standard_args(MKL REQUIRED_VARS ${lib}_file) + if(NOT MKL_LINK STREQUAL "static" AND (${lib} MATCHES "mkl_sycl" AND NOT ${lib} STREQUAL "mkl_sycl_distributed_dft") AND ${${lib}_file} STREQUAL "${lib}_file-NOTFOUND") + list(APPEND MISSED_MKL_SYCL_LIBS ${lib}) + set(MKL_SYCL_DOMAIN "") + string(REGEX REPLACE "mkl_sycl_" "" MKL_SYCL_DOMAIN ${lib}) + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug") + string(REGEX REPLACE "d$" "" MKL_SYCL_DOMAIN ${MKL_SYCL_DOMAIN}) + endif() + string(TOUPPER ${MKL_SYCL_DOMAIN} MKL_SYCL_DOMAIN) + if(MKL_SYCL_DOMAIN STREQUAL "DFT") + mkl_message(STATUS "Could NOT find ${lib} for targets MKL::MKL_SYCL::${MKL_SYCL_DOMAIN} and MKL::MKL_SYCL_DISTRIBUTED_DFT") + else() + mkl_message(STATUS "Could NOT find ${lib} for target MKL::MKL_SYCL::${MKL_SYCL_DOMAIN}") + endif() + else() + if(NOT USE_MPI AND (${lib} MATCHES "mkl_scalapack" OR ${lib} MATCHES "mkl_blacs" OR ${lib} MATCHES "mkl_cdft" OR ${lib} STREQUAL "mkl_sycl_distributed_dft") + AND ${${lib}_file} STREQUAL "${lib}_file-NOTFOUND") + if(${lib} MATCHES "mkl_scalapack") + mkl_message(STATUS "Could NOT find ${lib} for target MKL::MKL_SCALAPACK") + endif() + if(${lib} MATCHES "mkl_cdft") + mkl_message(STATUS "Could NOT find ${lib} for target MKL::MKL_CDFT") + endif() + if(${lib} MATCHES "mkl_blacs") + mkl_message(STATUS "Could NOT find ${lib} for targets MKL::MKL_SCALAPACK, MKL::MKL_CDFT, and MKL::MKL_BLACS") + endif() + if(${lib} STREQUAL "mkl_sycl_distributed_dft") + mkl_message(STATUS "Could NOT find ${lib} for target MKL::MKL_SYCL_DISTRIBUTED_DFT") + endif() + else() + check_required_vars(${lib}_file) + mkl_message(STATUS "Found ${${lib}_file}") + endif() + endif() # CMP0111, implemented in CMake 3.20+ requires a shared library target on Windows # to be defined with IMPLIB and LOCATION property. # It also requires a static library target to be defined with LOCATION property. @@ -632,10 +864,14 @@ foreach(lib ${MKL_LIBRARIES}) set_target_properties(MKL::${lib} PROPERTIES IMPORTED_IMPLIB "${${lib}_file}") # Find corresponding DLL set(MKL_DLL_GLOB ${lib}.*.dll) - file(GLOB MKL_DLL_FILE "${MKL_ROOT}/redist/${MKL_ARCH}/${MKL_DLL_GLOB}" + file(GLOB MKL_DLL_FILE "${MKL_ROOT}/bin/${MKL_DLL_GLOB}" + # Legacy oneAPI layout support below + "${MKL_ROOT}/redist/${MKL_ARCH}/${MKL_DLL_GLOB}" "${MKL_ROOT}/../redist/${MKL_ARCH}/${MKL_DLL_GLOB}" "${MKL_ROOT}/../redist/${MKL_ARCH}/mkl/${MKL_DLL_GLOB}" - "${MKL_ROOT}/bin/${MKL_DLL_GLOB}") + # Support for Conda directory layout + "${MKL_ROOT}/bin/${MKL_DLL_GLOB}" + ) if(NOT ${lib} STREQUAL ${MKL_IFACE_LIB} AND NOT ${lib} STREQUAL ${MKL_BLAS95} AND NOT ${lib} STREQUAL ${MKL_LAPACK95}) # Windows IFACE libs are static only list(LENGTH MKL_DLL_FILE MKL_DLL_FILE_LEN) if(MKL_DLL_FILE_LEN) @@ -647,9 +883,16 @@ foreach(lib ${MKL_LIBRARIES}) mkl_message(STATUS "Found DLL: ${MKL_DLL_FILE}") set_target_properties(MKL::${lib} PROPERTIES IMPORTED_LOCATION "${MKL_DLL_FILE}") else() - mkl_message(FATAL_ERROR "${MKL_DLL_GLOB} not found. MKL_ROOT was '${MKL_ROOT}'. MKL_DLL_FILE is '${MKL_DLL_FILE}'") + if(${lib} MATCHES "mkl_sycl" AND ${${lib}_file} STREQUAL "${lib}_file-NOTFOUND") + mkl_message(STATUS "Could NOT find ${MKL_DLL_GLOB} for target MKL::MKL_SYCL::${MKL_SYCL_DOMAIN}") + else() + mkl_not_found_and_return("${MKL_DLL_GLOB} not found") + endif() endif() endif() + if(NOT DEFINED MKL_DLL_DIR AND MKL_DLL_FILE) + get_filename_component(MKL_DLL_DIR ${MKL_DLL_FILE} DIRECTORY) + endif() else() set_target_properties(MKL::${lib} PROPERTIES IMPORTED_LOCATION "${${lib}_file}") endif() @@ -657,11 +900,28 @@ foreach(lib ${MKL_LIBRARIES}) endforeach() # Threading selection -if(MKL_THREADING) - if(MKL_THREADING STREQUAL "tbb_thread") - find_package(TBB REQUIRED CONFIG COMPONENTS tbb) - set(MKL_THREAD_LIB $) - set(MKL_SDL_THREAD_ENV "TBB") +if(MKL_THREADING STREQUAL "tbb_thread" OR MKL_SYCL_THREADING STREQUAL "tbb_thread") + set(TBB_FIND_RELEASE_ONLY TRUE) # Do not use tbb_debug + find_package(TBB CONFIG COMPONENTS tbb) + if(NOT TBB_tbb_FOUND) + if(MKL_THREADING STREQUAL "tbb_thread") + if(NOT MKL_LINK STREQUAL "sdl") + mkl_not_found_and_return("TBB not found for the specified MKL_THREADING: ${MKL_THREADING}") + elseif(WIN32) + mkl_message(WARNING "TBB not found for the specified MKL_THREADING: ${MKL_THREADING}. MKL_ENV will not contain paths for TBB.") + endif() + endif() + if(MKL_SYCL_THREADING STREQUAL "tbb_thread") + set(SYCL_COMPILER OFF) + mkl_message(WARNING "TBB not found for the specified MKL_SYCL_THREADING: ${MKL_SYCL_THREADING}. MKL::MKL_SYCL target will not be available.") + endif() + else() # TBB found + if(MKL_THREADING STREQUAL "tbb_thread") + set(MKL_THREAD_LIB $) + endif() + if(MKL_SYCL_THREADING STREQUAL "tbb_thread") + set(MKL_SYCL_THREAD_LIB $) + endif() get_property(TBB_LIB TARGET TBB::tbb PROPERTY IMPORTED_LOCATION_RELEASE) get_filename_component(TBB_LIB_DIR ${TBB_LIB} DIRECTORY) if(UNIX) @@ -670,147 +930,243 @@ if(MKL_THREADING) else() set(TBB_LINK "-Wl,-rpath,${TBB_LIB_DIR} -L${TBB_LIB_DIR} -ltbb") endif() - list(APPEND MKL_SUPP_LINK ${TBB_LINK}) - if(APPLE) - list(APPEND MKL_SUPP_LINK -lc++) - else() - list(APPEND MKL_SUPP_LINK -lstdc++) + if(MKL_THREADING STREQUAL "tbb_thread") + list(APPEND MKL_SUPP_LINK ${TBB_LINK}) + endif() + if(MKL_SYCL_THREADING STREQUAL "tbb_thread") + list(APPEND MKL_SYCL_SUPP_LINK ${TBB_LINK}) endif() endif() - if(WIN32 OR APPLE) + if(WIN32) set(MKL_ENV_PATH ${TBB_LIB_DIR}) endif() - elseif(MKL_THREADING MATCHES "_thread") - if(MKL_THREADING STREQUAL "pgi_thread") - list(APPEND MKL_SUPP_LINK -mp -pgf90libs) - set(MKL_SDL_THREAD_ENV "PGI") - elseif(MKL_THREADING STREQUAL "gnu_thread") + endif() + + if(UNIX AND MKL_THREADING STREQUAL "tbb_thread") + list(APPEND MKL_SUPP_LINK -lstdc++) + # force clang to link libstdc++ + if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + list(APPEND MKL_SUPP_LINK -stdlib=libstdc++ ) + endif() + endif() +endif() +if(NOT MKL_THREADING STREQUAL "tbb_thread" AND MKL_THREADING MATCHES "_thread") + if(MKL_THREADING STREQUAL "gnu_thread") + if(NOT MKL_LINK STREQUAL "sdl") list(APPEND MKL_SUPP_LINK -lgomp) - set(MKL_SDL_THREAD_ENV "GNU") + endif() + else() + # intel_thread + if(UNIX) + set(MKL_OMP_LIB iomp5) + set(LIB_EXT ".so") else() - # intel_thread - if(UNIX) - set(MKL_OMP_LIB iomp5) - set(LIB_EXT ".so") - if(APPLE) - set(LIB_EXT ".dylib") - endif() + set(MKL_OMP_LIB libiomp5md) + endif() + set(OMP_LIBNAME ${LIB_PREFIX}${MKL_OMP_LIB}${LIB_EXT}) + + find_library(OMP_LIBRARY ${OMP_LIBNAME} + HINTS $ENV{LIB} ${ENV_LIBRARY_PATH} $ENV{MKLROOT} ${MKL_ROOT} $ENV{CMPLR_ROOT} + PATH_SUFFIXES "lib" "lib/${MKL_ARCH}" + "lib/${MKL_ARCH}_lin" "lib/${MKL_ARCH}_win" + "linux/compiler/lib/${MKL_ARCH}" + "linux/compiler/lib/${MKL_ARCH}_lin" + "windows/compiler/lib/${MKL_ARCH}" + "windows/compiler/lib/${MKL_ARCH}_win" + "../compiler/lib/${MKL_ARCH}_lin" "../compiler/lib/${MKL_ARCH}_win" + "../compiler/lib/${MKL_ARCH}" "../compiler/lib" "compiler/lib" + "../../compiler/latest/lib" + "../../compiler/latest/linux/compiler/lib/${MKL_ARCH}" + "../../compiler/latest/linux/compiler/lib/${MKL_ARCH}_lin" + "../../compiler/latest/windows/compiler/lib/${MKL_ARCH}" + "../../compiler/latest/windows/compiler/lib/${MKL_ARCH}_win" + NO_DEFAULT_PATH) + if(WIN32) + set(OMP_DLLNAME ${LIB_PREFIX}${MKL_OMP_LIB}.dll) + find_path(OMP_DLL_DIR ${OMP_DLLNAME} + HINTS $ENV{LIB} ${ENV_LIBRARY_PATH} $ENV{MKLROOT} ${MKL_ROOT} $ENV{CMPLR_ROOT} + PATH_SUFFIXES "bin" + # Legacy layout support for oneMKL + "redist/${MKL_ARCH}" + "redist/${MKL_ARCH}_win" "redist/${MKL_ARCH}_win/compiler" + "../redist/${MKL_ARCH}/compiler" "../compiler/lib" + "../../compiler/latest/bin" + "../../compiler/latest/windows/redist/${MKL_ARCH}_win" + "../../compiler/latest/windows/redist/${MKL_ARCH}_win/compiler" + "../../compiler/latest/windows/compiler/redist/${MKL_ARCH}_win" + "../../compiler/latest/windows/compiler/redist/${MKL_ARCH}_win/compiler" + NO_DEFAULT_PATH) + if(MKL_LINK STREQUAL "sdl" AND NOT OMP_DLL_DIR) + mkl_message(WARNING "${OMP_DLLNAME} not found. MKL_ENV will not contain paths for ${OMP_DLLNAME}.") else() - set(MKL_OMP_LIB libiomp5md) - endif() - set(MKL_SDL_THREAD_ENV "INTEL") - set(OMP_LIBNAME ${LIB_PREFIX}${MKL_OMP_LIB}${LIB_EXT}) - - find_library(OMP_LIBRARY ${OMP_LIBNAME} - HINTS $ENV{LIB} $ENV{LIBRARY_PATH} $ENV{MKLROOT} ${MKL_ROOT} ${CMPLR_ROOT} - PATH_SUFFIXES "lib" "lib/${MKL_ARCH}" - "lib/${MKL_ARCH}_lin" "lib/${MKL_ARCH}_win" - "linux/compiler/lib/${MKL_ARCH}" - "linux/compiler/lib/${MKL_ARCH}_lin" - "windows/compiler/lib/${MKL_ARCH}" - "windows/compiler/lib/${MKL_ARCH}_win" - "../compiler/lib/${MKL_ARCH}_lin" "../compiler/lib/${MKL_ARCH}_win" - "../compiler/lib/${MKL_ARCH}" "../compiler/lib" - "../../compiler/latest/linux/compiler/lib/${MKL_ARCH}" - "../../compiler/latest/linux/compiler/lib/${MKL_ARCH}_lin" - "../../compiler/latest/windows/compiler/lib/${MKL_ARCH}" - "../../compiler/latest/windows/compiler/lib/${MKL_ARCH}_win" - "../../compiler/latest/mac/compiler/lib") - if(WIN32) - set(OMP_DLLNAME ${LIB_PREFIX}${MKL_OMP_LIB}.dll) - find_path(OMP_DLL_DIR ${OMP_DLLNAME} - HINTS $ENV{LIB} $ENV{LIBRARY_PATH} $ENV{MKLROOT} ${MKL_ROOT} ${CMPLR_ROOT} - PATH_SUFFIXES "redist/${MKL_ARCH}" - "redist/${MKL_ARCH}_win" "redist/${MKL_ARCH}_win/compiler" - "../redist/${MKL_ARCH}/compiler" "../compiler/lib" - "../../compiler/latest/windows/redist/${MKL_ARCH}_win" - "../../compiler/latest/windows/redist/${MKL_ARCH}_win/compiler" - "../../compiler/latest/windows/compiler/redist/${MKL_ARCH}_win" - "../../compiler/latest/windows/compiler/redist/${MKL_ARCH}_win/compiler") - find_package_handle_standard_args(MKL REQUIRED_VARS OMP_DLL_DIR) + check_required_vars(OMP_DLL_DIR) set(MKL_ENV_PATH "${OMP_DLL_DIR}") endif() + endif() - if(WIN32 AND SKIP_LIBPATH) - # Only for Intel OpenMP Offload - set(OMP_LINK "libiomp5md.lib") - else() - set(OMP_LINK "${OMP_LIBRARY}") - if(CMAKE_C_COMPILER_ID STREQUAL "PGI" OR CMAKE_Fortran_COMPILER_ID STREQUAL "PGI") - # Disable PGI OpenMP runtime for correct work of Intel OpenMP runtime - list(APPEND MKL_SUPP_LINK -nomp) - endif() + if(WIN32 AND SKIP_LIBPATH) + # Only for Intel OpenMP Offload + set(OMP_LINK "libiomp5md.lib") + else() + set(OMP_LINK "${OMP_LIBRARY}") + endif() + + if(NOT MKL_LINK STREQUAL "sdl") + check_required_vars(OMP_LIBRARY OMP_LINK) + mkl_message(STATUS "Found ${OMP_LIBRARY}") + if(MKL_SYCL_THREADING STREQUAL "intel_thread") + set(MKL_SYCL_THREAD_LIB ${OMP_LINK}) endif() - find_package_handle_standard_args(MKL REQUIRED_VARS OMP_LIBRARY OMP_LINK) set(MKL_THREAD_LIB ${OMP_LINK}) endif() - else() - # Sequential threading - set(MKL_SDL_THREAD_ENV "SEQUENTIAL") + endif() endif() # MKL_THREADING -if (UNIX) +if(UNIX) + if(SYCL_COMPILER) + list(APPEND MKL_SYCL_SUPP_LINK -lm -ldl -lpthread) + endif() list(APPEND MKL_SUPP_LINK -lm -ldl -lpthread) endif() -if(DPCPP_COMPILER OR ENABLE_OMP_OFFLOAD) - if(WIN32) - # Detect sycl library version - if(NOT DEFINED SYCL_LIB_VER_CACHE) - set(SYCL_LIB_VER "") - find_library(SYCL_LIB_DIR ${LIB_PREFIX}sycl${LIB_EXT} - HINTS $ENV{LIB} $ENV{CMPLR_ROOT} - PATH_SUFFIXES "windows/lib") - if(NOT SYCL_LIB_DIR) - foreach(ver RANGE 6 99) - find_library(SYCL_LIB_DIR ${LIB_PREFIX}sycl${ver}${LIB_EXT} - HINTS $ENV{LIB} $ENV{CMPLR_ROOT} - PATH_SUFFIXES "windows/lib") - if(SYCL_LIB_DIR) - set(SYCL_LIB_VER ${ver}) - break() - endif() - endforeach() - endif() - set(SYCL_LIB_VER_CACHE ${SYCL_LIB_VER} CACHE STRING "") +if(SYCL_COMPILER OR ENABLE_OMP_OFFLOAD) + if(SYCL_COMPILER) + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug") + list(APPEND MKL_SYCL_SUPP_LINK ${LINK_PREFIX}sycld${LINK_SUFFIX}) + else() + list(APPEND MKL_SYCL_SUPP_LINK ${LINK_PREFIX}sycl${LINK_SUFFIX}) endif() - - if(CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo") - list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${SYCL_LIB_VER_CACHE}d${LINK_SUFFIX}) + list(APPEND MKL_SYCL_SUPP_LINK ${LINK_PREFIX}OpenCL${LINK_SUFFIX}) + endif() + if(ENABLE_OMP_OFFLOAD) + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug") + list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycld${LINK_SUFFIX}) else() - list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${SYCL_LIB_VER_CACHE}${LINK_SUFFIX}) + list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${LINK_SUFFIX}) endif() - else() - list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${LINK_SUFFIX}) + list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}OpenCL${LINK_SUFFIX}) endif() - list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}OpenCL${LINK_SUFFIX}) endif() # Setup link types based on input options set(LINK_TYPES "") -if(DPCPP_COMPILER) - add_library(MKL::MKL_DPCPP INTERFACE IMPORTED GLOBAL) - target_compile_options(MKL::MKL_DPCPP INTERFACE ${MKL_DPCPP_COPT}) - target_link_libraries(MKL::MKL_DPCPP INTERFACE ${MKL_LINK_LINE} ${MKL_THREAD_LIB} ${MKL_SUPP_LINK}) - list(APPEND LINK_TYPES MKL::MKL_DPCPP) +if(SYCL_COMPILER OR ENABLE_OMP_OFFLOAD) +# Remove missed mkl_sycl libraries in case of incomplete oneMKL package + if(MISSED_MKL_SYCL_LIBS) + list(REMOVE_ITEM MKL_SYCL_LIBS ${MISSED_MKL_SYCL_LIBS}) + list(TRANSFORM MISSED_MKL_SYCL_LIBS PREPEND MKL:: OUTPUT_VARIABLE MISSED_MKL_SYCL_TARGETS) + list(REMOVE_ITEM MKL_SYCL_LINK_LINE ${MISSED_MKL_SYCL_TARGETS}) + list(REMOVE_ITEM MKL_LINK_LINE ${MISSED_MKL_SYCL_TARGETS}) + endif() +endif() + +if(SYCL_COMPILER) + if(NOT TARGET MKL::MKL_SYCL) + add_library(MKL::MKL_SYCL INTERFACE IMPORTED GLOBAL) + add_library(MKL::MKL_DPCPP ALIAS MKL::MKL_SYCL) + add_dependencies(MKL::MKL_SYCL MKL_SYCL_STATIC_MESSAGE) + endif() + target_compile_options(MKL::MKL_SYCL INTERFACE $<$:${MKL_SYCL_COPT}>) + target_link_libraries(MKL::MKL_SYCL INTERFACE ${MKL_SYCL_LINK_LINE} ${MKL_SYCL_THREAD_LIB} ${MKL_SYCL_SUPP_LINK}) + list(APPEND LINK_TYPES MKL::MKL_SYCL) + foreach(lib ${MKL_SYCL_LIBS}) + set(MKL_SYCL_DOMAIN "") + string(REGEX REPLACE "mkl_sycl_" "" MKL_SYCL_DOMAIN ${lib}) + if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug") + string(REGEX REPLACE "d$" "" MKL_SYCL_DOMAIN ${MKL_SYCL_DOMAIN}) + endif() + string(TOUPPER ${MKL_SYCL_DOMAIN} MKL_SYCL_DOMAIN) + add_library(MKL::MKL_SYCL::${MKL_SYCL_DOMAIN} INTERFACE IMPORTED GLOBAL) + add_dependencies(MKL::MKL_SYCL::${MKL_SYCL_DOMAIN} MKL_SYCL_STATIC_MESSAGE) + target_compile_options(MKL::MKL_SYCL::${MKL_SYCL_DOMAIN} INTERFACE $<$:${MKL_SYCL_COPT}>) + # Only dynamic link has domain specific libraries + # Domain specific targets still use mkl_sycl for static + if(NOT MKL_LINK STREQUAL "static") + list(TRANSFORM MKL_SYCL_LINK_LINE REPLACE ".*mkl_sycl.*" "TBD") + list(REMOVE_DUPLICATES MKL_SYCL_LINK_LINE) + list(TRANSFORM MKL_SYCL_LINK_LINE REPLACE "TBD" "MKL::${lib}") + endif() + target_link_libraries(MKL::MKL_SYCL::${MKL_SYCL_DOMAIN} INTERFACE ${MKL_SYCL_LINK_LINE} ${MKL_SYCL_THREAD_LIB} ${MKL_SYCL_SUPP_LINK}) + list(APPEND LINK_TYPES MKL::MKL_SYCL::${MKL_SYCL_DOMAIN}) + endforeach(lib) # MKL_SYCL_LIBS + if(UNIX AND NOT TARGET MKL::MKL_SYCL_DISTRIBUTED_DFT AND TARGET MKL::MKL_SYCL::DFT AND MKL_SYCL_MPI + AND NOT ${${MKL_SYCL_DISTRIBUTED_DFT}_file} STREQUAL "${MKL_SYCL_DISTRIBUTED_DFT}_file-NOTFOUND") + add_library(MKL::MKL_SYCL_DISTRIBUTED_DFT INTERFACE IMPORTED GLOBAL) + target_compile_options(MKL::MKL_SYCL_DISTRIBUTED_DFT INTERFACE $<$:${MKL_SYCL_COPT}>) + target_link_libraries(MKL::MKL_SYCL_DISTRIBUTED_DFT INTERFACE MKL::${MKL_SYCL_DISTRIBUTED_DFT} MKL::MKL_SYCL::DFT) + list(APPEND LINK_TYPES MKL::MKL_SYCL_DISTRIBUTED_DFT) + endif() endif() # Single target for all C, Fortran link-lines -add_library(MKL::MKL INTERFACE IMPORTED GLOBAL) +if(NOT TARGET MKL::MKL) + add_library(MKL::MKL INTERFACE IMPORTED GLOBAL) +endif() target_compile_options(MKL::MKL INTERFACE - $<$,C>:${MKL_C_COPT}> - $<$,Fortran>:${MKL_F_COPT}> - $<$,CXX>:${MKL_CXX_COPT}> + $<$:${MKL_C_COPT}> + $<$:${MKL_F_COPT}> + $<$:${MKL_CXX_COPT}> $,${MKL_OFFLOAD_COPT},>) target_link_libraries(MKL::MKL INTERFACE ${MKL_LINK_LINE} ${MKL_THREAD_LIB} ${MKL_SUPP_LINK}) list(APPEND LINK_TYPES MKL::MKL) +# Define cluster components +if(NOT ${${MKL_CDFT}_file} STREQUAL "${MKL_CDFT}_file-NOTFOUND") + if(NOT TARGET MKL::MKL_BLACS) + add_library(MKL::MKL_BLACS INTERFACE IMPORTED GLOBAL) + endif() + if(MKL_LINK STREQUAL "static") + # Static link requires duplications for cross library dependency resolutions + target_link_libraries(MKL::MKL_BLACS INTERFACE ${${MKL_IFACE_LIB}_file} ${${MKL_THREAD}_file} ${${MKL_CORE}_file} ${${MKL_BLACS}_file}) + target_link_libraries(MKL::MKL_BLACS INTERFACE ${${MKL_IFACE_LIB}_file} ${${MKL_THREAD}_file} ${${MKL_CORE}_file} ${${MKL_BLACS}_file}) + target_link_libraries(MKL::MKL_BLACS INTERFACE MKL::MKL) + else() + target_link_libraries(MKL::MKL_BLACS INTERFACE MKL::MKL MKL::${MKL_BLACS}) + endif() +endif() +if(NOT ${${MKL_CDFT}_file} STREQUAL "${MKL_CDFT}_file-NOTFOUND" + AND NOT ${${MKL_BLACS}_file} STREQUAL "${MKL_BLACS}_file-NOTFOUND") + if(NOT TARGET MKL::MKL_CDFT) + add_library(MKL::MKL_CDFT INTERFACE IMPORTED GLOBAL) + endif() + if(UNIX AND MKL_LINK STREQUAL "static") + # Static link requires duplications for cross library dependency resolutions + target_link_libraries(MKL::MKL_CDFT INTERFACE ${${MKL_CDFT}_file} ${${MKL_IFACE_LIB}_file} ${${MKL_THREAD}_file} ${${MKL_CORE}_file} ${${MKL_BLACS}_file}) + target_link_libraries(MKL::MKL_CDFT INTERFACE ${${MKL_CDFT}_file} ${${MKL_IFACE_LIB}_file} ${${MKL_THREAD}_file} ${${MKL_CORE}_file} ${${MKL_BLACS}_file}) + target_link_libraries(MKL::MKL_CDFT INTERFACE MKL::MKL) + else() + target_link_libraries(MKL::MKL_CDFT INTERFACE MKL::${MKL_CDFT} MKL::MKL_BLACS) + endif() +endif() +if(NOT ${${MKL_SCALAPACK}_file} STREQUAL "${MKL_SCALAPACK}_file-NOTFOUND" + AND NOT ${${MKL_BLACS}_file} STREQUAL "${MKL_BLACS}_file-NOTFOUND") + if(NOT TARGET MKL::MKL_SCALAPACK) + add_library(MKL::MKL_SCALAPACK INTERFACE IMPORTED GLOBAL) + endif() + if(UNIX AND MKL_LINK STREQUAL "static") + # Static link requires duplications for cross library dependency resolutions + target_link_libraries(MKL::MKL_SCALAPACK INTERFACE ${${MKL_SCALAPACK}_file} ${${MKL_IFACE_LIB}_file} ${${MKL_THREAD}_file} ${${MKL_CORE}_file} ${${MKL_BLACS}_file}) + target_link_libraries(MKL::MKL_SCALAPACK INTERFACE ${${MKL_SCALAPACK}_file} ${${MKL_IFACE_LIB}_file} ${${MKL_THREAD}_file} ${${MKL_CORE}_file} ${${MKL_BLACS}_file}) + target_link_libraries(MKL::MKL_SCALAPACK INTERFACE MKL::MKL) + else() + target_link_libraries(MKL::MKL_SCALAPACK INTERFACE MKL::${MKL_SCALAPACK} MKL::MKL_BLACS) + endif() +endif() + foreach(link ${LINK_TYPES}) # Set properties on all INTERFACE targets target_include_directories(${link} BEFORE INTERFACE "${MKL_INCLUDE}") list(APPEND MKL_IMPORTED_TARGETS ${link}) endforeach(link) # LINK_TYPES +# oneMKL could be added to implicit directories when it's defined in CPATH +# In order to avoid dependency on CPATH, remove oneMKL from implicit directories +if(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES) + list(REMOVE_ITEM CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "${MKL_INCLUDE}") +endif() +if(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES) + list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "${MKL_INCLUDE}") +endif() if(MKL_LINK STREQUAL "sdl") list(APPEND MKL_ENV "MKL_INTERFACE_LAYER=${MKL_SDL_IFACE_ENV}" "MKL_THREADING_LAYER=${MKL_SDL_THREAD_ENV}") @@ -819,33 +1175,159 @@ if(WIN32 AND NOT MKL_LINK STREQUAL "static") list(APPEND MKL_ENV "MKL_BLACS_MPI=${MKL_BLACS_ENV}") endif() -# Add MKL dynamic libraries if RPATH is not defined on Unix +# Add oneMKL dynamic libraries if RPATH is not defined on Unix if(UNIX AND CMAKE_SKIP_BUILD_RPATH) if(MKL_LINK STREQUAL "sdl") set(MKL_LIB_DIR $) else() set(MKL_LIB_DIR $) endif() - if(APPLE) - list(APPEND MKL_ENV "DYLD_LIBRARY_PATH=${MKL_LIB_DIR}\;$ENV{DYLD_LIBRARY_PATH}") - else() - list(APPEND MKL_ENV "LD_LIBRARY_PATH=${MKL_LIB_DIR}\;$ENV{LD_LIBRARY_PATH}") - endif() + list(APPEND MKL_ENV "LD_LIBRARY_PATH=${MKL_LIB_DIR}\;$ENV{LD_LIBRARY_PATH}") endif() -# Add MKL dynamic libraries to PATH on Windows +# Add oneMKL dynamic libraries to PATH on Windows if(WIN32 AND NOT MKL_LINK STREQUAL "static") - get_filename_component(MKL_DLL_DIR ${MKL_DLL_FILE} DIRECTORY) set(MKL_ENV_PATH "${MKL_DLL_DIR}\;${MKL_ENV_PATH}") endif() if(MKL_ENV_PATH) list(APPEND MKL_ENV "PATH=${MKL_ENV_PATH}\;${OLD_PATH}") - if(APPLE) - list(APPEND MKL_ENV "DYLD_LIBRARY_PATH=${MKL_ENV_PATH}\:${OLD_PATH}") +endif() + +# Additional checks +if(ENABLE_TRY_SYCL_COMPILE AND "CXX" IN_LIST CURR_LANGS AND SYCL_COMPILER AND MKL_SYCL_LIBS) + # The check is run only once with the result cached + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_LIBRARIES MKL::MKL_SYCL) + foreach(lib IN LISTS MKL_SYCL_LIBS) + if(lib STREQUAL "mkl_sycl_blas") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/blas.hpp\" + + int main() + { + sycl::queue q; + float x[1], res[1]; + oneapi::mkl::blas::asum(q, 1, x, 1, res); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_lapack") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/lapack.hpp\" + + int main() + { + sycl::queue q; + float a[1], scratchpad[1]; + std::int64_t ipiv[1]; + oneapi::mkl::lapack::getrf(q, 1, 1, a, 1, ipiv, scratchpad, 1); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_dft") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/dft.hpp\" + + int main() + { + namespace dft = oneapi::mkl::dft; + dft::descriptor desc(1); + sycl::queue q; + desc.commit(q); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_sparse") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/spblas.hpp\" + + int main() + { + sycl::queue q; + oneapi::mkl::sparse::matrix_handle_t handle; + float x[1], y[1]; + oneapi::mkl::sparse::gemv(q, oneapi::mkl::transpose::nontrans, 1, handle, x, 1, y); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_data_fitting") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/experimental/data_fitting.hpp\" + + int main() + { + namespace df = oneapi::mkl::experimental::data_fitting; + sycl::queue q; + df::spline spl(q); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_rng") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/rng.hpp\" + + int main() + { + sycl::queue q; + oneapi::mkl::rng::default_engine engine(q, 0); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_stats") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/stats.hpp\" + + int main() + { + namespace stats = oneapi::mkl::stats; + sycl::queue q; + float x[1], min[1]; + stats::min(q, stats::make_dataset(1, 1, x), min); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + elseif(lib STREQUAL "mkl_sycl_vm") + check_cxx_source_compiles(" + #include + #include \"oneapi/mkl/vm.hpp\" + + int main() + { + sycl::queue q; + float a[1], b[1], y[1]; + oneapi::mkl::vm::add(q, 1, a, b, y); + return 0; + } + " MKL_TRY_SYCL_COMPILE) + break() + endif() + endforeach() + unset(CMAKE_REQUIRED_LIBRARIES) + if(NOT MKL_TRY_SYCL_COMPILE) + mkl_not_found_and_return("The SYCL compiler \"${CMAKE_CXX_COMPILER}\" is not able to \ + compile a simple test program that calls a oneMKL SYCL API. \ + See \"CMakeError.log\" for details. Besides environment issues, \ + this could be caused by a compiler version that is incompatible \ + with oneMKL ${${CMAKE_FIND_PACKAGE_NAME}_VERSION}.") endif() endif() unset(MKL_DLL_FILE) +unset(MKL_LIBRARIES) -endif() # MKL_LIBRARIES +endif() # MKL::MKL diff --git a/dpnp/backend/cmake/Modules/TBBConfig.cmake b/dpnp/backend/cmake/Modules/TBBConfig.cmake index ab85e6fc2898..4955dc557149 100644 --- a/dpnp/backend/cmake/Modules/TBBConfig.cmake +++ b/dpnp/backend/cmake/Modules/TBBConfig.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2025 Intel Corporation +# Copyright (c) 2017-2023 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -50,123 +50,62 @@ endif() unset(_tbbmalloc_proxy_ix) if (CMAKE_SIZEOF_VOID_P STREQUAL "8") - set(_tbb_subdir intel64/gcc4.8) + set(_tbb_intel_arch intel64) else () - set(_tbb_subdir ia32/gcc4.8) -endif() - -if (UNIX) - set(_tbb_lib_ext ".so") - set(_tbb_lib_prefix "lib") - set(_tbb_lib_dir_conda "lib") - set(_bin_version "") -elseif (WIN32) - set(_bin_version "") - set(_tbb_lib_prefix "") - set(_tbb_lib_ext ".dll") - set(_tbb_impllib_ext ".lib") - set(_tbb_lib_dir_conda "bin") - set(_tbb_impllib_dir_conda "lib") -else() - message(FATAL_ERROR "Unsupported platform. Only Unix and Windows are supported.") + set(_tbb_intel_arch ia32) + set(_tbb_arch_suffix 32) endif() +set(_tbb_subdir gcc4.8) foreach (_tbb_component ${TBB_FIND_COMPONENTS}) + unset(_tbb_release_dll CACHE) + unset(_tbb_debug_dll CACHE) + unset(_tbb_release_lib CACHE) + unset(_tbb_debug_lib CACHE) + set(TBB_${_tbb_component}_FOUND 0) -if(WIN32) - unset(_bin_version) - if (_tbb_component STREQUAL tbb) - set(_bin_version ${_tbb_bin_version}) - endif() -endif() - if(UNIX) - find_library(_tbb_release_lib - NAMES ${_tbb_lib_prefix}${_tbb_component}${_bin_version}${_tbb_lib_ext} - PATHS ${_tbb_root} - HINTS ENV TBB_ROOT_HINT - PATH_SUFFIXES "${_tbb_lib_dir_conda}" "lib/${_tbb_subdir}") - - else() - find_file(_tbb_release_lib - NAMES ${_tbb_lib_prefix}${_tbb_component}${_bin_version}${_tbb_lib_ext} - PATHS ${_tbb_root} - HINTS ENV TBB_ROOT_HINT - PATH_SUFFIXES "${_tbb_lib_dir_conda}" "lib/${_tbb_subdir}") - - if (EXISTS "${_tbb_release_lib}") - find_library(_tbb_release_impllib - NAMES ${_tbb_lib_prefix}${_tbb_component}${_bin_version}${_tbb_impllib_ext} - PATHS ${_tbb_root} - HINTS ENV TBB_ROOT_HINT - PATH_SUFFIXES "${_tbb_impllib_dir_conda}" "lib/${_tbb_subdir}") - endif() - endif() + find_library(_tbb_release_lib + NAMES lib${_tbb_component}${_bin_version}.so.${_${_tbb_component}_bin_version} + PATHS ${_tbb_root} + PATH_SUFFIXES "lib/${_tbb_intel_arch}/${_tbb_subdir}" "lib${_tbb_arch_suffix}/${_tbb_subdir}" "lib${_tbb_arch_suffix}" "lib" + NO_DEFAULT_PATH + ) if (NOT TBB_FIND_RELEASE_ONLY) find_library(_tbb_debug_lib - NAMES ${_tbb_lib_prefix}${_tbb_component}${_bin_version}_debug.${_tbb_lib_ext} - PATHS ${_tbb_root} - HINTS ENV TBB_ROOT_HINT - PATH_SUFFIXES "${_tbb_lib_dir_conda}" "lib/${_tbb_subdir}") - if(WIN32 AND EXISTS "${_tbb_debug_lib}") - find_library(_tbb_debug_impllib - NAMES ${_tbb_lib_prefix}${_tbb_component}${_bin_version}_debug.${_tbb_impllib_ext} - PATHS ${_tbb_root} - HINTS ENV TBB_ROOT_HINT - PATH_SUFFIXES "${_tbb_impllib_dir_conda}" "lib/${_tbb_subdir}") - endif() + NAMES lib${_tbb_component}${_bin_version}_debug.so.${_${_tbb_component}_bin_version} + PATHS ${_tbb_root} + PATH_SUFFIXES "lib/${_tbb_intel_arch}/${_tbb_subdir}" "lib${_tbb_arch_suffix}/${_tbb_subdir}" "lib${_tbb_arch_suffix}" "lib" + NO_DEFAULT_PATH + ) endif() if (EXISTS "${_tbb_release_lib}" OR EXISTS "${_tbb_debug_lib}") if (NOT TARGET TBB::${_tbb_component}) add_library(TBB::${_tbb_component} SHARED IMPORTED) - find_path(_tbb_include_dir - oneapi/tbb.h - PATHS ${_tbb_root} - PATH_SUFFIXES include - HINTS ENV TBB_ROOT_HINT - ) - -if(WIN32) - set_target_properties( - TBB::${_tbb_component} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_tbb_include_dir}" - INTERFACE_COMPILE_DEFINITIONS "__TBB_NO_IMPLICIT_LINKAGE=1" - ) -else() - set_target_properties( - TBB::${_tbb_component} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_tbb_include_dir}" - ) -endif() + get_filename_component(_tbb_include_dir "${_tbb_root}/include" ABSOLUTE) + set_target_properties(TBB::${_tbb_component} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_tbb_include_dir}") unset(_tbb_current_realpath) unset(_tbb_include_dir) - if (EXISTS "${_tbb_release_lib}") -if(WIN32) - set_target_properties(TBB::${_tbb_component} PROPERTIES - IMPORTED_LOCATION_RELEASE "${_tbb_release_lib}" - IMPORTED_IMPLIB_RELEASE "${_tbb_release_impllib}") -else() + + set (_tbb_release_dll ${_tbb_release_lib}) + set (_tbb_debug_dll ${_tbb_debug_lib}) + + + if (EXISTS "${_tbb_release_dll}") set_target_properties(TBB::${_tbb_component} PROPERTIES - IMPORTED_LOCATION_RELEASE "${_tbb_release_lib}") -endif() + IMPORTED_LOCATION_RELEASE "${_tbb_release_dll}") set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) endif() - if (EXISTS "${_tbb_debug_lib}") -if(WIN32) - set_target_properties(TBB::${_tbb_component} PROPERTIES - IMPORTED_LOCATION_DEBUG "${_tbb_debug_lib}" - IMPORTED_IMPLIB_DEBUG "${_tbb_debug_impllib}" - ) -else() + if (EXISTS "${_tbb_debug_dll}") set_target_properties(TBB::${_tbb_component} PROPERTIES - IMPORTED_LOCATION_DEBUG "${_tbb_debug_lib}") -endif() + IMPORTED_LOCATION_DEBUG "${_tbb_debug_dll}") set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) endif() @@ -188,6 +127,10 @@ endif() endif() endforeach() list(REMOVE_DUPLICATES TBB_IMPORTED_TARGETS) +unset(_tbb_release_dll) +unset(_tbb_debug_dll) unset(_tbb_release_lib) unset(_tbb_debug_lib) unset(_tbb_root) +unset(_tbb_intel_arch) +unset(_tbb_arch_suffix) diff --git a/dpnp/backend/cmake/Modules/oneDPLConfig.cmake b/dpnp/backend/cmake/Modules/oneDPLConfig.cmake index bd5c12fbdabe..c373e30b5f47 100644 --- a/dpnp/backend/cmake/Modules/oneDPLConfig.cmake +++ b/dpnp/backend/cmake/Modules/oneDPLConfig.cmake @@ -1,6 +1,6 @@ ##===----------------------------------------------------------------------===## # -# Copyright (c) Intel Corporation +# Copyright (C) Intel Corporation # # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # @@ -12,32 +12,50 @@ # ##===----------------------------------------------------------------------===## -# Installation path: /lib/cmake/oneDPL/ -get_filename_component(_onedpl_root "${CMAKE_CURRENT_LIST_DIR}" REALPATH) -get_filename_component(_onedpl_root "${_onedpl_root}/../../../" ABSOLUTE) +if (CMAKE_HOST_WIN32 AND CMAKE_VERSION VERSION_LESS 3.20) + message(STATUS "oneDPL: requires CMake 3.20 or later on Windows") + set(oneDPL_FOUND FALSE) + return() +elseif (NOT CMAKE_HOST_WIN32 AND CMAKE_VERSION VERSION_LESS 3.11) + message(STATUS "oneDPL: requires CMake 3.11 or later on Linux") + set(oneDPL_FOUND FALSE) + return() +endif() -if (WIN32) - set(_onedpl_headers_subdir windows) +if (CMAKE_HOST_WIN32) + # Requires version 3.20 for baseline support of icx, icx-cl + cmake_minimum_required(VERSION 3.20) else() - set(_onedpl_headers_subdir linux) + # Requires version 3.11 for use of icpc with c++17 requirement + cmake_minimum_required(VERSION 3.11) endif() +# Installation path: /lib/cmake/oneDPL/ +get_filename_component(_onedpl_root "${CMAKE_CURRENT_LIST_DIR}" REALPATH) +get_filename_component(_onedpl_root "${_onedpl_root}/../../../" ABSOLUTE) -find_path(_onedpl_headers - NAMES oneapi/dpl - PATHS ${_onedpl_root} - HINTS ENV DPL_ROOT_HINT - PATH_SUFFIXES include ${_onedpl_headers_subdir}/include -) - +get_filename_component(_onedpl_headers "${_onedpl_root}/include" ABSOLUTE) if (EXISTS "${_onedpl_headers}") if (NOT TARGET oneDPL) + if (CMAKE_CXX_COMPILER MATCHES ".*(dpcpp-cl|icx-cl|icx)(.exe)?$") + set(INTEL_LLVM_COMPILER_MSVC_LIKE TRUE) + elseif(CMAKE_CXX_COMPILER MATCHES ".*(dpcpp|icpx)(.exe)?$") + set(INTEL_LLVM_COMPILER_GNU_LIKE TRUE) + endif() + + if ((NOT oneDPLWindowsIntelLLVM_FOUND) AND CMAKE_HOST_WIN32 AND (INTEL_LLVM_COMPILER_MSVC_LIKE OR INTEL_LLVM_COMPILER_GNU_LIKE)) + message(WARNING "On Windows, ${CMAKE_CXX_COMPILER} requires some workarounds to function properly with CMake. We recommend using 'find_package(oneDPLWindowsIntelLLVM)' before your 'project()' call to apply these workarounds.") + endif() + include(CheckCXXCompilerFlag) + include(CheckIncludeFileCXX) add_library(oneDPL INTERFACE IMPORTED) set_target_properties(oneDPL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_onedpl_headers}") + target_compile_features(oneDPL INTERFACE cxx_std_17) + if (ONEDPL_PAR_BACKEND AND NOT ONEDPL_PAR_BACKEND MATCHES "^(tbb|openmp|serial)$") message(STATUS "oneDPL: ONEDPL_PAR_BACKEND=${ONEDPL_PAR_BACKEND} is requested, but not supported, available backends: tbb, openmp, serial") set(oneDPL_FOUND FALSE) @@ -45,9 +63,7 @@ if (EXISTS "${_onedpl_headers}") endif() if (NOT ONEDPL_PAR_BACKEND OR ONEDPL_PAR_BACKEND STREQUAL "tbb") # Handle oneTBB backend - if (NOT TBB_FOUND) - find_package(TBB 2021 QUIET COMPONENTS tbb PATHS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules NO_DEFAULT_PATH) - endif() + find_package(TBB 2021 QUIET COMPONENTS tbb) if (NOT TBB_FOUND AND ONEDPL_PAR_BACKEND STREQUAL "tbb") # If oneTBB backend is requested explicitly, but not found. message(STATUS "oneDPL: ONEDPL_PAR_BACKEND=${ONEDPL_PAR_BACKEND} requested, but not found") set(oneDPL_FOUND FALSE) @@ -61,28 +77,37 @@ if (EXISTS "${_onedpl_headers}") endif() if (NOT ONEDPL_PAR_BACKEND OR ONEDPL_PAR_BACKEND STREQUAL "openmp") # Handle OpenMP backend - if (UNIX) - set(_openmp_flag "-fopenmp") - else() - set(_openmp_flag "-Qopenmp") + set(_openmp_minimum_version 4.5) + find_package(OpenMP) + if (OpenMP_CXX_FOUND) + if (OpenMP_CXX_VERSION VERSION_LESS _openmp_minimum_version) + message(STATUS "oneDPL: OpenMP version (${OpenMP_CXX_VERSION}) is less than minimum supported version (${_openmp_minimum_version}), disable OpenMP" ) + else() + set(_openmp_found_valid TRUE) + endif() endif() - # Some compilers may fail if _openmp_flag is not in CMAKE_REQUIRED_LIBRARIES. - set(_onedpl_saved_required_libs ${CMAKE_REQUIRED_LIBRARIES}) - set(CMAKE_REQUIRED_LIBRARIES ${_openmp_option}) - check_cxx_compiler_flag(${_openmp_flag} _openmp_option) - set(CMAKE_REQUIRED_LIBRARIES ${_onedpl_saved_required_libs}) - unset(_onedpl_saved_required_libs) - - if (NOT _openmp_option AND ONEDPL_PAR_BACKEND STREQUAL "openmp") # If OpenMP backend is requested explicitly, but not supported. + if (NOT _openmp_found_valid AND ONEDPL_PAR_BACKEND STREQUAL "openmp") # If OpenMP backend is requested explicitly, but not supported. message(STATUS "oneDPL: ONEDPL_PAR_BACKEND=${ONEDPL_PAR_BACKEND} requested, but not supported") set(oneDPL_FOUND FALSE) return() - elseif (_openmp_option) + elseif (_openmp_found_valid) set(ONEDPL_PAR_BACKEND openmp) message(STATUS "oneDPL: ONEDPL_PAR_BACKEND=${ONEDPL_PAR_BACKEND}, disable oneTBB backend") - set_target_properties(oneDPL PROPERTIES INTERFACE_COMPILE_OPTIONS ${_openmp_flag}) - set_target_properties(oneDPL PROPERTIES INTERFACE_LINK_LIBRARIES ${_openmp_flag}) + # Due to minor correctness issues with -fiopenmp / -Qiopenmp, we are using -fopenmp / -Qopenmp until they are corrected. + # Once correctness issues are resolved, we will limit this workaround to affected versions of specific compilers. + if (OpenMP_CXX_FLAGS MATCHES ".*-fiopenmp.*") + set(_openmp_flag -fopenmp) + elseif (OpenMP_CXX_FLAGS MATCHES ".*[-/]Qiopenmp.*") + set(_openmp_flag /Qopenmp) + endif() + if (_openmp_flag) + message(STATUS "oneDPL: Using ${_openmp_flag} for openMP") + set_target_properties(oneDPL PROPERTIES INTERFACE_COMPILE_OPTIONS ${_openmp_flag}) + set_target_properties(oneDPL PROPERTIES INTERFACE_LINK_LIBRARIES ${_openmp_flag}) + else() + set_target_properties(oneDPL PROPERTIES INTERFACE_LINK_LIBRARIES OpenMP::OpenMP_CXX) + endif() set_property(TARGET oneDPL APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ONEDPL_USE_TBB_BACKEND=0 ONEDPL_USE_OPENMP_BACKEND=1) endif() endif() @@ -93,9 +118,30 @@ if (EXISTS "${_onedpl_headers}") set_property(TARGET oneDPL APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ONEDPL_USE_TBB_BACKEND=0 ONEDPL_USE_OPENMP_BACKEND=0) endif() - check_cxx_compiler_flag("-fsycl" _fsycl_option) - if (NOT _fsycl_option) - message(STATUS "oneDPL: -fsycl is not supported by current compiler, set ONEDPL_USE_DPCPP_BACKEND=0") + # Check SYCL support by the compiler + set(FSYCL_OPTION "-fsycl") + check_cxx_compiler_flag(${FSYCL_OPTION} _fsycl_option) + if (_fsycl_option) + set(FSYCL_OPTION_IF_SUPPORTED ${FSYCL_OPTION}) + endif() + + CHECK_INCLUDE_FILE_CXX("sycl/sycl.hpp" SYCL_HEADER ${FSYCL_OPTION_IF_SUPPORTED}) + if (NOT SYCL_HEADER) + CHECK_INCLUDE_FILE_CXX("CL/sycl.hpp" SYCL_HEADER_OLD ${FSYCL_OPTION_IF_SUPPORTED}) + endif() + if (SYCL_HEADER OR SYCL_HEADER_OLD) + set(SYCL_SUPPORT TRUE) + endif() + + if (SYCL_SUPPORT) + # Enable SYCL* with compilers/compiler drivers not passing -fsycl by default + if (_fsycl_option AND NOT CMAKE_CXX_COMPILER MATCHES ".*(dpcpp-cl|dpcpp)(.exe)?$") + message(STATUS "Adding ${FSYCL_OPTION} compiler option") + target_compile_options(oneDPL INTERFACE ${FSYCL_OPTION}) + target_link_libraries(oneDPL INTERFACE ${FSYCL_OPTION}) + endif() + else() + message(STATUS "oneDPL: SYCL is not supported. Set ONEDPL_USE_DPCPP_BACKEND=0") set_property(TARGET oneDPL APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ONEDPL_USE_DPCPP_BACKEND=0) endif() endif() From 7114386cdc6878bed234caed3b2b6f378b0d887f Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 13:25:42 +0100 Subject: [PATCH 2/4] Use find_package() with HINTS per implementation used by oneMath for find_package(MKL ...) --- CMakeLists.txt | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c0b33fee4f9..45376dbd933e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,36 +45,28 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) -find_package(IntelSYCL REQUIRED PATHS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules NO_DEFAULT_PATH) -find_package(TBB QUIET) -if(TBB_FOUND) - find_package(TBB REQUIRED) -else() - find_package(TBB REQUIRED PATHS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules NO_DEFAULT_PATH) -endif() +# find_package() search order: +# 1. User-specified overrides (-DMKL_DIR=..., cache variables, package root variables like MKLROOT) +# 2. Environment variables (ENV{MKLROOT}, CMAKE_PREFIX_PATH which is automatically set by conda) +# 3. PATHS (if specified, but without NO_DEFAULT_PATH) +# 4. HINTS +# 5. System prefixes (/usr, /usr/local, etc.) +# 6. CMake built-in modules +find_package(IntelSYCL REQUIRED HINTS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) +find_package(TBB REQUIRED HINTS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) set(MKL_ARCH "intel64") set(MKL_LINK "dynamic") set(MKL_THREADING "tbb_thread") set(MKL_INTERFACE "ilp64") -find_package(MKL QUIET) -if(MKL_FOUND) - find_package(MKL REQUIRED) -else() - find_package(MKL REQUIRED PATHS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules NO_DEFAULT_PATH) -endif() +find_package(MKL REQUIRED + HINTS ${MKL_ROOT}/lib/cmake + ${MKL_ROOT}/lib/cmake/mkl + $ENV{MKLROOT} + ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) set(ONEDPL_PAR_BACKEND tbb) -find_package(oneDPL QUIET) -if(oneDPL_FOUND) - if(oneDPL_VERSION VERSION_GREATER_EQUAL "2022.3.0") - find_package(oneDPL REQUIRED) - else() - find_package(oneDPL REQUIRED PATHS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules NO_DEFAULT_PATH) - endif() -else() - find_package(oneDPL REQUIRED PATHS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules NO_DEFAULT_PATH) -endif() +find_package(oneDPL REQUIRED HINTS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) include(GNUInstallDirs) From f30c1d4acfd55381ea5c963ead67dcc944ca245f Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 6 Nov 2025 11:58:18 +0100 Subject: [PATCH 3/4] Updated per review comments --- CMakeLists.txt | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45376dbd933e..7e1d422ce157 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,18 +42,22 @@ option(DPNP_WITH_REDIST "Build DPNP assuming DPC++ redistributable is installed set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) - - -# find_package() search order: -# 1. User-specified overrides (-DMKL_DIR=..., cache variables, package root variables like MKLROOT) -# 2. Environment variables (ENV{MKLROOT}, CMAKE_PREFIX_PATH which is automatically set by conda) -# 3. PATHS (if specified, but without NO_DEFAULT_PATH) -# 4. HINTS -# 5. System prefixes (/usr, /usr/local, etc.) -# 6. CMake built-in modules -find_package(IntelSYCL REQUIRED HINTS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) -find_package(TBB REQUIRED HINTS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) +set(CMAKE_MODULES_DIR BOTH) + + +# find_package() search order in CONFIG mode: +# 1. _ROOT variables (CMake variable / environment) +# 2. CMake-specific cache variables (on the command line with -D_DIR=...) +# 3. CMake-specific environment variables (_DIR, CMAKE_PREFIX_PATH, etc.) +# 4. Paths specified by the HINTS option +# 5. Standard system environment variables (PATH, etc.) +# 6. Paths stored in the CMake User Package Registry +# 7. CMake variables defined in the Platform files for the current system (like in /usr/local for Linux) +# 8. Paths stored in the CMake System Package Registry +# 9. Paths specified by the PATHS option (assumed hard-coded guesses) +set(path_to_cmake_dir ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Modules) +find_package(IntelSYCL REQUIRED PATHS ${path_to_cmake_dir}) +find_package(TBB REQUIRED PATHS ${path_to_cmake_dir}) set(MKL_ARCH "intel64") set(MKL_LINK "dynamic") @@ -63,10 +67,10 @@ find_package(MKL REQUIRED HINTS ${MKL_ROOT}/lib/cmake ${MKL_ROOT}/lib/cmake/mkl $ENV{MKLROOT} - ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) + PATHS ${path_to_cmake_dir}) set(ONEDPL_PAR_BACKEND tbb) -find_package(oneDPL REQUIRED HINTS ${CMAKE_SOURCE_DIR}/dpnp/backend/cmake/Module) +find_package(oneDPL REQUIRED PATHS ${path_to_cmake_dir}) include(GNUInstallDirs) From 49dd44bc763ace63aa83d5976405e765f69198b5 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 6 Nov 2025 12:00:03 +0100 Subject: [PATCH 4/4] Fix a typo --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e1d422ce157..091e6f2b3ecf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ option(DPNP_WITH_REDIST "Build DPNP assuming DPC++ redistributable is installed set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) -set(CMAKE_MODULES_DIR BOTH) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) # find_package() search order in CONFIG mode: