From 9436ff4221744c3242aa207c25bb9b4b226a6c42 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Thu, 22 Jun 2023 13:42:02 -0700 Subject: [PATCH 01/13] Working sympiler wrapper --- CMakeLists.txt | 10 ++++- cmake/recipes/CPM.cmake | 36 ++++++++++++++++ cmake/recipes/sympiler.cmake | 41 ++++++++++++++++++ src/CMakeLists.txt | 2 + src/polysolve/LinearSolver.cpp | 12 ++++++ src/polysolve/LinearSolverSympiler.cpp | 59 ++++++++++++++++++++++++++ src/polysolve/LinearSolverSympiler.hpp | 49 +++++++++++++++++++++ 7 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 cmake/recipes/CPM.cmake create mode 100644 cmake/recipes/sympiler.cmake create mode 100644 src/polysolve/LinearSolverSympiler.cpp create mode 100644 src/polysolve/LinearSolverSympiler.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a7b3e3..bcbf489 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ endif() # Polysolve options option(POLYSOLVE_WITH_SANITIZERS "Enable sanitizers in compilation targets" OFF) # Polysolve options for enabling/disabling optional libraries +option(POLYSOLVE_WITH_SYMPILER "Enable sympiler library" ON) option(POLYSOLVE_WITH_ACCELERATE "Enable Apple Accelerate" ${POLYSOLVE_ON_APPLE_SILICON}) option(POLYSOLVE_WITH_CHOLMOD "Enable Cholmod library" ON) option(POLYSOLVE_WITH_UMFPACK "Enable UmfPack library" ON) @@ -160,7 +161,14 @@ endif() include(json) target_link_libraries(polysolve PUBLIC nlohmann_json::nlohmann_json) -# Accelerate solvers +# Polysolve solver +if (POLYSOLVE_WITH_SYMPILER) + include(sympiler) + target_link_libraries(polysolve PUBLIC sympiler::sym_sparse_blas) + target_compile_definitions(polysolve PUBLIC -DPOLYSOLVE_WITH_SYMPILER) +endif() + +# Accelerate solver if(POLYSOLVE_WITH_ACCELERATE) target_compile_definitions(polysolve PUBLIC -DPOLYSOLVE_WITH_ACCELERATE) endif() diff --git a/cmake/recipes/CPM.cmake b/cmake/recipes/CPM.cmake new file mode 100644 index 0000000..c8266bd --- /dev/null +++ b/cmake/recipes/CPM.cmake @@ -0,0 +1,36 @@ +# Source: https://github.com/cpm-cmake/CPM.cmake/blob/master/cmake/get_cpm.cmake +# SPDX-License-Identifier: MIT + +set(CPM_DOWNLOAD_VERSION 0.38.1) + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +function(download_cpm) + message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") + file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} + ) +endfunction() + +if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) + download_cpm() +else() + # resume download if it previously failed + file(READ ${CPM_DOWNLOAD_LOCATION} check) + if("${check}" STREQUAL "") + download_cpm() + endif() + unset(check) +endif() + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake new file mode 100644 index 0000000..2ffc9be --- /dev/null +++ b/cmake/recipes/sympiler.cmake @@ -0,0 +1,41 @@ +# +# Copyright 2020 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# +if(TARGET sympiler::sym_sparse_blas) + return() +endif() + +message(STATUS "Third-party (external): creating target 'sympiler::sym_sparse_blas'") + +if(APPLE) +include(CPM) + CPMAddPackage( + NAME sympiler + GITHUB_REPOSITORY ryansynk/sympiler + GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf + OPTIONS "SYMPILER_BLAS_BACKEND Apple" + ) +else() + CPMAddPackage( + NAME sympiler + GITHUB_REPOSITORY ryansynk/sympiler + GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf + ) +endif() + +add_library(sympiler INTERFACE) +add_library(sympiler::sym_sparse_blas ALIAS sym_sparse_blas) + +include(GNUInstallDirs) +target_include_directories(sym_sparse_blas INTERFACE + "$/include" + "$" +) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cfba8a3..bd7040b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,8 @@ set(SOURCES polysolve/LinearSolverEigen.tpp polysolve/LinearSolverHypre.cpp polysolve/LinearSolverHypre.hpp + polysolve/LinearSolverSympiler.hpp + polysolve/LinearSolverSympiler.cpp polysolve/LinearSolverPardiso.cpp polysolve/LinearSolverPardiso.hpp polysolve/SaddlePointSolver.cpp diff --git a/src/polysolve/LinearSolver.cpp b/src/polysolve/LinearSolver.cpp index d9f0a47..3cd55f5 100644 --- a/src/polysolve/LinearSolver.cpp +++ b/src/polysolve/LinearSolver.cpp @@ -5,6 +5,9 @@ // ----------------------------------------------------------------------------- #include +#ifdef POLYSOLVE_WITH_SYMPILER +#include +#endif #ifdef POLYSOLVE_WITH_ACCELERATE #include #endif @@ -191,6 +194,12 @@ namespace polysolve else if (solver == "Eigen::SparseLU") { RETURN_DIRECT_SOLVER_PTR(SparseLU, "Eigen::SparseLU"); +#ifdef POLYSOLVE_WITH_SYMPILER + } + else if (solver == "Sympiler") + { + return std::make_unique(); +#endif #ifdef POLYSOLVE_WITH_ACCELERATE } else if (solver == "Eigen::AccelerateLLT") @@ -363,6 +372,9 @@ namespace polysolve return {{ "Eigen::SimplicialLDLT", "Eigen::SparseLU", +#ifdef POLYSOLVE_WITH_SYMPILER + "Sympiler", +#endif #ifdef POLYSOLVE_WITH_ACCELERATE "Eigen::AccelerateLLT", "Eigen::AccelerateLDLT", diff --git a/src/polysolve/LinearSolverSympiler.cpp b/src/polysolve/LinearSolverSympiler.cpp new file mode 100644 index 0000000..bfab90b --- /dev/null +++ b/src/polysolve/LinearSolverSympiler.cpp @@ -0,0 +1,59 @@ +#ifdef POLYSOLVE_WITH_SYMPILER + +#include +#include +#include + +namespace polysolve +{ + // void LinearSolverSympiler::setParameters(const json ¶ms) {} + + // Retrieve memory information from Sympiler + // void LinearSolverSympiler::getInfo(json ¶ms) const {} + + // Analyze sparsity pattern + void LinearSolverSympiler::analyzePattern(const StiffnessMatrix &A, const int precond_num) + { + StiffnessMatrix A_copy = StiffnessMatrix(A); + + A_csc_->nzmax = A_copy.nonZeros(); + A_csc_->ncol= A_csc_->nrow=A_copy.rows(); + A_csc_->p = A_copy.outerIndexPtr(); + A_csc_->i = A_copy.innerIndexPtr(); + + A_csc_->x = A_copy.valuePtr(); + A_csc_->stype=-1; + A_csc_->packed=1; + A_csc_->nz = nullptr; + + solver_ = new sym_lib::parsy::SolverSettings(A_csc_); + solver_->symbolic_analysis(); + } + + // Factorize system matrix + void LinearSolverSympiler::factorize(const StiffnessMatrix &A) + { + StiffnessMatrix A_copy = StiffnessMatrix(A); + + A_csc_->nzmax = A_copy.nonZeros(); + A_csc_->ncol= A_csc_->nrow=A_copy.rows(); + A_csc_->p = A_copy.outerIndexPtr(); + A_csc_->i = A_copy.innerIndexPtr(); + + A_csc_->x = A_copy.valuePtr(); + A_csc_->stype=-1; + A_csc_->packed=1; + A_csc_->nz = nullptr; + solver_->numerical_factorization(A_csc_); + } + + // Solve the linear system Ax = b + void LinearSolverSympiler::solve(const Ref b, Ref x) + { + double* x_ptr = solver_->solve_only(b.data()); + x = Eigen::Map(x_ptr, x.rows(), x.cols()); + } + +} // namespace polysolve + +#endif \ No newline at end of file diff --git a/src/polysolve/LinearSolverSympiler.hpp b/src/polysolve/LinearSolverSympiler.hpp new file mode 100644 index 0000000..6d65e02 --- /dev/null +++ b/src/polysolve/LinearSolverSympiler.hpp @@ -0,0 +1,49 @@ +#ifdef POLYSOLVE_WITH_SYMPILER + +#include +#include +#include +#include + +namespace polysolve +{ + class LinearSolverSympiler : public LinearSolver + { + public: + LinearSolverSympiler() = default; + ~LinearSolverSympiler() = default; + + private: + POLYSOLVE_DELETE_MOVE_COPY(LinearSolverSympiler) + + public: + ////////////////////// + // Public interface // + ////////////////////// + + // Set solver parameters + // virtual void setParameters(const json ¶ms) override; + + // Retrieve memory information from Sympiler + // virtual void getInfo(json ¶ms) const override; + + // Analyze sparsity pattern + virtual void analyzePattern(const StiffnessMatrix &A, const int precond_num) override; + + // Factorize system matrix + virtual void factorize(const StiffnessMatrix &A) override; + + // Solve the linear system Ax = b + virtual void solve(const Ref b, Ref x) override; + + // Name of the solver type (for debugging purposes) + virtual std::string name() const override { return "Sympiler"; } + + private: + sym_lib::parsy::SolverSettings *solver_ = nullptr; + sym_lib::parsy::CSC *A_csc_ = new sym_lib::parsy::CSC; + + }; +} // namespace polysolve + +#endif \ No newline at end of file From afa30dd926b80c7558b678317cede93c698fea21 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Thu, 22 Jun 2023 14:47:05 -0700 Subject: [PATCH 02/13] Fixed bug in LinearSolverSympiler::factorize --- src/polysolve/LinearSolverSympiler.cpp | 53 ++++++++++++++++++-------- src/polysolve/LinearSolverSympiler.hpp | 16 ++++++-- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/polysolve/LinearSolverSympiler.cpp b/src/polysolve/LinearSolverSympiler.cpp index bfab90b..e1056b6 100644 --- a/src/polysolve/LinearSolverSympiler.cpp +++ b/src/polysolve/LinearSolverSympiler.cpp @@ -6,24 +6,46 @@ namespace polysolve { - // void LinearSolverSympiler::setParameters(const json ¶ms) {} + void LinearSolverSympiler::setSolverMode(int _solver_mode) + { + solver_mode = _solver_mode; + } - // Retrieve memory information from Sympiler - // void LinearSolverSympiler::getInfo(json ¶ms) const {} + void LinearSolverSympiler::setParameters(const json ¶ms) + { + if (params.contains("Sympiler")) + { + if (params["Sympiler"].contains("solver_mode")) + { + setSolverMode(params["Sympiler"]["mtype"].get()); + } + } + } + + void LinearSolverSympiler::getInfo(json ¶ms) const + { + if (factorize_status == 1) + { + params["factorize_info"] = "Success"; + } + else + { + params["factorize_info"] = "Failure"; + } + } - // Analyze sparsity pattern - void LinearSolverSympiler::analyzePattern(const StiffnessMatrix &A, const int precond_num) + void LinearSolverSympiler::analyzePattern(const StiffnessMatrix &A, const int precond_num) { StiffnessMatrix A_copy = StiffnessMatrix(A); A_csc_->nzmax = A_copy.nonZeros(); - A_csc_->ncol= A_csc_->nrow=A_copy.rows(); + A_csc_->ncol = A_csc_->nrow = A_copy.rows(); A_csc_->p = A_copy.outerIndexPtr(); A_csc_->i = A_copy.innerIndexPtr(); A_csc_->x = A_copy.valuePtr(); - A_csc_->stype=-1; - A_csc_->packed=1; + A_csc_->stype = -1; + A_csc_->packed = 1; A_csc_->nz = nullptr; solver_ = new sym_lib::parsy::SolverSettings(A_csc_); @@ -31,26 +53,27 @@ namespace polysolve } // Factorize system matrix - void LinearSolverSympiler::factorize(const StiffnessMatrix &A) + void LinearSolverSympiler::factorize(const StiffnessMatrix &A) { + // This copy isn't always necessary if matrix doesn't change StiffnessMatrix A_copy = StiffnessMatrix(A); A_csc_->nzmax = A_copy.nonZeros(); - A_csc_->ncol= A_csc_->nrow=A_copy.rows(); + A_csc_->ncol = A_csc_->nrow = A_copy.rows(); A_csc_->p = A_copy.outerIndexPtr(); A_csc_->i = A_copy.innerIndexPtr(); A_csc_->x = A_copy.valuePtr(); - A_csc_->stype=-1; - A_csc_->packed=1; + A_csc_->stype = -1; + A_csc_->packed = 1; A_csc_->nz = nullptr; - solver_->numerical_factorization(A_csc_); + factorize_status = solver_->numerical_factorization(A_csc_); } // Solve the linear system Ax = b - void LinearSolverSympiler::solve(const Ref b, Ref x) + void LinearSolverSympiler::solve(const Ref b, Ref x) { - double* x_ptr = solver_->solve_only(b.data()); + double *x_ptr = solver_->solve_only(b.data()); x = Eigen::Map(x_ptr, x.rows(), x.cols()); } diff --git a/src/polysolve/LinearSolverSympiler.hpp b/src/polysolve/LinearSolverSympiler.hpp index 6d65e02..705f7e9 100644 --- a/src/polysolve/LinearSolverSympiler.hpp +++ b/src/polysolve/LinearSolverSympiler.hpp @@ -16,16 +16,19 @@ namespace polysolve private: POLYSOLVE_DELETE_MOVE_COPY(LinearSolverSympiler) + protected: + void setSolverMode(int _solver_mode); + public: ////////////////////// // Public interface // ////////////////////// // Set solver parameters - // virtual void setParameters(const json ¶ms) override; + virtual void setParameters(const json ¶ms) override; - // Retrieve memory information from Sympiler - // virtual void getInfo(json ¶ms) const override; + // Retrieve status (success/failure) of factorization + virtual void getInfo(json ¶ms) const override; // Analyze sparsity pattern virtual void analyzePattern(const StiffnessMatrix &A, const int precond_num) override; @@ -43,6 +46,13 @@ namespace polysolve sym_lib::parsy::SolverSettings *solver_ = nullptr; sym_lib::parsy::CSC *A_csc_ = new sym_lib::parsy::CSC; + protected: + //////////////////// + // Sympiler stuff // + //////////////////// + int solver_mode = 0; //0 is normal solve, 1 is row/col addition + int factorize_status; + }; } // namespace polysolve From 3045d065c8d92e992507d991544ee73b6381bb12 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Thu, 22 Jun 2023 15:11:43 -0700 Subject: [PATCH 03/13] Fixed build errorr --- cmake/recipes/sympiler.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index 2ffc9be..7f3cb56 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -24,6 +24,7 @@ include(CPM) OPTIONS "SYMPILER_BLAS_BACKEND Apple" ) else() +include(CPM) CPMAddPackage( NAME sympiler GITHUB_REPOSITORY ryansynk/sympiler From f062fae4dc627428a3eb581c4a3b07ef6d37b90e Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Thu, 22 Jun 2023 15:33:27 -0700 Subject: [PATCH 04/13] Changed linux/windows to build with MKL --- cmake/recipes/sympiler.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index 7f3cb56..a0d7864 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -29,6 +29,7 @@ include(CPM) NAME sympiler GITHUB_REPOSITORY ryansynk/sympiler GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf + OPTIONS "SYMPILER_BLAS_BACKEND MKL" ) endif() From d888656755e8465ddd3264bd4964adf0ee5d5f00 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Thu, 22 Jun 2023 15:52:32 -0700 Subject: [PATCH 05/13] Added MKL Include statement --- cmake/recipes/sympiler.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index a0d7864..6ed9e8b 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -24,6 +24,7 @@ include(CPM) OPTIONS "SYMPILER_BLAS_BACKEND Apple" ) else() +include(mkl) include(CPM) CPMAddPackage( NAME sympiler From d4f790fc24ed25690c3f23f58164ceb0f71df85e Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Fri, 23 Jun 2023 12:56:51 -0700 Subject: [PATCH 06/13] Refactored wrapper with smart pointers --- cmake/recipes/sympiler.cmake | 32 +++++++-------- src/polysolve/LinearSolverSympiler.cpp | 54 ++++++++++++-------------- src/polysolve/LinearSolverSympiler.hpp | 16 ++++---- 3 files changed, 49 insertions(+), 53 deletions(-) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index 6ed9e8b..583aa0d 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -15,25 +15,25 @@ endif() message(STATUS "Third-party (external): creating target 'sympiler::sym_sparse_blas'") -if(APPLE) -include(CPM) - CPMAddPackage( - NAME sympiler - GITHUB_REPOSITORY ryansynk/sympiler - GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf - OPTIONS "SYMPILER_BLAS_BACKEND Apple" - ) +if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm64" OR "${CMAKE_OSX_ARCHITECTURES}" MATCHES "arm64") + # apple M1 + set(SYMPILER_BLAS_BACKEND "Apple" CACHE STRING "BLAS implementation for SYMPILER to use") else() -include(mkl) -include(CPM) - CPMAddPackage( - NAME sympiler - GITHUB_REPOSITORY ryansynk/sympiler - GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf - OPTIONS "SYMPILER_BLAS_BACKEND MKL" - ) + # windows, linux, apple intel + set(SYMPILER_BLAS_BACKEND "MKL" CACHE STRING "BLAS implementation for SYMPILER to use") +endif() + +if(SYMPILER_BLAS_BACKEND STREQUAL "MKL") + include(mkl) endif() +include(CPM) +CPMAddPackage( + NAME sympiler + GITHUB_REPOSITORY ryansynk/sympiler + GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf +) + add_library(sympiler INTERFACE) add_library(sympiler::sym_sparse_blas ALIAS sym_sparse_blas) diff --git a/src/polysolve/LinearSolverSympiler.cpp b/src/polysolve/LinearSolverSympiler.cpp index e1056b6..913a4c7 100644 --- a/src/polysolve/LinearSolverSympiler.cpp +++ b/src/polysolve/LinearSolverSympiler.cpp @@ -1,7 +1,6 @@ #ifdef POLYSOLVE_WITH_SYMPILER #include -#include #include namespace polysolve @@ -11,6 +10,19 @@ namespace polysolve solver_mode = _solver_mode; } + void LinearSolverSympiler::updateCSC() + { + m_A_csc->nzmax = m_A_copy.nonZeros(); + m_A_csc->ncol = m_A_csc->nrow = m_A_copy.rows(); + m_A_csc->p = m_A_copy.outerIndexPtr(); + m_A_csc->i = m_A_copy.innerIndexPtr(); + + m_A_csc->x = m_A_copy.valuePtr(); + m_A_csc->stype = -1; + m_A_csc->packed = 1; + m_A_csc->nz = nullptr; + } + void LinearSolverSympiler::setParameters(const json ¶ms) { if (params.contains("Sympiler")) @@ -36,44 +48,28 @@ namespace polysolve void LinearSolverSympiler::analyzePattern(const StiffnessMatrix &A, const int precond_num) { - StiffnessMatrix A_copy = StiffnessMatrix(A); - - A_csc_->nzmax = A_copy.nonZeros(); - A_csc_->ncol = A_csc_->nrow = A_copy.rows(); - A_csc_->p = A_copy.outerIndexPtr(); - A_csc_->i = A_copy.innerIndexPtr(); - - A_csc_->x = A_copy.valuePtr(); - A_csc_->stype = -1; - A_csc_->packed = 1; - A_csc_->nz = nullptr; - - solver_ = new sym_lib::parsy::SolverSettings(A_csc_); - solver_->symbolic_analysis(); + m_A_copy = StiffnessMatrix(A); + updateCSC(); + m_solver = std::make_unique(m_A_csc.get()); + m_solver->symbolic_analysis(); } // Factorize system matrix void LinearSolverSympiler::factorize(const StiffnessMatrix &A) { - // This copy isn't always necessary if matrix doesn't change - StiffnessMatrix A_copy = StiffnessMatrix(A); - - A_csc_->nzmax = A_copy.nonZeros(); - A_csc_->ncol = A_csc_->nrow = A_copy.rows(); - A_csc_->p = A_copy.outerIndexPtr(); - A_csc_->i = A_copy.innerIndexPtr(); - - A_csc_->x = A_copy.valuePtr(); - A_csc_->stype = -1; - A_csc_->packed = 1; - A_csc_->nz = nullptr; - factorize_status = solver_->numerical_factorization(A_csc_); + // Only copy when matrix changes + if (!m_A_copy.isApprox(A)) + { + m_A_copy = StiffnessMatrix(A); + updateCSC(); + } + factorize_status = m_solver->numerical_factorization(m_A_csc.get()); } // Solve the linear system Ax = b void LinearSolverSympiler::solve(const Ref b, Ref x) { - double *x_ptr = solver_->solve_only(b.data()); + double *x_ptr = m_solver->solve_only(b.data()); x = Eigen::Map(x_ptr, x.rows(), x.cols()); } diff --git a/src/polysolve/LinearSolverSympiler.hpp b/src/polysolve/LinearSolverSympiler.hpp index 705f7e9..4594d1f 100644 --- a/src/polysolve/LinearSolverSympiler.hpp +++ b/src/polysolve/LinearSolverSympiler.hpp @@ -2,15 +2,14 @@ #include #include -#include -#include namespace polysolve { class LinearSolverSympiler : public LinearSolver { public: - LinearSolverSympiler() = default; + LinearSolverSympiler() + : m_solver(nullptr), m_A_csc(std::make_unique()) {} ~LinearSolverSympiler() = default; private: @@ -18,6 +17,7 @@ namespace polysolve protected: void setSolverMode(int _solver_mode); + void updateCSC(); public: ////////////////////// @@ -43,16 +43,16 @@ namespace polysolve virtual std::string name() const override { return "Sympiler"; } private: - sym_lib::parsy::SolverSettings *solver_ = nullptr; - sym_lib::parsy::CSC *A_csc_ = new sym_lib::parsy::CSC; + std::unique_ptr m_solver; + std::unique_ptr m_A_csc; + polysolve::StiffnessMatrix m_A_copy; protected: //////////////////// // Sympiler stuff // //////////////////// - int solver_mode = 0; //0 is normal solve, 1 is row/col addition - int factorize_status; - + int solver_mode = 0; // 0 is normal solve, 1 is row/col addition + int factorize_status = -1; }; } // namespace polysolve From 9a0ce059e27e257504c9165e723690a01fd03f0d Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Fri, 23 Jun 2023 13:10:19 -0700 Subject: [PATCH 07/13] Updated to virtual destructor --- src/polysolve/LinearSolverSympiler.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/polysolve/LinearSolverSympiler.hpp b/src/polysolve/LinearSolverSympiler.hpp index 4594d1f..0a3a57d 100644 --- a/src/polysolve/LinearSolverSympiler.hpp +++ b/src/polysolve/LinearSolverSympiler.hpp @@ -10,7 +10,7 @@ namespace polysolve public: LinearSolverSympiler() : m_solver(nullptr), m_A_csc(std::make_unique()) {} - ~LinearSolverSympiler() = default; + virtual ~LinearSolverSympiler() = default; private: POLYSOLVE_DELETE_MOVE_COPY(LinearSolverSympiler) From bd6422379c9f0034d3315a624441757f814a8f87 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Fri, 23 Jun 2023 15:50:12 -0700 Subject: [PATCH 08/13] Updated MKL settings for sympiler --- cmake/recipes/sympiler.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index 583aa0d..bc4d878 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -24,7 +24,11 @@ else() endif() if(SYMPILER_BLAS_BACKEND STREQUAL "MKL") + message("INCLUDING MKL") include(mkl) + if(NOT TARGET MKL::MKL) + add_library(MKL::MKL ALIAS mkl::mkl) + endif() endif() include(CPM) @@ -32,9 +36,9 @@ CPMAddPackage( NAME sympiler GITHUB_REPOSITORY ryansynk/sympiler GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf + OPTIONS "SYMPILER_BLAS_BACKEND MKL" ) -add_library(sympiler INTERFACE) add_library(sympiler::sym_sparse_blas ALIAS sym_sparse_blas) include(GNUInstallDirs) From 8b50984fa64b473fdd900e2e6369190c397d6920 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Fri, 23 Jun 2023 16:17:05 -0700 Subject: [PATCH 09/13] Pointed sympiler to new fork --- cmake/recipes/sympiler.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index bc4d878..99857f8 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -35,7 +35,7 @@ include(CPM) CPMAddPackage( NAME sympiler GITHUB_REPOSITORY ryansynk/sympiler - GIT_TAG 51bffd948f902b4606b8a8173a933ad9b54e29bf + GIT_TAG 2fe1ef1d72b551acedd848d64b51fa5e90251804 OPTIONS "SYMPILER_BLAS_BACKEND MKL" ) From 85dafbe44d6db2e28994560a541681dbcf2e5b01 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Fri, 23 Jun 2023 17:25:26 -0700 Subject: [PATCH 10/13] Only enable on apple silicon --- CMakeLists.txt | 2 +- cmake/recipes/sympiler.cmake | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcbf489..69393c1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ endif() # Polysolve options option(POLYSOLVE_WITH_SANITIZERS "Enable sanitizers in compilation targets" OFF) # Polysolve options for enabling/disabling optional libraries -option(POLYSOLVE_WITH_SYMPILER "Enable sympiler library" ON) +option(POLYSOLVE_WITH_SYMPILER "Enable sympiler library" ${POLYSOLVE_ON_APPLE_SILICON}) option(POLYSOLVE_WITH_ACCELERATE "Enable Apple Accelerate" ${POLYSOLVE_ON_APPLE_SILICON}) option(POLYSOLVE_WITH_CHOLMOD "Enable Cholmod library" ON) option(POLYSOLVE_WITH_UMFPACK "Enable UmfPack library" ON) diff --git a/cmake/recipes/sympiler.cmake b/cmake/recipes/sympiler.cmake index 99857f8..fedad67 100644 --- a/cmake/recipes/sympiler.cmake +++ b/cmake/recipes/sympiler.cmake @@ -36,7 +36,6 @@ CPMAddPackage( NAME sympiler GITHUB_REPOSITORY ryansynk/sympiler GIT_TAG 2fe1ef1d72b551acedd848d64b51fa5e90251804 - OPTIONS "SYMPILER_BLAS_BACKEND MKL" ) add_library(sympiler::sym_sparse_blas ALIAS sym_sparse_blas) From 45feb170e6adef2a343f361638ef12476201d3c5 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Fri, 23 Jun 2023 18:31:59 -0700 Subject: [PATCH 11/13] Moved sympiler include into cpp filee --- src/polysolve/LinearSolverSympiler.cpp | 46 +++++++++++++++++--------- src/polysolve/LinearSolverSympiler.hpp | 11 +++--- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/polysolve/LinearSolverSympiler.cpp b/src/polysolve/LinearSolverSympiler.cpp index 913a4c7..be56280 100644 --- a/src/polysolve/LinearSolverSympiler.cpp +++ b/src/polysolve/LinearSolverSympiler.cpp @@ -1,10 +1,26 @@ #ifdef POLYSOLVE_WITH_SYMPILER #include +#include #include namespace polysolve { +class LinearSolverSympilerImpl +{ +public: + LinearSolverSympilerImpl() + : m_solver(nullptr), m_A_csc(std::make_unique()) {} + ~LinearSolverSympilerImpl() = default; + + std::unique_ptr m_solver; + std::unique_ptr m_A_csc; + polysolve::StiffnessMatrix m_A_copy; +}; + + LinearSolverSympiler::LinearSolverSympiler() : m_pImpl(new LinearSolverSympilerImpl) {} + LinearSolverSympiler::~LinearSolverSympiler() = default; + void LinearSolverSympiler::setSolverMode(int _solver_mode) { solver_mode = _solver_mode; @@ -12,15 +28,15 @@ namespace polysolve void LinearSolverSympiler::updateCSC() { - m_A_csc->nzmax = m_A_copy.nonZeros(); - m_A_csc->ncol = m_A_csc->nrow = m_A_copy.rows(); - m_A_csc->p = m_A_copy.outerIndexPtr(); - m_A_csc->i = m_A_copy.innerIndexPtr(); + m_pImpl->m_A_csc->nzmax = m_pImpl->m_A_copy.nonZeros(); + m_pImpl->m_A_csc->ncol = m_pImpl->m_A_csc->nrow = m_pImpl->m_A_copy.rows(); + m_pImpl->m_A_csc->p = m_pImpl->m_A_copy.outerIndexPtr(); + m_pImpl->m_A_csc->i = m_pImpl->m_A_copy.innerIndexPtr(); - m_A_csc->x = m_A_copy.valuePtr(); - m_A_csc->stype = -1; - m_A_csc->packed = 1; - m_A_csc->nz = nullptr; + m_pImpl->m_A_csc->x = m_pImpl->m_A_copy.valuePtr(); + m_pImpl->m_A_csc->stype = -1; + m_pImpl->m_A_csc->packed = 1; + m_pImpl->m_A_csc->nz = nullptr; } void LinearSolverSympiler::setParameters(const json ¶ms) @@ -48,28 +64,28 @@ namespace polysolve void LinearSolverSympiler::analyzePattern(const StiffnessMatrix &A, const int precond_num) { - m_A_copy = StiffnessMatrix(A); + m_pImpl->m_A_copy = StiffnessMatrix(A); updateCSC(); - m_solver = std::make_unique(m_A_csc.get()); - m_solver->symbolic_analysis(); + m_pImpl->m_solver = std::make_unique(m_pImpl->m_A_csc.get()); + m_pImpl->m_solver->symbolic_analysis(); } // Factorize system matrix void LinearSolverSympiler::factorize(const StiffnessMatrix &A) { // Only copy when matrix changes - if (!m_A_copy.isApprox(A)) + if (!m_pImpl->m_A_copy.isApprox(A)) { - m_A_copy = StiffnessMatrix(A); + m_pImpl->m_A_copy = StiffnessMatrix(A); updateCSC(); } - factorize_status = m_solver->numerical_factorization(m_A_csc.get()); + factorize_status = m_pImpl->m_solver->numerical_factorization(m_pImpl->m_A_csc.get()); } // Solve the linear system Ax = b void LinearSolverSympiler::solve(const Ref b, Ref x) { - double *x_ptr = m_solver->solve_only(b.data()); + double *x_ptr = m_pImpl->m_solver->solve_only(b.data()); x = Eigen::Map(x_ptr, x.rows(), x.cols()); } diff --git a/src/polysolve/LinearSolverSympiler.hpp b/src/polysolve/LinearSolverSympiler.hpp index 0a3a57d..6f1b230 100644 --- a/src/polysolve/LinearSolverSympiler.hpp +++ b/src/polysolve/LinearSolverSympiler.hpp @@ -1,16 +1,15 @@ #ifdef POLYSOLVE_WITH_SYMPILER #include -#include namespace polysolve { + class LinearSolverSympilerImpl; class LinearSolverSympiler : public LinearSolver { public: - LinearSolverSympiler() - : m_solver(nullptr), m_A_csc(std::make_unique()) {} - virtual ~LinearSolverSympiler() = default; + LinearSolverSympiler(); + ~LinearSolverSympiler(); private: POLYSOLVE_DELETE_MOVE_COPY(LinearSolverSympiler) @@ -43,9 +42,7 @@ namespace polysolve virtual std::string name() const override { return "Sympiler"; } private: - std::unique_ptr m_solver; - std::unique_ptr m_A_csc; - polysolve::StiffnessMatrix m_A_copy; + std::unique_ptr m_pImpl; protected: //////////////////// From b335e405d25c9966c5d87f484e0fd80408a0c2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Dumas?= Date: Thu, 29 Jun 2023 11:46:44 -0700 Subject: [PATCH 12/13] Enable Sympiler on Unix. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 001afcf..16c3813 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ endif() option(POLYSOLVE_WITH_SANITIZERS "Enable sanitizers in compilation targets" OFF) # Polysolve options for enabling/disabling optional libraries -option(POLYSOLVE_WITH_SYMPILER "Enable sympiler library" ${POLYSOLVE_ON_APPLE_SILICON}) +option(POLYSOLVE_WITH_SYMPILER "Enable sympiler library" ${UNIX}) option(POLYSOLVE_WITH_ACCELERATE "Enable Apple Accelerate" ${POLYSOLVE_ON_APPLE_SILICON}) option(POLYSOLVE_WITH_CHOLMOD "Enable Cholmod library" ON) option(POLYSOLVE_WITH_UMFPACK "Enable UmfPack library" ON) From 7a0e47a549afb8c1e61efe7bd985ae8fc45a1878 Mon Sep 17 00:00:00 2001 From: Ryan Synk Date: Tue, 11 Jul 2023 13:02:51 -0700 Subject: [PATCH 13/13] Added sorted=True --- src/polysolve/LinearSolverSympiler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/polysolve/LinearSolverSympiler.cpp b/src/polysolve/LinearSolverSympiler.cpp index be56280..54fa327 100644 --- a/src/polysolve/LinearSolverSympiler.cpp +++ b/src/polysolve/LinearSolverSympiler.cpp @@ -36,6 +36,7 @@ class LinearSolverSympilerImpl m_pImpl->m_A_csc->x = m_pImpl->m_A_copy.valuePtr(); m_pImpl->m_A_csc->stype = -1; m_pImpl->m_A_csc->packed = 1; + m_pImpl->m_A_csc->sorted = 1; m_pImpl->m_A_csc->nz = nullptr; }