cmake_minimum_required(VERSION 3.21) project(STRUMPACK VERSION 8.0.0 LANGUAGES CXX C Fortran) cmake_policy(SET CMP0074 NEW) option(STRUMPACK_USE_MPI "Build with MPI support" ON) option(STRUMPACK_USE_OPENMP "Use OpenMP for on-node threading tasking" ON) option(STRUMPACK_USE_CUDA "Use CUDA for NVIDIA GPU acceleration" OFF) option(STRUMPACK_USE_HIP "Use HIP for AMD or NVIDIA GPU acceleration" OFF) option(STRUMPACK_USE_SYCL "Use SYCL/DPC++ for Intel GPU acceleration" OFF) option(STRUMPACK_USE_BLAS64 "Use 64 bit interfaces to BLAS and LAPACK, e.g., MKL ILP64 or openblas64" OFF) option(TPL_ENABLE_SLATE "Use SLATE, the ECP ScaLAPACK replacement" ON) option(TPL_ENABLE_PARMETIS "Build with support for ParMetis" ON) option(TPL_ENABLE_SCOTCH "Build with support for Scotch" ON) option(TPL_ENABLE_PTSCOTCH "Build with support for PTScotch" ON) option(TPL_ENABLE_PAPI "Build with support for PAPI monitoring" OFF) option(TPL_ENABLE_COMBBLAS "Use CombBLAS for weighted matching" OFF) option(TPL_ENABLE_BPACK "Use BPACK (ButterflyPACK) code by Yang Liu" ON) option(TPL_ENABLE_ZFP "Build with support for ZFP compression" ON) option(TPL_ENABLE_SZ3 "Build with support for SZ3 compression" OFF) option(TPL_ENABLE_MAGMA "Build with support for MAGMA" OFF) option(TPL_ENABLE_KBLAS "Build with support for KBLAS (requires CUDA)" OFF) option(TPL_ENABLE_MATLAB "Build with Matlab interface" OFF) option(STRUMPACK_COUNT_FLOPS "Build with flop counters" OFF) option(STRUMPACK_TASK_TIMERS "Build with timers for internal routines" OFF) option(STRUMPACK_MESSAGE_COUNTER "Build with counter for MPI messages" OFF) include(CheckLibraryExists) # include(CMakePushCheckState) include(CheckCXXSourceCompiles) include(GNUInstallDirs) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules") ############################################################## ## settings for RPATH, ## see https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling # use, i.e. don't skip the full RPATH for the build tree set(CMAKE_SKIP_BUILD_RPATH FALSE) # when building, don't use the install RPATH already # (but later on when installing) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") # add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # the RPATH to be used when installing, but only if it's not a system directory list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_LIBDIR}" isSystemDir) if("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") endif("${isSystemDir}" STREQUAL "-1") ############################################################## # figure out Fortran/C name mangling include(FortranCInterface) FortranCInterface_HEADER( ${PROJECT_BINARY_DIR}/StrumpackFortranCInterface.h MACRO_NAMESPACE "STRUMPACK_FC_") FortranCInterface_VERIFY(CXX) if(STRUMPACK_USE_MPI) find_package(MPI) if(NOT MPI_FOUND) set(STRUMPACK_USE_MPI OFF) message(WARNING "Configuring without MPI support.") endif() endif() if(NOT STRUMPACK_USE_MPI) if(TPL_ENABLE_PARMETIS) message(STATUS "Disabling ParMetis, since it requires MPI support.") set(TPL_ENABLE_PARMETIS OFF) endif() if(TPL_ENABLE_PTSCOTCH) message(STATUS "Disabling PTScotch, since it requires MPI support.") set(TPL_ENABLE_PTSCOTCH OFF) endif() if(TPL_ENABLE_BPACK) message(STATUS "Disabling ButterflyPACK, since it requires MPI support.") set(TPL_ENABLE_BPACK OFF) endif() if(TPL_ENABLE_COMBBLAS) message(STATUS "Disabling CombBLAS, since it requires MPI support.") set(TPL_ENABLE_COMBBLAS OFF) endif() if(TPL_ENABLE_SLATE) message(STATUS "Disabling SLATE, since it requires MPI support.") set(TPL_ENABLE_SLATE OFF) endif() endif() if(TPL_ENABLE_PTSCOTCH) set(TPL_ENABLE_SCOTCH ON) endif() if(NOT (STRUMPACK_USE_CUDA OR STRUMPACK_USE_HIP)) if(TPL_ENABLE_MAGMA) message(STATUS "Disabling MAGMA, it requires CUDA/HIP to be enabled.") set(TPL_ENABLE_MAGMA OFF) endif() endif() if(NOT (STRUMPACK_USE_CUDA AND TPL_ENABLE_MAGMA)) if(TPL_ENABLE_KBLAS) message(STATUS "Disabling KBLAS, it requires CUDA and MAGMA to be enabled.") set(TPL_ENABLE_KBLAS OFF) endif() endif() if(STRUMPACK_USE_OPENMP) find_package(OpenMP) if(OpenMP_FOUND) set(_SCRATCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/omp_compile_test) try_compile(STRUMPACK_USE_OPENMP_TASK_DEPEND ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/taskdepend.cpp LINK_LIBRARIES OpenMP::OpenMP_CXX) message(STATUS "Support for OpenMP task depend/priority: " ${STRUMPACK_USE_OPENMP_TASK_DEPEND}) try_compile(STRUMPACK_USE_OPENMP_TASKLOOP ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/taskloop.cpp LINK_LIBRARIES OpenMP::OpenMP_CXX) message(STATUS "Support for OpenMP taskloop: " ${STRUMPACK_USE_OPENMP_TASKLOOP}) else() message(WARNING "Compiler does not support OpenMP," " proceeding without OpenMP support.") endif() else() message(STATUS "OpenMP support was not enabled.") endif() if(STRUMPACK_USE_CUDA) enable_language(CUDA) find_package(CUDAToolkit REQUIRED) endif() if(STRUMPACK_USE_HIP) if(STRUMPACK_USE_CUDA) message(WARNING "A CUDA compiler was found," " proceeding with CUDA support instead of HIP.") set(STRUMPACK_USE_HIP OFF) else() enable_language(HIP) find_package(hip REQUIRED) find_package(hipblas REQUIRED) find_package(hipsparse REQUIRED) find_package(rocsolver REQUIRED) find_package(rocblas REQUIRED) find_package(rocprim REQUIRED) find_package(rocthrust REQUIRED) endif() endif() if(STRUMPACK_USE_SYCL) message(STATUS "SYCL/DPC++ enabled, looking for MKL") list(APPEND CMAKE_PREFIX_PATH $ENV{MKLROOT} $ENV{TBBROOT}) find_package(MKL REQUIRED) endif() if(TPL_ENABLE_MATLAB) find_package(Matlab REQUIRED COMPONENTS MEX_COMPILER) if(Matlab_FOUND) message("Found MATLAB, make sure to use BLAS/LAPACK with 64bit interface, such as Intel MKL ILP64") set(STRUMPACK_USE_BLAS64 ON) option(STRUMPACK_USE_MATLAB "" ON) endif() endif() if(STRUMPACK_USE_BLAS64) # BLA_SIZEOF_INTEGER is new in CMake 3.22 set(BLA_SIZEOF_INTEGER 8) set_source_files_properties( ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 PROPERTIES COMPILE_OPTIONS "$<$:$<$,$,$>: -fdefault-integer-8>> $<$:$<$: -i8>>") endif() if(TPL_ENABLE_MAGMA) list(APPEND CMAKE_PREFIX_PATH ${TPL_MAGMA_PREFIX} $ENV{MAGMA_DIR} $ENV{MAGMA_ROOT}) find_package(MAGMA) if(MAGMA_FOUND) option(STRUMPACK_USE_MAGMA "" ON) endif() endif() if(TPL_ENABLE_KBLAS) if(MAGMA_FOUND) # TODO check for KBLAS message(WARNING "To use KBLAS, set TPL_KBLAS_INCLUDE_DIR and TPL_KBLAS_LIBRARIES.") option(STRUMPACK_USE_KBLAS "" ON) else() message(STATUS "Disabling KBLAS, MAGMA not found.") endif() endif() if(DEFINED TPL_BLAS_LIBRARIES) # xSDK policies require the user be able to specify BLAS libraries # through the TPL_BLAS_LIBRARIES variable. If these do not work, # then an error should be generated, and we shouldn't just continue. set(BLAS_LIBRARIES ${TPL_BLAS_LIBRARIES}) set(BLAS_FOUND TRUE) set(_SCRATCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/blas_compile_test) if(TARGET OpenMP::OpenMP_Fortran) try_compile(STRUMPACK_TPL_BLAS_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 LINK_LIBRARIES ${TPL_BLAS_LIBRARIES} OpenMP::OpenMP_Fortran) else() try_compile(STRUMPACK_TPL_BLAS_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 LINK_LIBRARIES ${TPL_BLAS_LIBRARIES}) endif() if(STRUMPACK_TPL_BLAS_WORKS) message(STATUS "Using BLAS from TPL_BLAS_LIBRARIES (${TPL_BLAS_LIBRARIES})") else() message(STATUS "Linking with TPL_BLAS_LIBRARIES did not work," " trying again with additional threading library linked in.") # Compilation with TPL_BLAS_LIBRARIES failed. Perhaps we were # missing a threading library? Just guessing. One more try with # threading (pthreads) linked in and then we give up. find_package(Threads) if(TARGET OpenMP::OpenMP_Fortran) try_compile(STRUMPACK_TPL_BLAS_WITH_THREADS_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 LINK_LIBRARIES ${TPL_BLAS_LIBRARIES} Threads::Threads OpenMP::OpenMP_Fortran) else() try_compile(STRUMPACK_TPL_BLAS_WITH_THREADS_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 LINK_LIBRARIES ${TPL_BLAS_LIBRARIES} Threads::Threads) endif() if(STRUMPACK_TPL_BLAS_WITH_THREADS_WORKS) message(STATUS "Using BLAS (${TPL_BLAS_LIBRARIES}), with additional threading library.") else() message(FATAL_ERROR "BLAS libraries defined in TPL_BLAS_LIBRARIES (${TPL_BLAS_LIBRARIES}) cannot be used. " "If your BLAS library links to OpenMP, enable OpenMP with -DSTRUMPACK_USE_OPENMP=ON. " "If that doesn't work, try running CMake with --debug-trycompile and check " "the output in build/blas_compile_test/CMakeFiles/CMakeTmp/ .") endif() endif() else() find_package(BLAS) if(NOT BLAS_FOUND) # BLAS was not specified in TPL_BLAS_LIBRARIES, and not found # elsewhere. We will still try to compile a BLAS example, because # perhaps BLAS is automatically linked by the compiler wrapper, as # is the case for instance on Cray machines. message(STATUS "A BLAS library could not be found on the system, " "checking if BLAS is implicitly linked by the compiler(wrapper).") set(_SCRATCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/blas_compile_test) find_package(Threads) if(TARGET OpenMP::OpenMP_Fortran) try_compile(STRUMPACK_BLAS_JUST_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 LINK_LIBRARIES Threads::Threads OpenMP::OpenMP_Fortran) else() try_compile(STRUMPACK_BLAS_JUST_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_blas.f90 LINK_LIBRARIES Threads::Threads) endif() if(NOT STRUMPACK_BLAS_JUST_WORKS) message(FATAL_ERROR "Could not find a BLAS library.\n" " You can specify a BLAS library using -DTPL_BLAS_LIBRARIES=\"...\"") endif() endif() endif() if(DEFINED TPL_LAPACK_LIBRARIES) # xSDK policies require the user be able to specify LAPACK libraries # through the TPL_LAPACK_LIBRARIES variable. If these do not work, # then an error should be generated, and we shouldn't just continue. set(LAPACK_LIBRARIES ${TPL_LAPACK_LIBRARIES}) set(LAPACK_FOUND TRUE) set(_SCRATCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/lapack_compile_test) if(TARGET OpenMP::OpenMP_Fortran) try_compile(STRUMPACK_TPL_LAPACK_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 LINK_LIBRARIES ${TPL_LAPACK_LIBRARIES} ${BLAS_LIBRARIES} OpenMP::OpenMP_Fortran) else() try_compile(STRUMPACK_TPL_LAPACK_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 LINK_LIBRARIES ${TPL_LAPACK_LIBRARIES} ${BLAS_LIBRARIES}) endif() if(STRUMPACK_TPL_LAPACK_WORKS) message(STATUS "Using LAPACK from TPL_LAPACK_LIBRARIES (${TPL_LAPACK_LIBRARIES})") else() message(STATUS "Linking with TPL_LAPACK_LIBRARIES did not work," " trying again with additional threading library linked in.") # Compilation with TPL_LAPACK_LIBRARIES failed. Perhaps we were # missing a threading library? Just guessing. One more try with # threading (pthreads) linked in and then we give up. find_package(Threads) if(TARGET OpenMP::OpenMP_Fortran) try_compile(STRUMPACK_TPL_LAPACK_WITH_THREADS_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 LINK_LIBRARIES ${TPL_LAPACK_LIBRARIES} ${BLAS_LIBRARIES} Threads::Threads OpenMP::OpenMP_Fortran) else() try_compile(STRUMPACK_TPL_LAPACK_WITH_THREADS_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 LINK_LIBRARIES ${TPL_LAPACK_LIBRARIES} ${BLAS_LIBRARIES} Threads::Threads) endif() if(STRUMPACK_TPL_LAPACK_WITH_THREADS_WORKS) message(STATUS "Using LAPACK (${TPL_LAPACK_LIBRARIES}), " "with additional threading library.") else() message(FATAL_ERROR "LAPACK libraries defined in TPL_LAPACK_LIBRARIES (${TPL_LAPACK_LIBRARIES}) cannot be used. " "If your LAPACK library links to OpenMP, enable OpenMP with -DSTRUMPACK_USE_OPENMP=ON. " "If that doesn't work, try running CMake with --debug-trycompile and check " "the output in build/lapack_compile_test/CMakeFiles/CMakeTmp/") endif() endif() else() if(DEFINED TPL_BLAS_LIBRARIES) message(WARNING "TPL_BLAS_LIBRARIES was specified. " "Consider specifying TPL_LAPACK_LIBRARIES as well to ensure " "compatible BLAS and LAPACK libraries.") endif() find_package(LAPACK) if(NOT LAPACK_FOUND) # LAPACK was not specified in TPL_LAPACK_LIBRARIES, and not found # elsewhere. We will still try to compile a LAPACK example, # because perhaps LAPACK is automatically linked by the compiler # wrapper, as is the case for instance on Cray machines. message(STATUS "A LAPACK library could not be found on the system, " "checking if LAPACK is implicitly linked by the compiler(wrapper).") set(_SCRATCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/lapack_compile_test) find_package(Threads) if(TARGET OpenMP::OpenMP_Fortran) try_compile(STRUMPACK_LAPACK_JUST_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 LINK_LIBRARIES Threads::Threads OpenMP::OpenMP_Fortran) else() try_compile(STRUMPACK_LAPACK_JUST_WORKS ${_SCRATCH_DIR} SOURCES ${CMAKE_SOURCE_DIR}/cmake/test_lapack.f90 LINK_LIBRARIES Threads::Threads) endif() if(NOT STRUMPACK_LAPACK_JUST_WORKS) message(FATAL_ERROR "Could not find a LAPACK library.\n" " You can specify a LAPACK library using -DTPL_LAPACK_LIBRARIES=\"...\"") endif() endif() endif() # check if getopt.h is available check_cxx_source_compiles("#include int main(int argc, char* argv[]) { getopt_long(argc, argv, \"\", 0, 0); }" STRUMPACK_USE_GETOPT) if(STRUMPACK_USE_MPI) # the default blocksize when using ScaLAPACK, # might be changed when using SLATE, see below set(STRUMPACK_PBLAS_BLOCKSIZE "32") if(DEFINED TPL_SCALAPACK_LIBRARIES) set(SCALAPACK_FOUND TRUE) set(SCALAPACK_LIBRARIES ${TPL_SCALAPACK_LIBRARIES}) message(STATUS "Using ScaLAPACK from TPL_SCALAPACK_LIBRARIES" " (${TPL_SCALAPACK_LIBRARIES})") ### this check doesn't work: needs MPI, BLAS, LAPACK, threads, libm, ..? # cmake_push_check_state() # set(CMAKE_REQUIRED_LIBRARIES MPI::MPI_C) # if(BLAS_FOUND) # list(APPEND CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES}) # endif() # if(LAPACK_FOUND) # list(APPEND CMAKE_REQUIRED_LIBRARIES ${LAPACK_LIBRARIES}) # endif() # check_library_exists("${TPL_SCALAPACK_LIBRARIES}" pdgemm_ "" TPL_SCALAPACK_WORKS_U) # check_library_exists("${TPL_SCALAPACK_LIBRARIES}" pdgemm "" TPL_SCALAPACK_WORKS_NOU) # cmake_pop_check_state() # if(TPL_SCALAPACK_WORKS_U OR TPL_SCALAPACK_WORKS_NOU) # message(STATUS # "Using ScaLAPACK from TPL_SCALAPACK_LIBRARIES" # " (${TPL_SCALAPACK_LIBRARIES})") # else() # message(FATAL_ERROR # "Cannot use TPL_SCALAPACK_LIBRARIES (${TPL_SCALAPACK_LIBRARIES})") # endif() else() find_package(SCALAPACK) if(NOT SCALAPACK_FOUND) # SCALAPACK was not specified in TPL_SCALAPACK_LIBRARIES, and # not found elsewhere. We will still try to compile a SCALAPACK # example, because perhaps SCALAPACK is automatically linked by # the compiler wrapper, as is the case for instance on Cray # machines. message(STATUS "A SCALAPACK library could not be found on the system, " "checking if SCALAPACK is implicitly linked by the compiler(wrapper).") check_library_exists("" pdgemm_ "" SCALAPACK_JUST_WORKS_U) check_library_exists("" pdgemm "" SCALAPACK_JUST_WORKS_NOU) if(NOT (SCALAPACK_JUST_WORKS_U OR SCALAPACK_JUST_WORKS_NOU)) message(FATAL_ERROR "Could not find a SCALAPACK library.\n" " You can specify a SCALAPACK library using -DTPL_SCALAPACK_LIBRARIES=\"...\"") endif() else() set(SCALAPACK_LIBRARIES scalapack) message(STATUS "Found SCALAPACK " ${SCALAPACK_LIBRARIES}) endif() endif() endif() list(APPEND CMAKE_PREFIX_PATH ${TPL_METIS_PREFIX} $ENV{METIS_DIR} $ENV{METIS_ROOT}) if(NOT DEFINED metis_INCLUDE_DIR) set(metis_INCLUDE_DIR ${TPL_METIS_INCLUDE_DIRS}) endif() if(NOT DEFINED metis_LIBRARY_DIR) set(metis_LIBRARY_DIR ${TPL_METIS_LIBRARY_DIR}) endif() if(NOT DEFINED metis_LIBRARIES) set(metis_LIBRARIES ${TPL_METIS_LIBRARIES}) endif() find_package(METIS REQUIRED) if(TPL_ENABLE_SCOTCH) list(APPEND CMAKE_PREFIX_PATH ${TPL_SCOTCH_PREFIX} $ENV{SCOTCH_DIR} $ENV{SCOTCH_ROOT} ${TPL_PTSCOTCH_PREFIX} $ENV{PTSCOTCH_DIR} $ENV{PTSCOTCH_ROOT}) find_package(SCOTCH) if(SCOTCH_FOUND) message("-- Found SCOTCH") option(STRUMPACK_USE_SCOTCH "" ON) if(TPL_ENABLE_PTSCOTCH) if(TARGET SCOTCH::ptscotch) message("-- Found PTSCOTCH") option(STRUMPACK_USE_PTSCOTCH "" ON) else() message(WARNING "SCOTCH was found, but does not contain PTSOTCH") endif() endif() endif() endif() if(TPL_ENABLE_PARMETIS) list(APPEND CMAKE_PREFIX_PATH ${TPL_PARMETIS_PREFIX} $ENV{PARMETIS_DIR} $ENV{PARMETIS_ROOT} $ENV{ParMETIS_DIR} $ENV{ParMETIS_ROOT}) if(NOT DEFINED parmetis_INCLUDE_DIR) set(parmetis_INCLUDE_DIR ${TPL_PARMETIS_INCLUDE_DIRS}) endif() if(NOT DEFINED parmetis_LIBRARY_DIR) set(parmetis_LIBRARY_DIR ${TPL_PARMETIS_LIBRARY_DIR}) endif() if(NOT DEFINED parmetis_LIBRARIES) set(parmetis_LIBRARIES ${TPL_PARMETIS_LIBRARIES}) endif() find_package(ParMETIS) if(ParMETIS_FOUND) option(STRUMPACK_USE_PARMETIS "" ON) endif() endif() if(TPL_ENABLE_ZFP) list(APPEND CMAKE_PREFIX_PATH ${TPL_ZFP_PREFIX} $ENV{ZFP_ROOT} $ENV{ZFP_DIR}) find_package(ZFP) if(ZFP_FOUND) option(STRUMPACK_USE_ZFP "" ON) endif() endif() if(TPL_ENABLE_SZ3) list(APPEND CMAKE_PREFIX_PATH ${TPL_SZ3_PREFIX} $ENV{SZ3_ROOT} $ENV{SZ3_DIR}) find_package(SZ3) if(SZ3_FOUND) option(STRUMPACK_USE_SZ3 "" ON) endif() endif() if(TPL_ENABLE_BPACK) list(APPEND CMAKE_PREFIX_PATH ${TPL_BUTTERFLYPACK_PREFIX} $ENV{ButterflyPACK_DIR} $ENV{ButterflyPACK_ROOT} $ENV{BUTTERFLYPACK_DIR} $ENV{BUTTERFLYPACK_ROOT}) find_package(ButterflyPACK) if(ButterflyPACK_FOUND) option(STRUMPACK_USE_BPACK "" ON) endif() endif() if(TPL_ENABLE_SLATE) list(APPEND CMAKE_PREFIX_PATH ${TPL_SLATE_PREFIX} $ENV{slate_DIR} $ENV{slate_ROOT} $ENV{SLATE_DIR} $ENV{SLATE_ROOT}) find_package(blaspp) find_package(lapackpp) find_package(slate) if(slate_FOUND) message(STATUS "Found SLATE") # option(STRUMPACK_USE_SLATE_LAPACK "" ON) option(STRUMPACK_USE_SLATE "" ON) option(STRUMPACK_USE_SLATE_SCALAPACK "" ON) set(STRUMPACK_PBLAS_BLOCKSIZE "512") else() message(WARNING "SLATE was not found." " SLATE is required for GPU support in the distributed memory code.") endif() endif() if(TPL_ENABLE_COMBBLAS) list(APPEND CMAKE_PREFIX_PATH ${TPL_COMBBLAS_PREFIX} $ENV{COMBBLAS_DIR} $ENV{COMBBLAS_ROOT} $ENV{CombBLAS_DIR} $ENV{CombBLAS_ROOT}) find_package(CombBLAS) if(CombBLAS_FOUND) message(STATUS "Found CombBLAS") option(STRUMPACK_USE_COMBBLAS "" ON) else() message(STATUS "CombBLAS not found") endif() endif() add_library(strumpack "") # this is to fix a link issue for the fortran example when compiling # with clang set_target_properties(strumpack PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" POSITION_INDEPENDENT_CODE ON) # see https://github.com/pghysels/STRUMPACK/issues/82 # TODO check if 32bit, check compiler?? set(ATOMIC_TEST_SOURCE "#include int main() { std::atomic i(0); i++; return 0; }") check_cxx_source_compiles("${ATOMIC_TEST_SOURCE}" ATOMIC_INT64_IS_BUILTIN) if(NOT ATOMIC_INT64_IS_BUILTIN) set(CMAKE_REQUIRED_LIBRARIES atomic) check_cxx_source_compiles( "${ATOMIC_TEST_SOURCE}" ATOMIC_INT64_REQUIRES_LIBATOMIC) if (ATOMIC_INT64_REQUIRES_LIBATOMIC) target_link_libraries(strumpack PRIVATE atomic) endif() unset(CMAKE_REQUIRED_LIBRARIES) endif() add_subdirectory(src) target_sources(strumpack PRIVATE ${PROJECT_BINARY_DIR}/StrumpackFortranCInterface.h) target_compile_features(strumpack PUBLIC cxx_std_17) set_target_properties(strumpack PROPERTIES CXX_EXTENSIONS OFF) target_compile_options(strumpack PRIVATE $<$:$<$,$,$>: -Wall>> $<$:$<$: /W4>>) include(CheckCXXCompilerFlag) check_cxx_compiler_flag(-Wno-overloaded-virtual COMPILER_SUPPORTS_NOOVERLOAD_WARNING) if(COMPILER_SUPPORTS_NOOVERLOAD_WARNING) target_compile_options(strumpack PUBLIC $<$:-Wno-overloaded-virtual>) endif() if(STRUMPACK_USE_BLAS64) target_compile_options(strumpack PRIVATE $<$:$<$,$,$>: -fdefault-integer-8>> $<$:$<$: -i8>>) endif() if(STRUMPACK_USE_MPI) target_link_libraries(strumpack PUBLIC MPI::MPI_CXX MPI::MPI_C ${MPI_Fortran_LIBRARIES}) ## adding the MPI::MPI_Fortran target risks adding unwanted compile flags endif() if(OpenMP_FOUND) # if(OpenMP_C_FOUND) # target_link_libraries(strumpack PRIVATE OpenMP::OpenMP_C) # endif() if(OpenMP_CXX_FOUND) target_link_libraries(strumpack PUBLIC OpenMP::OpenMP_CXX) endif() # if(OpenMP_Fortran_FOUND) # target_link_libraries(strumpack PRIVATE OpenMP::OpenMP_Fortran) # endif() endif() if(NOT STRUMPACK_USE_OPENMP) include(CheckCXXCompilerFlag) check_cxx_compiler_flag(-Wno-unknown-pragmas COMPILER_SUPPORTS_NOPRAGMA_WARNING) if(COMPILER_SUPPORTS_NOPRAGMA_WARNING) target_compile_options(strumpack PUBLIC $<$:-Wno-unknown-pragmas>) endif() endif() if(STRUMPACK_USE_MPI) if(SCALAPACK_FOUND) target_link_libraries(strumpack PUBLIC ${SCALAPACK_LIBRARIES}) endif() endif() if(LAPACK_FOUND) target_link_libraries(strumpack PUBLIC ${LAPACK_LIBRARIES}) endif() if(BLAS_FOUND) target_link_libraries(strumpack PUBLIC ${BLAS_LIBRARIES}) endif() if(MKL_FOUND) # target_link_libraries(strumpack PUBLIC MKL::MKL MKL::MKL_SYCL) target_include_directories(strumpack INTERFACE "${MKL_ROOT}/include") target_link_libraries(strumpack INTERFACE "${MKL_ROOT}/lib/libmkl_sycl.so") target_link_libraries(strumpack INTERFACE "${MKL_ROOT}/lib/libmkl_sequential.so") target_link_libraries(strumpack INTERFACE "${MKL_ROOT}/lib/libmkl_core.so") target_link_libraries(strumpack INTERFACE "${MKL_ROOT}/lib/libmkl_intel_lp64.so") target_link_libraries(strumpack INTERFACE "-lsycl -lpthread -lm -ldl") endif() # the order is important # - ParMETIS before METIS, since ParMETIS needs METIS # - (ParMETIS) before Scotch to avoid confusion with the Scotch # ParMETIS compatibility layer if(ParMETIS_FOUND) target_link_libraries(strumpack PUBLIC ParMETIS::parmetis) endif() target_link_libraries(strumpack PUBLIC METIS::metis) if(SCOTCH_FOUND) target_link_libraries(strumpack PUBLIC SCOTCH::scotch SCOTCH::scotcherr) if(STRUMPACK_USE_PTSCOTCH) target_link_libraries(strumpack PUBLIC SCOTCH::ptscotch SCOTCH::ptscotcherr) endif() # if(SCOTCH_USES_PTHREADS) # target_link_libraries(strumpack PUBLIC Threads::Threads) # endif() endif() if(ZFP_FOUND) target_link_libraries(strumpack PUBLIC zfp::zfp) endif() if(SZ3_FOUND) target_link_libraries(strumpack PUBLIC SZ3::SZ3) endif() if(ButterflyPACK_FOUND) target_link_libraries(strumpack PUBLIC ButterflyPACK::sbutterflypack ButterflyPACK::dbutterflypack ButterflyPACK::cbutterflypack ButterflyPACK::zbutterflypack) endif() if(slate_FOUND) target_link_libraries(strumpack PUBLIC slate lapackpp blaspp) endif() if(CUDAToolkit_FOUND) target_link_libraries(strumpack PUBLIC CUDA::cudart CUDA::cusolver CUDA::cublas) endif() if(MAGMA_FOUND) target_link_libraries(strumpack PUBLIC MAGMA::magma) endif() if(TPL_ENABLE_KBLAS) target_include_directories(strumpack PUBLIC ${TPL_KBLAS_INCLUDE_DIR}) target_link_libraries(strumpack PUBLIC ${TPL_KBLAS_LIBRARIES}) endif() if(hipblas_FOUND) target_link_libraries(strumpack PUBLIC roc::hipblas roc::rocblas roc::rocsolver roc::hipsparse roc::rocthrust) endif() if(CombBLAS_FOUND) target_link_libraries(strumpack PUBLIC CombBLAS::CombBLAS) target_include_directories(strumpack PRIVATE $ENV{COMBBLASAPP_DIR}) endif() # examples add_subdirectory(examples) # testing include(CTest) add_subdirectory(test) # documentation find_package(Doxygen) if(DOXYGEN_FOUND) configure_file(${CMAKE_SOURCE_DIR}/doc/doxygen/doxygen.dox.in ${CMAKE_BINARY_DIR}/doxygen.dox @ONLY) add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/doxygen.dox WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Generating API documentation with doxygen" VERBATIM) endif() # installation install(FILES ${PROJECT_BINARY_DIR}/StrumpackFortranCInterface.h DESTINATION include) install(TARGETS strumpack EXPORT STRUMPACKTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) # export targets and all set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/STRUMPACK) install(EXPORT STRUMPACKTargets FILE strumpack-targets.cmake NAMESPACE STRUMPACK:: DESTINATION ${ConfigPackageLocation}) include(CMakePackageConfigHelpers) write_basic_package_version_file(strumpack-config-version.cmake VERSION ${STRUMPACK_VERSION} COMPATIBILITY AnyNewerVersion) install(FILES "${CMAKE_BINARY_DIR}/strumpack-config-version.cmake" DESTINATION ${ConfigPackageLocation}) # stupid CMake makes me write one more file configure_package_config_file( ${PROJECT_SOURCE_DIR}/cmake/strumpack-config.cmake.in ${CMAKE_BINARY_DIR}/strumpack-config.cmake INSTALL_DESTINATION ${ConfigPackageLocation}) install(FILES "${CMAKE_BINARY_DIR}/strumpack-config.cmake" DESTINATION ${ConfigPackageLocation}) # install the FindMETIS, etc modules for STRUMPACK users install(DIRECTORY cmake/Modules/ DESTINATION ${ConfigPackageLocation} FILES_MATCHING PATTERN "*.cmake")