From 04c5764d890b269e41a8da57d779d400b21d2a5c Mon Sep 17 00:00:00 2001 From: Tim Davis Date: Tue, 5 Mar 2024 09:24:34 -0600 Subject: [PATCH] add OpenMP to SPEX (required for thread safety) --- ChangeLog | 2 +- Makefile | 6 +-- README.md | 5 +++ SPEX/CMakeLists.txt | 56 ++++++++++++++++++++++++++ SPEX/Demo/spex_demo_threaded.c | 6 +++ SPEX/Makefile | 6 +-- SPEX/SPEX_Utilities/Source/SPEX_gmp.c | 1 + SPEX/TODO.txt | 2 - SuiteSparse_config/Config/README.md.in | 5 +++ 9 files changed, 80 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2bff4cc4ea..4dbc3a759a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Feb XX, 2024: version 7.7.0 +Mar XX, 2024: version 7.7.0 * SPEX 3.1.0: major revision to API, new methods. Added SPEX_Cholesky, SPEX_Backslash, and python interface. MATLAB interface revised. diff --git a/Makefile b/Makefile index 0b1d0d81d6..8305e68b34 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,9 @@ export SUITESPARSE = $(CURDIR) # Compile the default rules for each package. +# Note that CSparse is compiled but not installed by "make install"; +# CXSparse is installed instead. + # default: "make install" will install all libraries in /usr/local/lib # and include files in /usr/local/include. Not installed in SuiteSparse/lib. default: library @@ -59,7 +62,6 @@ local: ( cd CCOLAMD && $(MAKE) local ) ( cd CHOLMOD && $(MAKE) local ) ( cd CSparse && $(MAKE) ) -# CSparse is compiled but not installed ( cd CXSparse && $(MAKE) local ) ( cd LDL && $(MAKE) local ) ( cd KLU && $(MAKE) local ) @@ -83,7 +85,6 @@ global: ( cd CCOLAMD && $(MAKE) global ) ( cd CHOLMOD && $(MAKE) global ) ( cd CSparse && $(MAKE) ) -# CSparse is compiled but not installed ( cd CXSparse && $(MAKE) global ) ( cd LDL && $(MAKE) global ) ( cd KLU && $(MAKE) global ) @@ -106,7 +107,6 @@ install: ( cd CCOLAMD && $(MAKE) install ) ( cd CHOLMOD && $(MAKE) install ) ( cd CXSparse && $(MAKE) install ) -# CXSparse is installed instead ( cd LDL && $(MAKE) install ) ( cd KLU && $(MAKE) install ) ( cd UMFPACK && $(MAKE) install ) diff --git a/README.md b/README.md index 3b4edafd57..7e91a14325 100644 --- a/README.md +++ b/README.md @@ -1023,6 +1023,11 @@ build type). The static libraries will not be built (since If `ON`, OpenMP is used in ParU if it is available. Default: `SUITESPARSE_USE_OPENMP`. +* `SPEX_USE_OPENMP`: + + If `ON`, OpenMP is used in SPEX if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + * `SUITESPARSE_DEMOS`: If `ON`, build the demo programs for each package. Default: `OFF`. diff --git a/SPEX/CMakeLists.txt b/SPEX/CMakeLists.txt index 558905fa06..8216104653 100644 --- a/SPEX/CMakeLists.txt +++ b/SPEX/CMakeLists.txt @@ -40,6 +40,34 @@ set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} include ( SuiteSparsePolicy ) +#------------------------------------------------------------------------------- +# find OpenMP +#------------------------------------------------------------------------------- + +option ( SPEX_USE_OPENMP "ON: Use OpenMP in SPEX if available. OFF: Do not use OpenMP. (Default: SUITESPARSE_USE_OPENMP)" ${SUITESPARSE_USE_OPENMP} ) +if ( SPEX_USE_OPENMP ) + if ( CMAKE_VERSION VERSION_LESS 3.24 ) + find_package ( OpenMP COMPONENTS C ) + else ( ) + find_package ( OpenMP COMPONENTS C GLOBAL ) + endif ( ) +else ( ) + # OpenMP has been disabled + set ( OpenMP_C_FOUND OFF ) +endif ( ) + +if ( SPEX_USE_OPENMP AND OpenMP_C_FOUND ) + set ( SPEX_HAS_OPENMP ON ) +else ( ) + set ( SPEX_HAS_OPENMP OFF ) +endif ( ) +message ( STATUS "SPEX has OpenMP: ${SPEX_HAS_OPENMP}" ) + +# check for strict usage +if ( SUITESPARSE_USE_STRICT AND SPEX_USE_OPENMP AND NOT SPEX_HAS_OPENMP ) + message ( FATAL_ERROR "OpenMP required for SPEX but not found" ) +endif ( ) + #------------------------------------------------------------------------------- # find library dependencies #------------------------------------------------------------------------------- @@ -208,6 +236,25 @@ if ( BUILD_STATIC_LIBS ) target_include_directories ( SPEX_static SYSTEM AFTER PUBLIC ${GMP_INCLUDE_DIR} ) endif ( ) +# OpenMP: +if ( SPEX_HAS_OPENMP ) + 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}" ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( SPEX_static PRIVATE OpenMP::OpenMP_C ) + list ( APPEND SPEX_STATIC_LIBS ${OpenMP_C_LIBRARIES} ) + endif ( ) +else ( ) + # use threadprivate variables for SPEX instead of globals, so multiple user + # threads can call SPEX in parallel on different matrices. Otherwise, SPEX + # is not thread-safe (see SPEX_Utilities/Source/SPEX_gmp.c). + include ( SuiteSparse__thread ) +endif ( ) + # libm: include ( CheckSymbolExists ) check_symbol_exists ( fmax "math.h" NO_LIBM ) @@ -425,6 +472,15 @@ if ( SUITESPARSE_DEMOS ) target_link_libraries ( spex_demo_threaded PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) endif ( ) + if ( SPEX_USE_OPENMP ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( spex_demo_threaded PUBLIC OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( spex_demo_threaded PUBLIC OpenMP::OpenMP_C ) + endif ( ) + endif ( ) + else ( ) message ( STATUS "Skipping the demos in SPEX/Demo" ) diff --git a/SPEX/Demo/spex_demo_threaded.c b/SPEX/Demo/spex_demo_threaded.c index ac9f002437..05819e12db 100644 --- a/SPEX/Demo/spex_demo_threaded.c +++ b/SPEX/Demo/spex_demo_threaded.c @@ -53,6 +53,12 @@ int main( int argc, char *argv[] ) // by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- + #ifdef _OPENMP + printf ("spex_demo_threaded: with OpenMP\n") ; + #else + printf ("spex_demo_threaded: without OpenMP\n") ; + #endif + SPEX_TRY (SPEX_initialize ( )) ; //-------------------------------------------------------------------------- diff --git a/SPEX/Makefile b/SPEX/Makefile index cd662c172f..68328e2859 100644 --- a/SPEX/Makefile +++ b/SPEX/Makefile @@ -59,10 +59,10 @@ demos: ./build/spex_demo_lu_extended f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt ./build/spex_demo_lu_doub f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt ./build/spex_demo_backslash f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt - ./build/spex_demo_backslash f ExampleMats/Trefethen_500.mat.txt ExampleMats/Trefethen_500.rhs.txt - ./build/spex_demo_cholesky_simple f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt - ./build/spex_demo_cholesky_extended f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt + ./build/spex_demo_cholesky_simple f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt + ./build/spex_demo_cholesky_extended f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt ./build/spex_demo_threaded f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt + ./build/spex_demo_backslash f ExampleMats/Trefethen_500.mat.txt ExampleMats/Trefethen_500.rhs.txt cov: ( cd Tcov && $(MAKE) ) diff --git a/SPEX/SPEX_Utilities/Source/SPEX_gmp.c b/SPEX/SPEX_Utilities/Source/SPEX_gmp.c index 9a0950cc4a..8a77133f7b 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_gmp.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_gmp.c @@ -120,6 +120,7 @@ // SPEX will not be thread-safe. spex_gmp_t *spex_gmp = NULL ; + #warning "SPEX not compiled with OpenMP or thread keyword; SPEX will not be thread-safe!" #endif diff --git a/SPEX/TODO.txt b/SPEX/TODO.txt index ff59895e43..5dd17c49f3 100644 --- a/SPEX/TODO.txt +++ b/SPEX/TODO.txt @@ -1,6 +1,4 @@ -Tim: put in OpenMP - Lorena: test python interface Tim: test MATLAB interface diff --git a/SuiteSparse_config/Config/README.md.in b/SuiteSparse_config/Config/README.md.in index f123440c89..16fbb9f95a 100644 --- a/SuiteSparse_config/Config/README.md.in +++ b/SuiteSparse_config/Config/README.md.in @@ -1023,6 +1023,11 @@ build type). The static libraries will not be built (since If `ON`, OpenMP is used in ParU if it is available. Default: `SUITESPARSE_USE_OPENMP`. +* `SPEX_USE_OPENMP`: + + If `ON`, OpenMP is used in SPEX if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + * `SUITESPARSE_DEMOS`: If `ON`, build the demo programs for each package. Default: `OFF`.