10#include <kernel/backend.hpp>
11#include <kernel/solver/adp_solver_base.hpp>
32 static constexpr bool have_cudss =
true;
35 typedef double CUDSS_DT;
38 typedef std::int32_t CUDSS_IT;
40 void* create_cudss_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
41 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes);
43 void destroy_cudss_core(
void* core);
45 CUDSS_IT* get_cudss_row_ptr(
void* core);
46 CUDSS_IT* get_cudss_col_idx(
void* core);
47 CUDSS_DT* get_cudss_mat_val(
void* core);
48 CUDSS_DT* get_cudss_rhs_val(
void* core);
49 CUDSS_DT* get_cudss_sol_val(
void* core);
51 void init_cudss_symbolic(
void* core);
52 void init_cudss_numeric(
void* core);
54 void solve_cudss(
void* core);
56 std::int64_t get_peak_mem_cudss_host(
void* core);
57 std::int64_t get_peak_mem_cudss_device(
void* core);
60 static constexpr bool have_cudss =
false;
69 static constexpr bool have_mkldss =
true;
72 typedef double MKLDSS_DT;
77 typedef long long MKLDSS_IT;
79 typedef int MKLDSS_IT;
82 void* create_mkldss_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
83 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes);
85 void destroy_mkldss_core(
void* core);
87 MKLDSS_IT* get_mkldss_row_ptr(
void* core);
88 MKLDSS_IT* get_mkldss_col_idx(
void* core);
89 MKLDSS_DT* get_mkldss_mat_val(
void* core);
90 MKLDSS_DT* get_mkldss_rhs_val(
void* core);
91 MKLDSS_DT* get_mkldss_sol_val(
void* core);
93 void init_mkldss_symbolic(
void* core);
94 void init_mkldss_numeric(
void* core);
96 void solve_mkldss(
void* core);
98 std::int64_t get_peak_mem_mkldss(
void* core);
101 static constexpr bool have_mkldss =
false;
107#ifdef FEAT_HAVE_MUMPS
109 static constexpr bool have_mumps =
true;
112 typedef double MUMPS_DT;
116 typedef std::int64_t MUMPS_IT;
118 void* create_mumps_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
119 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes);
121 void destroy_mumps_core(
void* core);
123 MUMPS_IT* get_mumps_row_ptr(
void* core);
124 MUMPS_IT* get_mumps_col_idx(
void* core);
125 MUMPS_DT* get_mumps_mat_val(
void* core);
126 MUMPS_DT* get_mumps_vector(
void* core);
128 void init_mumps_symbolic(
void* core);
129 void init_mumps_numeric(
void* core);
130 void done_mumps_numeric(
void* core);
132 void solve_mumps(
void* core);
135 static constexpr bool have_mumps =
false;
141#ifdef FEAT_HAVE_SUPERLU_DIST
143 static constexpr bool have_superlu =
true;
146 typedef double SUPERLU_DT;
150#ifdef FEAT_TPL_SUPERLU_INT64
151 typedef std::int64_t SUPERLU_IT;
153 typedef int SUPERLU_IT;
156 void* create_superlu_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
157 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes);
159 void destroy_superlu_core(
void* core);
161 SUPERLU_IT* get_superlu_row_ptr(
void* core);
162 SUPERLU_IT* get_superlu_col_idx(
void* core);
163 SUPERLU_DT* get_superlu_mat_val(
void* core);
164 SUPERLU_DT* get_superlu_vector(
void* core);
166 void init_superlu_symbolic(
void* core);
167 void init_superlu_numeric(
void* core);
168 void done_superlu_numeric(
void* core);
170 void solve_superlu(
void* core);
173 static constexpr bool have_superlu =
false;
180#ifdef FEAT_HAVE_UMFPACK
182 static constexpr bool have_umfpack =
true;
185 typedef double UMFPACK_DT;
189 typedef std::int32_t UMFPACK_IT;
191 void* create_umfpack_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
192 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes);
194 void destroy_umfpack_core(
void* core);
196 UMFPACK_IT* get_umfpack_row_ptr(
void* core);
197 UMFPACK_IT* get_umfpack_col_idx(
void* core);
198 UMFPACK_DT* get_umfpack_mat_val(
void* core);
199 UMFPACK_DT* get_umfpack_rhs_val(
void* core);
200 UMFPACK_DT* get_umfpack_sol_val(
void* core);
202 void init_umfpack_symbolic(
void* core);
203 void init_umfpack_numeric(
void* core);
204 void done_umfpack_numeric(
void* core);
206 void solve_umfpack(
void* core);
209 static constexpr bool have_umfpack =
false;
215 static constexpr bool have_backend_local = have_cudss || have_mkldss || have_superlu || have_umfpack;
218 static constexpr bool have_backend_global = have_cudss || have_mkldss || have_superlu;
240 return static_cast<DSSBackend>(
static_cast<int>(a) |
static_cast<int>(b));
246 return static_cast<DSSBackend>(
static_cast<int>(a) &
static_cast<int>(b));
257 static std::ostream& operator<<(std::ostream& os,
DSSBackend a)
447 template<
typename Matrix_,
typename Filter_>
526 String s =
"DirectSparseSolver";
555 if constexpr (MatrixType::is_local)
558 if constexpr (MatrixType::is_global)
562 if((comm ==
nullptr) || (comm->
size() <= 1))
570 XABORTM(
"matrix type is neither local nor global!");
594 for(
const auto& s : backends)
617 for(
const String& s : sbacks)
619 if(s.compare_no_case(
"none") == 0)
621 else if(s.compare_no_case(
"all") == 0)
623 else if(s.compare_no_case(
"cudss") == 0)
625 else if(s.compare_no_case(
"mkldss") == 0)
627 else if(s.compare_no_case(
"mkl-dss") == 0)
629 else if(s.compare_no_case(
"mumps") == 0)
631 else if(s.compare_no_case(
"superlu") == 0)
633 else if(s.compare_no_case(
"umfpack") == 0)
674 if(this->_core_umfpack)
676 if(this->_core_superlu)
678 if(this->_core_mkldss)
680 if(this->_core_mumps)
682 if(this->_core_cudss)
702 const bool single_process = ((comm ==
nullptr) || (comm->
size() <= 1));
788#ifdef FEAT_HAVE_CUDSS
789 if(this->_core_cudss)
791 DSS::destroy_cudss_core(this->_core_cudss);
792 this->_core_cudss =
nullptr;
796 if(this->_core_mkldss)
798 DSS::destroy_mkldss_core(this->_core_mkldss);
799 this->_core_mkldss =
nullptr;
802#ifdef FEAT_HAVE_MUMPS
803 if(this->_core_mumps)
805 DSS::destroy_mumps_core(this->_core_mumps);
806 this->_core_mumps =
nullptr;
809#ifdef FEAT_HAVE_SUPERLU_DIST
810 if(this->_core_superlu)
812 DSS::destroy_superlu_core(this->_core_superlu);
813 this->_core_superlu =
nullptr;
816#ifdef FEAT_HAVE_UMFPACK
817 if(this->_core_umfpack)
819 DSS::destroy_umfpack_core(this->_core_umfpack);
820 this->_core_umfpack =
nullptr;
834#ifdef FEAT_HAVE_CUDSS
835 if(this->_core_cudss)
838 DSS::get_cudss_mat_val(this->_core_cudss),
839 DSS::get_cudss_row_ptr(this->_core_cudss),
840 DSS::get_cudss_col_idx(this->_core_cudss));
842 DSS::init_cudss_numeric(this->_core_cudss);
846 if(this->_core_mkldss)
849 DSS::get_mkldss_mat_val(this->_core_mkldss),
850 DSS::get_mkldss_row_ptr(this->_core_mkldss),
851 DSS::get_mkldss_col_idx(this->_core_mkldss));
853 DSS::init_mkldss_numeric(this->_core_mkldss);
856#ifdef FEAT_HAVE_MUMPS
857 if(this->_core_mumps)
860 DSS::get_mumps_mat_val(this->_core_mumps),
861 DSS::get_mumps_row_ptr(this->_core_mumps),
862 DSS::get_mumps_col_idx(this->_core_mumps));
864 DSS::init_mumps_numeric(this->_core_mumps);
867#ifdef FEAT_HAVE_SUPERLU_DIST
868 if(this->_core_superlu)
871 DSS::get_superlu_mat_val(this->_core_superlu),
872 DSS::get_superlu_row_ptr(this->_core_superlu),
873 DSS::get_superlu_col_idx(this->_core_superlu));
875 DSS::init_superlu_numeric(this->_core_superlu);
878#ifdef FEAT_HAVE_UMFPACK
879 if(this->_core_umfpack)
882 DSS::get_umfpack_mat_val(this->_core_umfpack),
883 DSS::get_umfpack_row_ptr(this->_core_umfpack),
884 DSS::get_umfpack_col_idx(this->_core_umfpack));
886 DSS::init_umfpack_numeric(this->_core_umfpack);
896#ifdef FEAT_HAVE_SUPERLU_DIST
897 if(this->_core_superlu)
899 DSS::done_superlu_numeric(this->_core_superlu);
902#ifdef FEAT_HAVE_UMFPACK
903 if(this->_core_umfpack)
905 DSS::done_umfpack_numeric(this->_core_umfpack);
927#ifdef FEAT_HAVE_CUDSS
928 if(this->_core_cudss)
931 this->
_upload_vector(DSS::get_cudss_rhs_val(this->_core_cudss), vec_def);
936 DSS::solve_cudss(this->_core_cudss);
954 if(this->_core_mkldss)
957 this->
_upload_vector(DSS::get_mkldss_rhs_val(this->_core_mkldss), vec_def);
962 DSS::solve_mkldss(this->_core_mkldss);
974 this->
_download_vector(vec_cor, DSS::get_mkldss_sol_val(this->_core_mkldss));
979#ifdef FEAT_HAVE_MUMPS
980 if(this->_core_mumps)
983 this->
_upload_vector(DSS::get_mumps_vector(this->_core_mumps), vec_def);
988 DSS::solve_mumps(this->_core_mumps);
1005#ifdef FEAT_HAVE_SUPERLU_DIST
1006 if(this->_core_superlu)
1009 this->
_upload_vector(DSS::get_superlu_vector(this->_core_superlu), vec_def);
1014 DSS::solve_superlu(this->_core_superlu);
1026 this->
_download_vector(vec_cor, DSS::get_superlu_vector(this->_core_superlu));
1031#ifdef FEAT_HAVE_UMFPACK
1032 if(this->_core_umfpack)
1035 this->
_upload_vector(DSS::get_umfpack_rhs_val(this->_core_umfpack), vec_def);
1040 DSS::solve_umfpack(this->_core_umfpack);
1052 this->
_download_vector(vec_cor, DSS::get_umfpack_sol_val(this->_core_umfpack));
1065#ifdef FEAT_HAVE_CUDSS
1067 this->_core_cudss = DSS::create_cudss_core(
1077 DSS::get_cudss_row_ptr(this->_core_cudss),
1078 DSS::get_cudss_col_idx(this->_core_cudss));
1081 DSS::init_cudss_symbolic(this->_core_cudss);
1094 this->_core_mkldss = DSS::create_mkldss_core(
1104 DSS::get_mkldss_row_ptr(this->_core_mkldss),
1105 DSS::get_mkldss_col_idx(this->_core_mkldss));
1108 DSS::init_mkldss_symbolic(this->_core_mkldss);
1119#ifdef FEAT_HAVE_MUMPS
1121 this->_core_mumps = DSS::create_mumps_core(
1131 DSS::get_mumps_row_ptr(this->_core_mumps),
1132 DSS::get_mumps_col_idx(this->_core_mumps));
1135 DSS::init_mumps_symbolic(this->_core_mumps);
1146#ifdef FEAT_HAVE_SUPERLU_DIST
1148 this->_core_superlu = DSS::create_superlu_core(
1158 DSS::get_superlu_row_ptr(this->_core_superlu),
1159 DSS::get_superlu_col_idx(this->_core_superlu));
1162 DSS::init_superlu_symbolic(this->_core_superlu);
1173#ifdef FEAT_HAVE_UMFPACK
1175 this->_core_umfpack = DSS::create_umfpack_core(
1185 DSS::get_umfpack_row_ptr(this->_core_umfpack),
1186 DSS::get_umfpack_col_idx(this->_core_umfpack));
1189 DSS::init_umfpack_symbolic(this->_core_umfpack);
1210 template<
typename Matrix_,
typename Filter_>
1213 return std::make_shared<DirectSparseSolver<Matrix_, Filter_>>(matrix, filter);
1228 template<
typename Matrix_,
typename Filter_>
#define XABORTM(msg)
Abortion macro definition with custom message.
int size() const
Returns the size of this communicator.
Base-Class for solvers based on Algebraic-DOF-Partitioning.
const Dist::Comm * _get_comm() const
void _upload_symbolic(RPT_ *row_ptr, CIT_ *col_idx)
Uploads the ADP matrix structure to the given arrays.
Index _get_num_owned_dofs() const
Index _get_global_dof_offset() const
void _download_vector(LocalVectorType &vector, const DTV_ *val)
Downloads the ADP vector values from the given array.
void _upload_vector(DTV_ *val, const LocalVectorType &vector)
Uploads the ADP vector values to the given array.
Index _get_num_global_nonzeros() const
MatrixType::VectorTypeL VectorType
the (local) vector type
Index _get_num_global_dofs() const
Filter_ FilterType
the (local) filter type
Index _get_adp_matrix_num_nzes() const
Matrix_ MatrixType
this specialization expects a local matrix
void _upload_numeric(DTV_ *val, const RPT_ *row_ptr, const CIT_ *col_idx)
Uploads the (filtered) ADP matrix values to the given array.
DirectSparseSolver backend not found exception.
Exception base class for errors occurring in DirectSparseSolver.
Front-end wrapper class for (parallel) third-party direct sparse solvers.
bool _create_core_umfpack()
Tries to create an UMFPACK backend core and returns true, if it succeeded.
void * _core_cudss
Nvidia cuDSS core.
virtual void init_numeric() override
Performs the numeric initialization of the solver.
void * _core_superlu
SuperLU core.
static constexpr bool have_backend_global
specifies whether at least one backend for global systems is available
void push_allowed_backend_list(const String &backends)
Pushes a list of allowed backends into the backend queue.
void push_allowed_backend(const String &backend)
Pushes a combination of allowed backends into the backend queue.
PreferredBackend _preferred_backend
preferred backend of runtime at time of object creation
virtual void done_symbolic() override
Releases the symbolic factorization data and frees the backend.
ADPSolverBase< Matrix_, Filter_ > BaseClass
our base class
void * _core_mumps
MUMPS core.
static constexpr bool have_backend_mkldss
specifies whether the MKL-DSS solver backend is available
static constexpr bool have_backend_mumps
specifies whether the MUMPS solver backend is available
static constexpr bool have_backend_cudss
specifies whether the cuDSS solver backend is available
void clear_allowed_backends()
Clears the deque of allowed backends.
BaseClass::VectorType VectorType
our (global or local) system vector type
bool _create_core_mkldss()
Tries to create a MKL-DSS backend core and returns true, if it succeeded.
void push_allowed_backend_list(const std::deque< String > &backends)
Pushes a deque of allowed backends into the backend queue.
static constexpr bool have_backend_umfpack
specifies whether the UMFPACK solver backend is available
void push_allowed_backend(DSSBackend backend)
Pushes a combination of allowed backends into the backend queue.
bool _create_core_superlu()
Tries to create a SuperLU backend core and returns true, if it succeeded.
bool _create_core_cudss()
Tries to create a cuDSS backend core and returns true, if it succeeded.
const std::deque< DSSBackend > get_allowed_backends() const
Returns a reference to the deque of allowed backends.
void * _core_umfpack
UMFPACK core.
virtual ~DirectSparseSolver()
virtual destructor
virtual Status apply(VectorType &vec_cor, const VectorType &vec_def) override
Solves a linear system with the factorized system matrix.
void * _core_mkldss
Intel MKLDSS core.
virtual void done_numeric() override
Releases the numeric initialization data of the solver.
virtual void init_symbolic() override
Performs the symbolic initialization of the solver.
std::deque< DSSBackend > _allowed_backends
backends that the user allowed us to use
DirectSparseSolver(const MatrixType &matrix, const FilterType &filter)
Creates a new DirectSparseSolver object for the given system.
static constexpr bool have_backend_superlu
specifies whether the SuperLU solver backend is available
DSSBackend get_selected_backend() const
Returns the selected backend.
virtual String name() const override
Returns the name of the solver.
static constexpr bool have_backend_local
specifies whether at least one backend for local systems is available
BaseClass::MatrixType MatrixType
our (global or local) system matrix type
static bool is_available(const MatrixType &matrix, const FilterType &filter)
Checks whether a suitable backend for the given matrix and filter.
bool _create_core_mumps()
Tries to create a MUMPS backend core and returns true, if it succeeded.
BaseClass::FilterType FilterType
our (global or local) system filter type
virtual void init_symbolic()
Symbolic initialization method.
virtual void init_numeric()
Numeric initialization method.
virtual void done_symbolic()
Symbolic finalization method.
virtual void done_numeric()
Numeric finalization method.
Base-class for solver generated exceptions.
String class implementation.
std::deque< String > split_by_whitespaces() const
Splits the string by white-spaces.
std::deque< String > split_by_charset(const String &charset) const
Splits the string by a delimiter charset.
static constexpr DSSBackend operator&(DSSBackend a, DSSBackend b)
bit-wise AND operator for DSSBackend enum values
std::shared_ptr< DirectSparseSolver< Matrix_, Filter_ > > new_direct_sparse_solver(const Matrix_ &matrix, const Filter_ &filter)
Creates a new DirectSparseSolver object.
Status
Solver status return codes enumeration.
@ success
solving successful (convergence criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
DSSBackend
Enumeration of allowed backends for DirectSparseSolver class.
@ umfpack
UMFPACK backend.
@ all
all backends allowed
@ superlu
SuperLU backend.
static constexpr DSSBackend operator|(DSSBackend a, DSSBackend b)
bit-wise OR operator for DSSBackend enum values
bool have_direct_sparse_solver(const Matrix_ &matrix, const Filter_ &filter)
Checks whether at least one DirectSparseSolver backend is available.
static constexpr bool operator*(DSSBackend a)
checks whether at least one of the bits in DSSBackend is selected
PreferredBackend
The backend that shall be used in all compute heavy calculations.
String stringify(const T_ &item)
Converts an item into a String.