From 7780d6522da2bba8f2b8d877cee8eda1ea308aab Mon Sep 17 00:00:00 2001
From: Daniel Weindl <daniel.weindl@helmholtz-munich.de>
Date: Tue, 14 May 2024 09:47:43 +0200
Subject: [PATCH] CMake: Fix MKL detection when not using environment modules

If MKLROOT is set (e.g., `source /opt/intel/oneapi/setvars.sh` will do that), first try FindBLAS instead of just relying on MKL_INCDIR and MKL_LIB.

Fixes #2441.
---
 CMakeLists.txt              |  2 +-
 cmake/AmiciFindBLAS.cmake   | 48 ++++++++++++++++++++++++-------------
 cmake/cmakelang-tools.cmake |  2 ++
 swig/CMakeLists.txt         |  5 +++-
 4 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d8a1109d90..81cc70c9d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -135,7 +135,7 @@ endif()
 set(VENDORED_SUNDIALS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/sundials)
 set(SUNDIALS_PRIVATE_INCLUDE_DIRS "${VENDORED_SUNDIALS_DIR}/src")
 # Handle different sundials build/install dirs, depending on whether we are
-#  building the Python extension only or the full C++ interface
+# building the Python extension only or the full C++ interface
 if(AMICI_PYTHON_BUILD_EXT_ONLY)
   set(VENDORED_SUNDIALS_BUILD_DIR ${CMAKE_CURRENT_SOURCE_DIR})
   set(VENDORED_SUNDIALS_INSTALL_DIR ${VENDORED_SUNDIALS_BUILD_DIR})
diff --git a/cmake/AmiciFindBLAS.cmake b/cmake/AmiciFindBLAS.cmake
index 51d9c9b257..6f71da9eeb 100644
--- a/cmake/AmiciFindBLAS.cmake
+++ b/cmake/AmiciFindBLAS.cmake
@@ -12,18 +12,32 @@ set_property(CACHE BLAS PROPERTY STRINGS "CBLAS" "MKL" "ACCELERATE")
 
 if(${BLAS} STREQUAL "MKL" OR DEFINED ENV{MKLROOT})
   if(DEFINED ENV{MKLROOT})
-    # This is set by Environment Modules
-    message(STATUS "Using MKL_INCDIR and MKL_LIB from environment module")
     set(BLAS
         "MKL"
         CACHE STRING "BLAS library to use" FORCE)
-    set(BLAS_INCLUDE_DIRS
-        "$ENV{MKL_INCDIR}"
-        CACHE STRING "" FORCE)
-    set(BLAS_LIBRARIES
-        "$ENV{MKL_LIB}"
-        CACHE STRING "" FORCE)
+
+    # Was MKLROOT set by /opt/intel/oneapi/setvars.sh? then cmake will find it
+    message(STATUS "Trying to find BLAS based on MKLROOT=$ENV{MKLROOT}")
+    # give the user the option to override the BLA_VENDOR
+    if(NOT DEFINED BLA_VENDOR)
+      set(BLA_VENDOR Intel10_64lp)
+    endif()
+    find_package(BLAS)
+    if(BLAS_FOUND)
+      message(STATUS "Found BLAS via FindBLAS and MKLROOT")
+    else()
+      # This is set by Environment Modules and might not be compatible with
+      # FindBLAS
+      message(STATUS "Using MKL_INCDIR and MKL_LIB from environment module")
+      set(BLAS_INCLUDE_DIRS
+          "$ENV{MKL_INCDIR}"
+          CACHE STRING "" FORCE)
+      set(BLAS_LIBRARIES
+          "$ENV{MKL_LIB}"
+          CACHE STRING "" FORCE)
+    endif()
   else()
+    message(STATUS "BLAS is set to MKL, but MKLROOT is not set.")
     set(BLAS_INCLUDE_DIRS
         ""
         CACHE STRING "")
@@ -79,17 +93,17 @@ endif()
 # Create an imported target
 if(NOT TARGET BLAS::BLAS)
   add_library(BLAS INTERFACE)
-  set_target_properties(BLAS PROPERTIES
-    INTERFACE_INCLUDE_DIRECTORIES "${BLAS_INCLUDE_DIRS}"
-    INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}")
+  set_target_properties(
+    BLAS PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${BLAS_INCLUDE_DIRS}"
+                    INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}")
   add_library(BLAS::BLAS ALIAS BLAS)
   if("${PROJECT_NAME}" STREQUAL "amici")
-      install(TARGETS BLAS EXPORT BLAS)
-      export(EXPORT BLAS NAMESPACE BLAS::)
-      install(
-        EXPORT BLAS
-        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Amici"
-        NAMESPACE BLAS::)
+    install(TARGETS BLAS EXPORT BLAS)
+    export(EXPORT BLAS NAMESPACE BLAS::)
+    install(
+      EXPORT BLAS
+      DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Amici"
+      NAMESPACE BLAS::)
   endif()
 
   # legacy python package environment variables:
diff --git a/cmake/cmakelang-tools.cmake b/cmake/cmakelang-tools.cmake
index ad489500bc..5796938d2c 100644
--- a/cmake/cmakelang-tools.cmake
+++ b/cmake/cmakelang-tools.cmake
@@ -9,7 +9,9 @@ set(ALL_CMAKE_FILES
     tests/cpp/unittests/CMakeLists.txt
     ${CMAKE_MODULE_PATH}/cmakelang-tools.cmake
     ${CMAKE_MODULE_PATH}/clang-tools.cmake
+    ${CMAKE_MODULE_PATH}/AmiciFindBLAS.cmake
     ${CMAKE_MODULE_PATH}/version.cmake)
+
 list(JOIN ALL_CMAKE_FILES " " ALL_CMAKE_FILES)
 
 # --- cmake-format ---
diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt
index 7b7baf9be9..5cc6e6b5a2 100644
--- a/swig/CMakeLists.txt
+++ b/swig/CMakeLists.txt
@@ -20,7 +20,10 @@ find_package(
   Python3
   COMPONENTS Interpreter Development NumPy
   REQUIRED)
-message(STATUS "Found numpy ${Python3_NumPy_VERSION} include dir ${Python3_NumPy_INCLUDE_DIRS}")
+message(
+  STATUS
+    "Found numpy ${Python3_NumPy_VERSION} include dir ${Python3_NumPy_INCLUDE_DIRS}"
+)
 set(AMICI_INTERFACE_LIST
     ${CMAKE_CURRENT_SOURCE_DIR}/amici.i
     ${CMAKE_CURRENT_SOURCE_DIR}/edata.i