From 4e9d1e45d812abc73f6d052e911d1e744719d122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=BCtzel?= Date: Wed, 6 Sep 2023 18:17:57 +0200 Subject: [PATCH 1/2] SPQR: Overhaul CMake build rules. Use targets more consistently instead of variables. Set properties on the target instead of globally where possible. No need for a CUDA compiler for the sources of SPQR. There are no OpenMP accelerated expressions in the sources. So, don't depend on OpenMP. Don't link transient targets of CHOLMOD (AMD and COLAMD) explicitly. Link static libraries to static libraries if possible. --- SPQR/CMakeLists.txt | 145 ++++++++++++++---------------------- SPQR/Config/SPQR.pc.in | 4 +- SPQR/SPQRGPU/CMakeLists.txt | 14 ++-- 3 files changed, 63 insertions(+), 100 deletions(-) diff --git a/SPQR/CMakeLists.txt b/SPQR/CMakeLists.txt index e39e783b8..7d7e5e897 100644 --- a/SPQR/CMakeLists.txt +++ b/SPQR/CMakeLists.txt @@ -30,7 +30,7 @@ message ( STATUS "Building SPQR version: v" set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) -option ( ENABLE_CUDA "Enable CUDA acceleration" on ) +option ( ENABLE_CUDA "Enable CUDA acceleration" ON ) include ( SuiteSparsePolicy ) @@ -38,32 +38,14 @@ include ( SuiteSparsePolicy ) # define the project #------------------------------------------------------------------------------- -if ( SUITESPARSE_CUDA ) - # SPQR with CUDA - project ( spqr - VERSION "${SPQR_VERSION_MAJOR}.${SPQR_VERSION_MINOR}.${SPQR_VERSION_SUB}" - LANGUAGES C CXX CUDA ) -else ( ) - # SPQR without CUDA - project ( spqr - VERSION "${SPQR_VERSION_MAJOR}.${SPQR_VERSION_MINOR}.${SPQR_VERSION_SUB}" - LANGUAGES C CXX ) -endif ( ) +project ( spqr + VERSION "${SPQR_VERSION_MAJOR}.${SPQR_VERSION_MINOR}.${SPQR_VERSION_SUB}" + LANGUAGES C CXX ) #------------------------------------------------------------------------------- # find library dependencies #------------------------------------------------------------------------------- -enable_language ( C ) - -option ( NOPENMP "ON: do not use OpenMP. OFF (default): use OpenMP" off ) -if ( NOPENMP ) - # OpenMP has been disabled - set ( OPENMP_FOUND false ) -else ( ) - find_package ( OpenMP ) -endif ( ) - find_package ( SuiteSparse_config 7.2.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) @@ -82,6 +64,8 @@ if ( NOT TARGET SuiteSparse::COLAMD ) find_package ( COLAMD 3.2.0 REQUIRED ) endif ( ) +# It would be nice if just checking for CHOLMOD would automatically pull in +# the targets for its dependencies. find_package ( CHOLMOD 4.2.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD ) @@ -128,11 +112,6 @@ include ( SuiteSparseLAPACK ) # requires cmake 3.22 if ( SUITESPARSE_CUDA ) # with CUDA add_subdirectory ( SPQRGPU ) - set ( SPQR_CUDA_LIBS SPQR_CUDA ${CUDA_LIBRARIES} ) - list ( APPEND SPQR_CUDA_LIBS SuiteSparse::GPUQREngine SuiteSparse::GPURuntime SuiteSparse::CHOLMOD_CUDA ) - - include_directories ( SPQRGPU ${CUDAToolkit_INCLUDE_DIRS} ) - link_directories ( "SPQRGPU" "${CUDA_LIBRARIES}" "/usr/local/cuda/lib64/stubs" "/usr/local/cuda/lib64" ) endif ( ) #------------------------------------------------------------------------------- @@ -146,12 +125,6 @@ configure_file ( "Config/spqr_version.tex.in" "${PROJECT_SOURCE_DIR}/Doc/spqr_version.tex" NEWLINE_STYLE LF ) -#------------------------------------------------------------------------------- -# include directories -#------------------------------------------------------------------------------- - -include_directories ( Source Include ) - #------------------------------------------------------------------------------- # dynamic spqr library properties #------------------------------------------------------------------------------- @@ -171,6 +144,7 @@ set_target_properties ( SPQR PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) target_include_directories ( SPQR + PRIVATE Source Include INTERFACE $ $ ) @@ -196,6 +170,7 @@ if ( NOT NSTATIC ) endif ( ) target_include_directories ( SPQR_static + PRIVATE Source Include INTERFACE $ $ ) @@ -215,20 +190,6 @@ if ( NOT NSTATIC ) endif ( ) endif ( ) -# OpenMP: -if ( OPENMP_FOUND ) - message ( STATUS "OpenMP C libraries: ${OpenMP_C_LIBRARIES} ") - message ( STATUS "OpenMP C include: ${OpenMP_C_INCLUDE_DIRS} ") - message ( STATUS "OpenMP C flags: ${OpenMP_C_FLAGS} ") - target_link_libraries ( SPQR PRIVATE ${OpenMP_C_LIBRARIES} ) - if ( NOT NSTATIC ) - target_link_libraries ( SPQR_static PUBLIC ${OpenMP_C_LIBRARIES} ) - list ( APPEND SPQR_STATIC_LIBS ${OpenMP_C_LIBRARIES} ) - endif ( ) - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} " ) - include_directories ( ${OpenMP_C_INCLUDE_DIRS} ) -endif ( ) - # libm: if ( NOT WIN32 ) target_link_libraries ( SPQR PRIVATE m ) @@ -238,55 +199,35 @@ if ( NOT WIN32 ) endif ( ) endif ( ) -# AMD: -target_link_libraries ( SPQR PRIVATE SuiteSparse::AMD ) -if ( NOT NSTATIC ) - if ( TARGET SuiteSparse::AMD_static ) - target_link_libraries ( SPQR_static PUBLIC SuiteSparse::AMD_static ) - else ( ) - target_link_libraries ( SPQR_static PUBLIC SuiteSparse::AMD ) - endif ( ) -endif ( ) - -# COLAMD: -target_link_libraries ( SPQR PRIVATE SuiteSparse::COLAMD ) -if ( NOT NSTATIC ) - if ( TARGET SuiteSparse::COLAMD_static ) - target_link_libraries ( SPQR_static PUBLIC SuiteSparse::COLAMD_static ) - else ( ) - target_link_libraries ( SPQR_static PUBLIC SuiteSparse::COLAMD ) - endif ( ) -endif ( ) - # LAPACK: message ( STATUS "LAPACK libraries: ${LAPACK_LIBRARIES} ") message ( STATUS "LAPACK include: ${LAPACK_INCLUDE_DIRS} ") message ( STATUS "LAPACK linker flags: ${LAPACK_LINKER_FLAGS} ") target_link_libraries ( SPQR PRIVATE ${LAPACK_LIBRARIES} ) +target_include_directories ( SPQR PRIVATE ${LAPACK_INCLUDE_DIR} ) if ( NOT NSTATIC ) list ( APPEND SPQR_STATIC_LIBS ${LAPACK_LIBRARIES} ) target_link_libraries ( SPQR_static PUBLIC ${LAPACK_LIBRARIES} ) + target_include_directories ( SPQR_static PRIVATE ${LAPACK_INCLUDE_DIR} ) endif ( ) -include_directories ( ${LAPACK_INCLUDE_DIR} ) # BLAS: message ( STATUS "BLAS libraries: ${BLAS_LIBRARIES} ") message ( STATUS "BLAS include: ${BLAS_INCLUDE_DIRS} ") message ( STATUS "BLAS linker flags: ${BLAS_LINKER_FLAGS} ") target_link_libraries ( SPQR PRIVATE ${BLAS_LIBRARIES} ) +target_include_directories ( SPQR PRIVATE ${BLAS_INCLUDE_DIRS} ) if ( NOT NSTATIC ) list ( APPEND SPQR_STATIC_LIBS ${BLAS_LIBRARIES} ) target_link_libraries ( SPQR_static PUBLIC ${BLAS_LIBRARIES} ) + target_include_directories ( SPQR_static PRIVATE ${BLAS_INCLUDE_DIRS} ) endif ( ) -include_directories ( ${BLAS_INCLUDE_DIRS} ) # CHOLMOD: -# link with CHOLMOD and its dependencies, both required and optional +# link with CHOLMOD and its dependencies target_link_libraries ( SPQR PRIVATE - SuiteSparse::CHOLMOD ${CHOLMOD_CUDA_LIBRARIES} ) + SuiteSparse::CHOLMOD ) if ( NOT NSTATIC ) - target_link_libraries ( SPQR_static PUBLIC - ${CHOLMOD_CUDA_STATIC} ) if ( TARGET SuiteSparse::CHOLMOD_static ) target_link_libraries ( SPQR_static PUBLIC SuiteSparse::CHOLMOD_static ) else ( ) @@ -296,10 +237,34 @@ endif ( ) if ( SUITESPARSE_CUDA ) # CUDA - message ( STATUS "SPQR cuda: ${SPQR_CUDA_LIBS} " ) - target_link_libraries ( SPQR PRIVATE ${SPQR_CUDA_LIBS} ${CUDA_LIBRARIES} ) + target_link_libraries ( SPQR PRIVATE SuiteSparse::CHOLMOD_CUDA SPQR_CUDA ) + # SPQR includes files from the following targets that are not installed by + # them. That looks strange and will only work before they are installed. + # Maybe, those two targets aren't actually standalone libraries but should + # be part of the SPQR project? + target_link_libraries ( SPQR PRIVATE + SuiteSparse::GPUQREngine SuiteSparse::GPURuntime ) + target_compile_definitions ( SPQR PUBLIC "SUITESPARSE_CUDA" ) + set ( SPQR_CFLAGS "-DSUITESPARSE_CUDA" ) if ( NOT NSTATIC ) - target_link_libraries ( SPQR_static PUBLIC ${SPQR_CUDA_LIBS} ${CUDA_LIBRARIES} ) + if ( TARGET SuiteSparse::CHOLMOD_CUDA_static ) + target_link_libraries ( SPQR_static PUBLIC SuiteSparse::CHOLMOD_CUDA_static ) + else ( ) + target_link_libraries ( SPQR_static PUBLIC SuiteSparse::CHOLMOD_CUDA ) + endif ( ) + target_link_libraries ( SPQR_static PUBLIC SPQR_CUDA_static ) + target_compile_definitions ( SPQR_static PUBLIC "SUITESPARSE_CUDA" ) + + if ( TARGET SuiteSparse::GPUQREngine_static ) + target_link_libraries ( SPQR_static PUBLIC SuiteSparse::GPUQREngine_static ) + else ( ) + target_link_libraries ( SPQR_static PUBLIC SuiteSparse::GPUQREngine ) + endif ( ) + if ( TARGET SuiteSparse::GPURuntime_static ) + target_link_libraries ( SPQR_static PUBLIC SuiteSparse::GPURuntime_static ) + else ( ) + target_link_libraries ( SPQR_static PUBLIC SuiteSparse::GPURuntime ) + endif ( ) endif ( ) endif ( ) @@ -413,7 +378,7 @@ endif ( ) # Demo library and programs #------------------------------------------------------------------------------- -option ( DEMO "ON: Build the demo programs. OFF (default): do not build the demo programs." off ) +option ( DEMO "ON: Build the demo programs. OFF (default): do not build the demo programs." OFF ) if ( DEMO ) #--------------------------------------------------------------------------- @@ -443,22 +408,22 @@ if ( DEMO ) endif ( ) # Libraries required for Demo programs - target_link_libraries ( qrsimple PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) - target_link_libraries ( qrsimplec PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) - target_link_libraries ( qrdemo PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) - target_link_libraries ( qrdemoc PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) + target_link_libraries ( qrsimple PUBLIC SPQR SuiteSparse::CHOLMOD ) + target_link_libraries ( qrsimplec PUBLIC SPQR SuiteSparse::CHOLMOD ) + target_link_libraries ( qrdemo PUBLIC SPQR SuiteSparse::CHOLMOD ) + target_link_libraries ( qrdemoc PUBLIC SPQR SuiteSparse::CHOLMOD ) - target_link_libraries ( qrsimplec_int32 PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) - target_link_libraries ( qrdemoc_int32 PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) - target_link_libraries ( qrdemo_int32 PUBLIC SPQR ${SPQR_CUDA_LIBS} SuiteSparse::CHOLMOD ) + target_link_libraries ( qrsimplec_int32 PUBLIC SPQR SuiteSparse::CHOLMOD ) + target_link_libraries ( qrdemoc_int32 PUBLIC SPQR SuiteSparse::CHOLMOD ) + target_link_libraries ( qrdemo_int32 PUBLIC SPQR SuiteSparse::CHOLMOD ) if ( SUITESPARSE_CUDA ) - target_link_libraries ( qrdemo_gpu PUBLIC SPQR ${SPQR_CUDA_LIBS} - SuiteSparse::CHOLMOD SuiteSparse::SuiteSparseConfig ) - target_link_libraries ( qrdemo_gpu2 PUBLIC SPQR ${SPQR_CUDA_LIBS} - SuiteSparse::CHOLMOD SuiteSparse::SuiteSparseConfig ) - target_link_libraries ( qrdemo_gpu3 PUBLIC SPQR ${SPQR_CUDA_LIBS} - SuiteSparse::CHOLMOD SuiteSparse::SuiteSparseConfig ) + target_link_libraries ( qrdemo_gpu PUBLIC SPQR SPQR_CUDA + SuiteSparse::CHOLMOD SuiteSparse::CHOLMOD_CUDA SuiteSparse::SuiteSparseConfig ) + target_link_libraries ( qrdemo_gpu2 PUBLIC SPQR SPQR_CUDA + SuiteSparse::CHOLMOD SuiteSparse::CHOLMOD_CUDA SuiteSparse::SuiteSparseConfig ) + target_link_libraries ( qrdemo_gpu3 PUBLIC SPQR SPQR_CUDA + SuiteSparse::CHOLMOD SuiteSparse::CHOLMOD_CUDA SuiteSparse::SuiteSparseConfig ) endif ( ) else ( ) diff --git a/SPQR/Config/SPQR.pc.in b/SPQR/Config/SPQR.pc.in index 83eb0b62a..65c8174e1 100644 --- a/SPQR/Config/SPQR.pc.in +++ b/SPQR/Config/SPQR.pc.in @@ -13,7 +13,7 @@ Name: SPQR URL: https://github.com/DrTimothyAldenDavis/SuiteSparse Description: Multithreaded, multifrontal, rank-revealing sparse QR factorization method in SuiteSparse Version: @SPQR_VERSION_MAJOR@.@SPQR_VERSION_MINOR@.@SPQR_VERSION_SUB@ -Requires.private: SuiteSparse_config AMD COLAMD CHOLMOD +Requires.private: SuiteSparse_config CHOLMOD Libs: -L${libdir} -lspqr Libs.private: @SPQR_STATIC_LIBS@ -Cflags: -I${includedir} +Cflags: -I${includedir} @SPQR_CFLAGS@ diff --git a/SPQR/SPQRGPU/CMakeLists.txt b/SPQR/SPQRGPU/CMakeLists.txt index ad412736e..4b4ec76a8 100644 --- a/SPQR/SPQRGPU/CMakeLists.txt +++ b/SPQR/SPQRGPU/CMakeLists.txt @@ -22,11 +22,8 @@ include ( SuiteSparsePolicy ) project ( spqr_cuda VERSION "${SPQR_VERSION_MAJOR}.${SPQR_VERSION_MINOR}.${SPQR_VERSION_SUB}" - LANGUAGES C CXX CUDA ) -set ( CMAKE_CUDA_FLAGS "-cudart=static -lineinfo -DSUITESPARSE_CUDA" ) -set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSUITESPARSE_CUDA" ) + LANGUAGES CXX ) message ( STATUS "C++ flags for CUDA: ${CMAKE_CXX_FLAGS}" ) -message ( STATUS "nvcc flags for CUDA: ${CMAKE_CUDA_FLAGS}" ) file ( GLOB SPQR_CUDA_SOURCES "spqrgpu_*.cpp" ) @@ -61,8 +58,6 @@ endif ( ) set ( SPQR_CUDA_INCLUDES ../Include ) -include_directories ( ${SPQR_CUDA_INCLUDES} ${CUDAToolkit_INCLUDE_DIRS} ) - if ( TARGET SuiteSparse::GPUQREngine ) target_include_directories ( SPQR_CUDA PRIVATE "$" ) @@ -83,14 +78,17 @@ target_include_directories ( SPQR_CUDA PRIVATE "$" ) set_target_properties ( SPQR_CUDA PROPERTIES POSITION_INDEPENDENT_CODE ON ) set_target_properties ( SPQR_CUDA PROPERTIES CUDA_SEPARABLE_COMPILATION ON ) +target_compile_definitions ( SPQR_CUDA PRIVATE "SUITESPARSE_CUDA" ) if ( NOT NSTATIC ) target_include_directories ( SPQR_CUDA_static PRIVATE ${CUDAToolkit_INCLUDE_DIRS} ${SPQR_CUDA_INCLUDES} "$" ) - set_target_properties ( SPQR_CUDA_static PROPERTIES CUDA_SEPARABLE_COMPILATION on ) - set_target_properties ( SPQR_CUDA_static PROPERTIES POSITION_INDEPENDENT_CODE on ) + set_target_properties ( SPQR_CUDA_static PROPERTIES CUDA_SEPARABLE_COMPILATION ON ) + set_target_properties ( SPQR_CUDA_static PROPERTIES POSITION_INDEPENDENT_CODE ON ) + target_compile_definitions ( SPQR_CUDA_static PRIVATE "SUITESPARSE_CUDA" ) + if ( TARGET SuiteSparse::CHOLMOD_static ) target_link_libraries ( SPQR_CUDA_static PUBLIC SuiteSparse::CHOLMOD_static ) From 717841a9577b730d6b86ff88f21c1de2fdda564e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=BCtzel?= Date: Thu, 7 Sep 2023 08:18:38 +0200 Subject: [PATCH 2/2] SPQR: Add option for OpenMP again. SPQR might use OpenMP in the future. By default, OpenMP is disabled for now to avoid over-linking. --- SPQR/CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/SPQR/CMakeLists.txt b/SPQR/CMakeLists.txt index 7d7e5e897..a0676b15e 100644 --- a/SPQR/CMakeLists.txt +++ b/SPQR/CMakeLists.txt @@ -46,6 +46,14 @@ project ( spqr # find library dependencies #------------------------------------------------------------------------------- +option ( NOPENMP "ON (default): do not use OpenMP. OFF: use OpenMP" ON ) +if ( NOPENMP ) + # OpenMP has been disabled + set ( OPENMP_FOUND false ) +else ( ) + find_package ( OpenMP ) +endif ( ) + find_package ( SuiteSparse_config 7.2.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) @@ -190,6 +198,15 @@ if ( NOT NSTATIC ) endif ( ) endif ( ) +# OpenMP: +if ( OPENMP_FOUND ) + target_link_libraries ( SPQR PRIVATE OpenMP::OpenMP_CXX ) + if ( NOT NSTATIC ) + target_link_libraries ( SPQR_static PUBLIC OpenMP::OpenMP_CXX ) + list ( APPEND SPQR_STATIC_LIBS ${OpenMP_CXX_LIBRARIES} ) + endif ( ) +endif ( ) + # libm: if ( NOT WIN32 ) target_link_libraries ( SPQR PRIVATE m )