Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
threading: [TBB]
include:
- os: ubuntu-latest
name: Linux
Expand All @@ -44,8 +43,8 @@ jobs:
uses: actions/cache@v5
with:
path: ${{ env.CACHE_PATH }}
key: ${{ runner.os }}-Release-${{ matrix.threading }}-cache-${{ github.sha }}
restore-keys: ${{ runner.os }}-Release-${{ matrix.threading }}-cache
key: ${{ runner.os }}-Release-cache-${{ github.sha }}
restore-keys: ${{ runner.os }}-Release-cache

- name: Prepare ccache
run: |
Expand Down
157 changes: 157 additions & 0 deletions .github/workflows/optional-dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
name: Optional Dependencies

on:
push:
branches: [main]
pull_request:

jobs:
forced-missing:
name: Forced missing (${{ matrix.name }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
name: Linux
- os: macos-latest
name: macOS
- os: windows-latest
name: Windows
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 10

- name: Configure contract test
run: >
cmake
-S tests/cmake/optional_dependencies
-B build/optional-dependencies-forced-missing
-DPOLYSOLVE_WITH_ACCELERATE=ON
-DPOLYSOLVE_WITH_CHOLMOD=OFF
-DPOLYSOLVE_WITH_UMFPACK=OFF
-DPOLYSOLVE_WITH_SUPERLU=ON
-DPOLYSOLVE_WITH_SPQR=ON
-DPOLYSOLVE_WITH_MKL=OFF
-DPOLYSOLVE_WITH_CUSOLVER=OFF
-DPOLYSOLVE_WITH_PARDISO=ON
-DPOLYSOLVE_WITH_HYPRE=OFF
-DPOLYSOLVE_WITH_AMGCL=OFF
-DPOLYSOLVE_WITH_SPECTRA=OFF
-DCMAKE_DISABLE_FIND_PACKAGE_BLAS=ON
-DCMAKE_DISABLE_FIND_PACKAGE_LAPACK=ON
-DCMAKE_DISABLE_FIND_PACKAGE_SUPERLU=ON
-DCMAKE_DISABLE_FIND_PACKAGE_Pardiso=ON
-DCMAKE_DISABLE_FIND_PACKAGE_SPQR=ON
-DPOLYSOLVE_EXPECT_ACCELERATE=OFF
-DPOLYSOLVE_EXPECT_SUPERLU=OFF
-DPOLYSOLVE_EXPECT_SPQR=OFF
-DPOLYSOLVE_EXPECT_PARDISO=OFF

all-off:
name: All optional solvers off (${{ matrix.name }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
name: Linux
- os: macos-latest
name: macOS
- os: windows-latest
name: Windows
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 10

- name: Configure contract test
run: >
cmake
-S tests/cmake/optional_dependencies
-B build/optional-dependencies-all-off
-DPOLYSOLVE_WITH_ACCELERATE=OFF
-DPOLYSOLVE_WITH_CHOLMOD=OFF
-DPOLYSOLVE_WITH_UMFPACK=OFF
-DPOLYSOLVE_WITH_SUPERLU=OFF
-DPOLYSOLVE_WITH_SPQR=OFF
-DPOLYSOLVE_WITH_MKL=OFF
-DPOLYSOLVE_WITH_CUSOLVER=OFF
-DPOLYSOLVE_WITH_PARDISO=OFF
-DPOLYSOLVE_WITH_HYPRE=OFF
-DPOLYSOLVE_WITH_AMGCL=OFF
-DPOLYSOLVE_WITH_SPECTRA=OFF

accelerate:
name: Accelerate available (macOS)
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 10

- name: Configure contract test
run: >
cmake
-S tests/cmake/optional_dependencies
-B build/optional-dependencies-accelerate
-DPOLYSOLVE_WITH_ACCELERATE=ON
-DPOLYSOLVE_WITH_CHOLMOD=OFF
-DPOLYSOLVE_WITH_UMFPACK=OFF
-DPOLYSOLVE_WITH_SUPERLU=OFF
-DPOLYSOLVE_WITH_SPQR=OFF
-DPOLYSOLVE_WITH_MKL=OFF
-DPOLYSOLVE_WITH_CUSOLVER=OFF
-DPOLYSOLVE_WITH_PARDISO=OFF
-DPOLYSOLVE_WITH_HYPRE=OFF
-DPOLYSOLVE_WITH_AMGCL=OFF
-DPOLYSOLVE_WITH_SPECTRA=OFF
-DPOLYSOLVE_EXPECT_ACCELERATE=ON

- name: Build polysolve_linear
run: cmake --build build/optional-dependencies-accelerate --target polysolve_linear --parallel 2

suitesparse:
name: SuiteSparse available (Linux)
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 10

- name: Dependencies
run: |
sudo apt-get update
sudo apt-get -o Acquire::Retries=3 install \
libblas-dev \
liblapack-dev \
libsuitesparse-dev

- name: Configure contract test
run: >
cmake
-S tests/cmake/optional_dependencies
-B build/optional-dependencies-suitesparse
-DPOLYSOLVE_WITH_ACCELERATE=OFF
-DPOLYSOLVE_WITH_CHOLMOD=ON
-DPOLYSOLVE_WITH_UMFPACK=ON
-DPOLYSOLVE_WITH_SUPERLU=OFF
-DPOLYSOLVE_WITH_SPQR=OFF
-DPOLYSOLVE_WITH_MKL=OFF
-DPOLYSOLVE_WITH_CUSOLVER=OFF
-DPOLYSOLVE_WITH_PARDISO=OFF
-DPOLYSOLVE_WITH_HYPRE=OFF
-DPOLYSOLVE_WITH_AMGCL=OFF
-DPOLYSOLVE_WITH_SPECTRA=OFF
-DPOLYSOLVE_EXPECT_CHOLMOD=ON
-DPOLYSOLVE_EXPECT_UMFPACK=ON

- name: Build polysolve_linear
run: cmake --build build/optional-dependencies-suitesparse --target polysolve_linear --parallel 2
110 changes: 74 additions & 36 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,24 @@ project(PolySolve
DESCRIPTION "Easy-to-use wrapper for linear solver"
LANGUAGES CXX)

if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64" AND APPLE)
set(POLYSOLVE_NOT_ON_APPLE_SILICON OFF)
set(POLYSOLVE_ON_ARM OFF)
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR};${CMAKE_HOST_SYSTEM_PROCESSOR};${CMAKE_OSX_ARCHITECTURES}" POLYSOLVE_ARCHITECTURES)
if(POLYSOLVE_ARCHITECTURES MATCHES "(^|[^a-z0-9_])(arm64|aarch64)([^a-z0-9_]|$)")
set(POLYSOLVE_ON_ARM ON)
endif()

if(APPLE AND POLYSOLVE_ON_ARM)
set(POLYSOLVE_ON_APPLE_SILICON ON)
else()
set(POLYSOLVE_NOT_ON_APPLE_SILICON ON)
set(POLYSOLVE_ON_APPLE_SILICON OFF)
endif()

if(POLYSOLVE_ON_ARM)
set(POLYSOLVE_WITH_MKL_DEFAULT OFF)
else()
set(POLYSOLVE_WITH_MKL_DEFAULT ON)
endif()

# Polysolve options
option(POLYSOLVE_WITH_SANITIZERS "Enable sanitizers in compilation targets" OFF)
option(POLYSOLVE_WITH_UNICODE "Use Unicode in logging messages" ON)
Expand All @@ -82,7 +92,7 @@ option(POLYSOLVE_WITH_CHOLMOD "Enable Cholmod library"
option(POLYSOLVE_WITH_UMFPACK "Enable UmfPack library" ON)
option(POLYSOLVE_WITH_SUPERLU "Enable SuperLU library" ON)
option(POLYSOLVE_WITH_SPQR "Enable SPQR library" ON)
option(POLYSOLVE_WITH_MKL "Enable MKL library" ${POLYSOLVE_NOT_ON_APPLE_SILICON})
option(POLYSOLVE_WITH_MKL "Enable MKL library" ${POLYSOLVE_WITH_MKL_DEFAULT})
option(POLYSOLVE_WITH_CUSOLVER "Enable cuSOLVER library" OFF)
option(POLYSOLVE_WITH_PARDISO "Enable Pardiso library" OFF)
option(POLYSOLVE_WITH_HYPRE "Enable hypre" ON)
Expand Down Expand Up @@ -133,6 +143,7 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/find/")
# General CMake utils
include(polysolve_cpm_cache)
include(polysolve_use_colors)
include(polysolve_optional_dependency)

# Sort projects inside the solution
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
Expand All @@ -142,7 +153,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Since MKL comes precompiled with /MD on Windows, we need to use the same MSVC runtime library flag
# globally for the whole project (otherwise in Debug we will have a mismatch between /MD and /MDd).
if(POLYSOLVE_WITH_MKL)
if(MSVC AND POLYSOLVE_WITH_MKL)
# Set MSVC runtime library globally for all targets
message(STATUS "Forcing /MD globally due MKL being enabled")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "Select the MSVC runtime library")
Expand Down Expand Up @@ -195,18 +206,26 @@ target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_JSON_SPEC_DIR="${PR

# Accelerate solver (Include before Eigen)
if(POLYSOLVE_WITH_ACCELERATE)
include(CPM)
CPMAddPackage(
NAME eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 969c31eefcdfaab11da763bea3f7502086673ab0
DOWNLOAD_ONLY ON
)
set(BLA_VENDOR Apple)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
target_link_libraries(polysolve_linear PRIVATE BLAS::BLAS LAPACK::LAPACK)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_ACCELERATE)
include(accelerate)
if(TARGET polysolve::accelerate)
target_link_libraries(polysolve_linear PRIVATE polysolve::accelerate)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_ACCELERATE)
else()
polysolve_note_disabled_dependency("Accelerate" "Target 'polysolve::accelerate' was not created.")
endif()
endif()

# MKL library (probe before Eigen so Eigen only uses MKL when it is usable)
if(POLYSOLVE_WITH_MKL)
if(POLYSOLVE_ON_ARM)
polysolve_note_disabled_dependency("MKL" "MKL is disabled for ARM targets.")
else()
include(mkl)
endif()
endif()

if(EIGEN_WITH_MKL AND NOT TARGET mkl::mkl)
set(EIGEN_WITH_MKL OFF CACHE BOOL "Use Eigen with MKL" FORCE)
endif()

include(eigen)
Expand All @@ -227,23 +246,30 @@ target_link_libraries(polysolve_linear PUBLIC jse::jse)
# Hypre (GNU Lesser General Public License)
if(POLYSOLVE_WITH_HYPRE)
include(hypre)
target_link_libraries(polysolve_linear PUBLIC HYPRE::HYPRE)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_HYPRE)
if(HYPRE_WITH_MPI)
target_compile_definitions(polysolve_linear PUBLIC HYPRE_WITH_MPI)
if(TARGET HYPRE::HYPRE)
target_link_libraries(polysolve_linear PUBLIC HYPRE::HYPRE)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_HYPRE)
if(HYPRE_WITH_MPI)
target_compile_definitions(polysolve_linear PUBLIC HYPRE_WITH_MPI)
endif()
else()
polysolve_note_disabled_dependency("HYPRE" "Target 'HYPRE::HYPRE' was not created.")
endif()
endif()

# CHOLMOD solver
if(POLYSOLVE_WITH_CHOLMOD)
include(suitesparse)
target_link_libraries(polysolve_linear PRIVATE SuiteSparse::CHOLMOD)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_CHOLMOD)
if(TARGET SuiteSparse::CHOLMOD)
target_link_libraries(polysolve_linear PRIVATE SuiteSparse::CHOLMOD)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_CHOLMOD)
else()
polysolve_note_disabled_dependency("CHOLMOD" "Target 'SuiteSparse::CHOLMOD' was not created.")
endif()
endif()

# MKL library
if(POLYSOLVE_WITH_MKL)
include(mkl)
# MKL solver support
if(TARGET mkl::mkl)
target_link_libraries(polysolve_linear PRIVATE mkl::mkl)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_MKL)
endif()
Expand All @@ -255,15 +281,19 @@ if(POLYSOLVE_WITH_PARDISO)
target_link_libraries(polysolve_linear PRIVATE Pardiso::Pardiso)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_PARDISO)
else()
message(WARNING "Pardiso not found, solver will not be available.")
polysolve_note_disabled_dependency("Pardiso" "Target 'Pardiso::Pardiso' was not created.")
endif()
endif()

# UmfPack solver
if(POLYSOLVE_WITH_UMFPACK)
include(suitesparse)
target_link_libraries(polysolve_linear PRIVATE SuiteSparse::UMFPACK)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_UMFPACK)
if(TARGET SuiteSparse::UMFPACK)
target_link_libraries(polysolve_linear PRIVATE SuiteSparse::UMFPACK)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_UMFPACK)
else()
polysolve_note_disabled_dependency("UMFPACK" "Target 'SuiteSparse::UMFPACK' was not created.")
endif()
endif()

# SuperLU solver
Expand All @@ -273,33 +303,41 @@ if(POLYSOLVE_WITH_SUPERLU)
target_link_libraries(polysolve_linear PRIVATE SuperLU::SuperLU)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_SUPERLU)
else()
message(WARNING "SuperLU not found, solver will not be available.")
polysolve_note_disabled_dependency("SuperLU" "Target 'SuperLU::SuperLU' was not created.")
endif()
endif()

# SuperLU solver
# SPQR solver
if(POLYSOLVE_WITH_SPQR)
include(spqr)
if(TARGET SuiteSparse::SPQR)
target_link_libraries(polysolve_linear PRIVATE SuiteSparse::SPQR)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_SPQR)
else()
message(WARNING "SPQR Not found, solver will not be available.")
polysolve_note_disabled_dependency("SPQR" "Target 'SuiteSparse::SPQR' was not created.")
endif()
endif()

# AMGCL solver
if(POLYSOLVE_WITH_AMGCL)
include(amgcl)
target_link_libraries(polysolve_linear PUBLIC amgcl::amgcl)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_AMGCL)
if(TARGET amgcl::amgcl)
target_link_libraries(polysolve_linear PUBLIC amgcl::amgcl)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_AMGCL)
else()
polysolve_note_disabled_dependency("AMGCL" "Target 'amgcl::amgcl' was not created.")
endif()
endif()

# Spectra (MPL 2.0)
if(POLYSOLVE_WITH_SPECTRA)
include(spectra)
target_link_libraries(polysolve_linear PUBLIC Spectra::Spectra)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_SPECTRA)
if(TARGET Spectra::Spectra)
target_link_libraries(polysolve_linear PUBLIC Spectra::Spectra)
target_compile_definitions(polysolve_linear PUBLIC POLYSOLVE_WITH_SPECTRA)
else()
polysolve_note_disabled_dependency("Spectra" "Target 'Spectra::Spectra' was not created.")
endif()
endif()

# cuSolver solvers
Expand Down
2 changes: 1 addition & 1 deletion cmake/find/FindPardiso.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ find_library(PARDISO_LIBRARIES
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PARDISO DEFAULT_MSG PARDISO_LIBRARIES)
find_package_handle_standard_args(Pardiso DEFAULT_MSG PARDISO_LIBRARIES)

mark_as_advanced(PARDISO_LIBRARIES)
Loading
Loading