ezp
lightweight C++ wrapper for selected distributed solvers for linear systems
Loading...
Searching...
No Matches
lis.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2025-2026 Theodore Chang
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
35#ifndef LIS_HPP
36#define LIS_HPP
37
38#include "abstract/sparse_solver.hpp"
39
40#include <mpl/mpl.hpp>
41
42using LIS_INT = int_t;
43using LIS_SCALAR = double;
44using LIS_REAL = double;
45using LIS_Comm = MPI_Comm;
46
48 LIS_INT label;
49 LIS_INT status;
50 LIS_INT precision;
51 LIS_INT gn;
52 LIS_INT n;
53 LIS_INT np;
54 LIS_INT pad;
55 LIS_INT origin;
56 LIS_INT is_copy;
57 LIS_INT is_destroy;
58 LIS_INT is_scaled;
59 LIS_INT my_rank;
60 LIS_INT nprocs;
61 LIS_Comm comm;
62 LIS_INT is;
63 LIS_INT ie;
64 LIS_INT* ranges;
65 LIS_SCALAR* value;
66 LIS_SCALAR* value_lo;
67 LIS_SCALAR* work;
68 LIS_INT intvalue;
69};
70
72
74 LIS_INT nnz;
75 LIS_INT ndz;
76 LIS_INT bnr;
77 LIS_INT bnc;
78 LIS_INT nr;
79 LIS_INT nc;
80 LIS_INT bnnz;
81 LIS_INT nnd;
82 LIS_INT maxnzr;
83 LIS_INT* ptr;
84 LIS_INT* row;
85 LIS_INT* col;
86 LIS_INT* index;
87 LIS_INT* bptr;
88 LIS_INT* bindex;
89 LIS_SCALAR* value;
90 LIS_SCALAR* work;
91};
92
94
96 LIS_INT label;
97 LIS_INT status;
98 LIS_INT precision;
99 LIS_INT gn;
100 LIS_INT n;
101 LIS_INT np;
102 LIS_INT pad;
103 LIS_INT origin;
104 LIS_INT is_copy;
105 LIS_INT is_destroy;
106 LIS_INT is_scaled;
107 LIS_INT my_rank;
108 LIS_INT nprocs;
109 LIS_Comm comm;
110 LIS_INT is;
111 LIS_INT ie;
112 LIS_INT* ranges;
113 LIS_SCALAR* value;
114 LIS_SCALAR* work;
115
116 LIS_INT bn;
117 LIS_INT nr;
118 LIS_INT* bns;
119 LIS_INT* ptr;
120 LIS_SCALAR** v_value;
121};
122
124
126 LIS_Comm comm;
127 LIS_INT pad;
128 LIS_INT neibpetot;
129 LIS_INT imnnz;
130 LIS_INT exnnz;
131 LIS_INT wssize;
132 LIS_INT wrsize;
133 LIS_INT* neibpe;
134 LIS_INT* import_ptr;
135 LIS_INT* import_index;
136 LIS_INT* export_ptr;
137 LIS_INT* export_index;
138 LIS_SCALAR* ws;
139 LIS_SCALAR* wr;
140 MPI_Request *req1, *req2;
141 MPI_Status *sta1, *sta2;
142};
143
145
147 LIS_INT label;
148 LIS_INT status;
149 LIS_INT precision;
150 LIS_INT gn;
151 LIS_INT n;
152 LIS_INT np;
153 LIS_INT pad;
154 LIS_INT origin;
155 LIS_INT is_copy;
156 LIS_INT is_destroy;
157 LIS_INT is_scaled;
158 LIS_INT my_rank;
159 LIS_INT nprocs;
160 LIS_Comm comm;
161 LIS_INT is;
162 LIS_INT ie;
163 LIS_INT* ranges;
164
165 LIS_INT matrix_type;
166 LIS_INT nnz; /* CSR,CSC,MSR,JAD,VBR,COO */
167 LIS_INT ndz; /* MSR */
168 LIS_INT bnr; /* BSR,BSC */
169 LIS_INT bnc; /* BSR,BSC */
170 LIS_INT nr; /* BSR,BSC,VBR */
171 LIS_INT nc; /* BSR,BSC,VBR */
172 LIS_INT bnnz; /* BSR,BSC,VBR */
173 LIS_INT nnd; /* DIA */
174 LIS_INT maxnzr; /* ELL,JAD */
175 LIS_INT* ptr; /* CSR,CSC,JAD */
176 LIS_INT* row; /* JAD,VBR,COO */
177 LIS_INT* col; /* JAD,VBR,COO */
178 LIS_INT* index; /* CSR,CSC,MSR,DIA,ELL,JAD */
179 LIS_INT* bptr; /* BSR,BSC,VBR */
180 LIS_INT* bindex; /* BSR,BSC,VBR */
181 LIS_SCALAR* value; /* CSR,CSC,MSR,DIA,ELL,JAD,BSR,BSC,VBR,DNS,COO */
182 LIS_SCALAR* work;
183
188
189 LIS_INT is_block;
190 LIS_INT pad_comm;
191 LIS_INT is_pmat;
192 LIS_INT is_sorted;
193 LIS_INT is_splited;
194 LIS_INT is_save;
195 LIS_INT is_comm;
196 LIS_INT is_fallocated;
197 LIS_INT use_wd;
198 LIS_INT conv_bnr;
199 LIS_INT conv_bnc;
200 LIS_INT* conv_row;
201 LIS_INT* conv_col;
202 LIS_INT options[10];
203
204 LIS_INT w_annz;
205 LIS_INT* w_nnz;
206 LIS_INT* w_row;
207 LIS_INT** w_index;
208 LIS_SCALAR** w_value;
209 LIS_SCALAR*** v_value;
210
211 LIS_INT* l2g_map;
212 LIS_COMMTABLE commtable;
213};
214
216
218 LIS_INT n;
219 LIS_INT bs;
220 LIS_INT* nnz_ma;
221 LIS_INT* nnz;
222 LIS_INT* bsz;
223 LIS_INT** index;
224 LIS_SCALAR** value;
225 LIS_SCALAR*** values;
226};
227
229
231 LIS_INT precon_type;
232 LIS_MATRIX A; /* SSOR */
233 LIS_MATRIX Ah;
234 LIS_MATRIX_ILU L; /* ilu(k),ilut,iluc,sainv */
235 LIS_MATRIX_ILU U; /* ilu(k),ilut,iluc,sainv */
236 LIS_MATRIX_DIAG WD; /* bilu(k),bilut,biluc,bjacobi */
237 LIS_VECTOR D; /* ilu(k),ilut,iluc,jacobi,sainv */
238 LIS_VECTOR Pb; /* i+s */
239 LIS_VECTOR temp; /* saamg */
240 LIS_REAL theta; /* saamg */
241 LIS_VECTOR* work; /* adds */
242 struct LIS_SOLVER_STRUCT* solver; /* hybrid */
243 LIS_INT worklen; /* adds */
244 LIS_INT level_num; /* saamg */
245 LIS_INT wsize; /* saamg */
246 LIS_INT solver_comm; /* saamg */
247 LIS_INT my_rank; /* saamg */
248 LIS_INT nprocs; /* saamg */
249 LIS_INT is_copy;
250 LIS_COMMTABLE commtable; /* saamg */
251};
252
254
256 LIS_MATRIX A, Ah;
257 LIS_VECTOR b, x, xx, d;
259 LIS_PRECON precon;
260 LIS_VECTOR* work;
261 LIS_REAL* rhistory;
262 LIS_INT worklen;
263 LIS_INT options[27];
264 LIS_SCALAR params[15];
265 LIS_INT retcode;
266 LIS_INT iter;
267 LIS_INT iter2;
268 LIS_REAL resid;
269 double time;
270 double itime;
271 double ptime;
272 double p_c_time;
273 double p_i_time;
274 LIS_INT precision;
275 LIS_REAL bnrm;
276 LIS_REAL tol;
277 LIS_REAL tol_switch;
278 LIS_INT setup;
279};
280
282
283extern "C" {
284LIS_INT lis_finalize(void);
285LIS_INT lis_initialize(int* argc, char** argv[]);
286LIS_INT lis_matrix_assemble(LIS_MATRIX A);
287LIS_INT lis_matrix_create(LIS_Comm comm, LIS_MATRIX* Amat);
288LIS_INT lis_matrix_destroy(LIS_MATRIX Amat);
289LIS_INT lis_matrix_set_csr(LIS_INT nnz, LIS_INT* row, LIS_INT* index, LIS_SCALAR* value, LIS_MATRIX A);
290LIS_INT lis_matrix_set_size(LIS_MATRIX A, LIS_INT local_n, LIS_INT global_n);
291LIS_INT lis_matrix_unset(LIS_MATRIX A);
292LIS_INT lis_solve(LIS_MATRIX A, LIS_VECTOR b, LIS_VECTOR x, LIS_SOLVER solver);
293LIS_INT lis_solver_create(LIS_SOLVER* solver);
294LIS_INT lis_solver_destroy(LIS_SOLVER solver);
295LIS_INT lis_solver_set_option(const char* text, LIS_SOLVER solver);
296LIS_INT lis_vector_create(LIS_Comm comm, LIS_VECTOR* vec);
297LIS_INT lis_vector_destroy(LIS_VECTOR vec);
298LIS_INT lis_vector_set_size(LIS_VECTOR vec, LIS_INT local_n, LIS_INT global_n);
299LIS_INT lis_vector_set(LIS_VECTOR vec, LIS_SCALAR* value);
300LIS_INT lis_vector_unset(LIS_VECTOR vec);
301void lis_do_not_handle_mpi();
302}
303
304namespace ezp {
305 namespace detail {
306 struct lis_env {
307 const mpl::communicator& comm_world{mpl::environment::comm_world()};
308
309 lis_env() {
310 lis_do_not_handle_mpi();
311 lis_initialize(nullptr, nullptr);
312 }
313 ~lis_env() { lis_finalize(); }
314
315 [[nodiscard]] auto rank() const { return comm_world.rank(); }
316
317 [[nodiscard]] auto native_handle() const { return comm_world.native_handle(); }
318 };
319
320 inline auto& get_lis_env() {
321 static const lis_env env;
322 return env;
323 }
324
325 class lis_matrix final {
326 LIS_MATRIX a_mat{};
327
328 bool is_set = false;
329
330 auto unset() {
331 if(is_set) lis_matrix_unset(a_mat);
332 lis_matrix_destroy(a_mat);
333 is_set = false;
334 }
335
336 auto create() { return lis_matrix_create(get_lis_env().native_handle(), &a_mat); }
337
338 public:
339 lis_matrix() { create(); }
340
341 lis_matrix(const lis_matrix&)
342 : lis_matrix() {}
343 lis_matrix(lis_matrix&&) = delete;
344 lis_matrix& operator=(const lis_matrix&) = delete;
345 lis_matrix& operator=(lis_matrix&&) = delete;
346
347 ~lis_matrix() { unset(); }
348
349 explicit lis_matrix(const sparse_csr_mat<LIS_SCALAR, LIS_INT>& A) { set(A); }
350
351 [[nodiscard]] auto get() const { return a_mat; }
352
353 void set(const sparse_csr_mat<LIS_SCALAR, LIS_INT>& A) {
354 unset();
355 create();
356 const bool is_root = 0 == get_lis_env().rank();
357 lis_matrix_set_size(a_mat, is_root ? A.n : 0, 0);
358 lis_matrix_set_csr(is_root ? A.nnz : 0, A.row_ptr, A.col_idx, A.data, a_mat);
359 lis_matrix_assemble(a_mat);
360 is_set = true;
361 }
362 };
363
364 class lis_vector final {
365 LIS_VECTOR v{};
366
367 bool is_set = false;
368
369 auto unset() {
370 if(is_set) lis_vector_unset(v);
371 is_set = false;
372 }
373
374 public:
375 explicit lis_vector(const LIS_INT n = 0) {
376 lis_vector_create(get_lis_env().native_handle(), &v);
377 if(n > 0) lis_vector_set_size(v, 0 == get_lis_env().rank() ? n : 0, 0);
378 }
379
380 lis_vector(const lis_vector&) = delete;
381 lis_vector(lis_vector&&) = delete;
382 lis_vector& operator=(const lis_vector&) = delete;
383 lis_vector& operator=(lis_vector&&) = delete;
384
385 ~lis_vector() {
386 unset();
387 lis_vector_destroy(v);
388 }
389
390 [[nodiscard]] auto get() const { return v; }
391
392 auto& set(LIS_SCALAR* value) {
393 unset();
394 is_set = true;
395 lis_vector_set(v, 0 == get_lis_env().rank() ? value : nullptr);
396 return *this;
397 }
398 };
399
400 class lis_solver final {
401 LIS_SOLVER solver{};
402
403 public:
404 lis_solver() { lis_solver_create(&solver); }
405
406 lis_solver(const lis_solver&)
407 : lis_solver() {};
408 lis_solver(lis_solver&&) = delete;
409 lis_solver& operator=(const lis_solver&) = delete;
410 lis_solver& operator=(lis_solver&&) = delete;
411
412 ~lis_solver() { lis_solver_destroy(solver); }
413
414 explicit lis_solver(const std::string_view setting)
415 : lis_solver() { set_option(setting); }
416
417 void set_option(const std::string_view setting) const { lis_solver_set_option(setting.data(), solver); }
418
419 auto solve(const lis_matrix& A, const lis_vector& B, const lis_vector& X) const { return lis_solve(A.get(), B.get(), X.get(), solver); }
420 };
421
422 class lis_base {
423 protected:
424 const detail::lis_env& env = detail::get_lis_env();
425
426 [[nodiscard]] auto sync_error(LIS_INT error) const {
427 env.comm_world.allreduce(mpl::min<LIS_INT>(), error);
428 return error;
429 }
430
431 public:
432 lis_base() = default;
433 };
434 } // namespace detail
435
436 class lis final : public detail::lis_base {
437 detail::lis_solver solver;
438 detail::lis_matrix a_loc;
439
440 public:
441 lis() = default;
442
443 explicit lis(const std::string_view setting)
444 : solver(setting) {}
445
446 void set_option(const std::string_view setting) const { solver.set_option(setting); }
447
449 a_loc.set(std::move(A));
450
451 return solve(std::move(B));
452 }
453
454 LIS_INT solve(full_mat<LIS_SCALAR, LIS_INT>&& B) const {
455 if(a_loc.get()->gn != B.n_rows) return -1;
456
457 LIS_INT error = 0;
458
459 std::vector<LIS_SCALAR> b_ref;
460 if(0 == env.rank()) {
461 b_ref.resize(B.n_rows * B.n_cols);
462 std::copy_n(B.data, b_ref.size(), b_ref.data());
463 }
464
465 detail::lis_vector b_loc{B.n_rows}, x_loc{B.n_rows};
466
467 for(decltype(B.n_rows) I = 0; I < B.n_rows * B.n_cols; I += B.n_rows) {
468 error = solver.solve(a_loc, b_loc.set(b_ref.data() + I), x_loc.set(B.data + I));
469
470 if(0 != error) break;
471 }
472
473 return error;
474 }
475 };
476} // namespace ezp
477
478#endif
479
Definition lis.hpp:422
Definition lis.hpp:325
Definition lis.hpp:400
Definition lis.hpp:364
Definition lis.hpp:436
Definition lis.hpp:125
Definition lis.hpp:73
Definition lis.hpp:95
Definition lis.hpp:217
Definition lis.hpp:146
Definition lis.hpp:230
Definition lis.hpp:255
Definition lis.hpp:47
Definition lis.hpp:306
Definition traits.hpp:85
Definition sparse_solver.hpp:69