suanPan
🧮 An Open Source, Parallel and Heterogeneous Finite Element Analysis Framework
Loading...
Searching...
No Matches
SparseMat.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-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 ******************************************************************************/
29#ifndef SPARSEMAT_HPP
30#define SPARSEMAT_HPP
31
32#include "MetaMat.hpp"
33
34template<sp_d T> class SparseMat : public MetaMat<T> {
35protected:
36 using MetaMat<T>::direct_solve;
37
38 int direct_solve(Mat<T>& X, Mat<T>&& B) override { return this->direct_solve(X, B); }
39
40public:
41 SparseMat(const uword in_row, const uword in_col, const uword in_elem = 0)
42 : MetaMat<T>(in_row, in_col, 0) { this->triplet_mat.init(in_elem); }
43
44 [[nodiscard]] bool is_empty() const override { return this->triplet_mat.is_empty(); }
45
46 void zeros() override {
47 this->factored = false;
48 this->triplet_mat.zeros();
49 }
50
51 void nullify(const uword idx) override {
52 this->factored = false;
53 this->triplet_mat.nullify(idx);
54 }
55
56 [[nodiscard]] T max() const override { return this->triplet_mat.max(); }
57
58 T operator()(const uword in_row, const uword in_col) const override { return this->triplet_mat(in_row, in_col); }
59
60 T& at(const uword in_row, const uword in_col) override {
61 this->factored = false;
62 return this->triplet_mat.at(in_row, in_col);
63 }
64
65 [[nodiscard]] const T* memptr() const override { throw std::invalid_argument("not supported"); }
66
67 T* memptr() override { throw std::invalid_argument("not supported"); }
68
69 void scale_accu(const T scalar, const shared_ptr<MetaMat<T>>& in_mat) override {
70 if(nullptr == in_mat) return;
71 if(!in_mat->triplet_mat.is_empty()) return this->scale_accu(scalar, in_mat->triplet_mat);
72 this->factored = false;
73 for(auto I = 0llu; I < in_mat->n_rows; ++I)
74 for(auto J = 0llu; J < in_mat->n_cols; ++J)
75 if(const auto t_val = in_mat->operator()(I, J); !suanpan::approx_equal(T(0), t_val)) at(I, J) = scalar * t_val;
76 }
77
78 void scale_accu(const T scalar, const triplet_form<T, uword>& in_mat) override {
79 this->factored = false;
80 if(1. == scalar) this->triplet_mat += in_mat;
81 else if(-1. == scalar) this->triplet_mat -= in_mat;
82 else this->triplet_mat.assemble(in_mat, 0, 0, scalar);
83 }
84
85 Mat<T> operator*(const Mat<T>& in_mat) const override { return this->triplet_mat * in_mat; }
86
87 void operator*=(const T scalar) override {
88 this->factored = false;
89 this->triplet_mat *= scalar;
90 }
91
92 void allreduce() override {
93#ifdef SUANPAN_DISTRIBUTED
94 const auto coo_elem = this->triplet_mat.n_elem;
95 std::vector<uword> dist_elem(comm_size);
96 comm_world.allgather(coo_elem, dist_elem.data());
97 this->triplet_mat.hack_size(std::accumulate(dist_elem.begin(), dist_elem.end(), uword{0}));
98
99 mpl::irequest_pool requests;
100
101 auto accu_elem = coo_elem;
102 for(auto comm_n = 0; comm_n < comm_size; ++comm_n)
103 if(comm_n == comm_rank) {
104 requests.push(comm_world.ibcast(comm_n, this->triplet_mat.row_mem(), mpl::contiguous_layout<uword>{coo_elem}));
105 requests.push(comm_world.ibcast(comm_n, this->triplet_mat.col_mem(), mpl::contiguous_layout<uword>{coo_elem}));
106 requests.push(comm_world.ibcast(comm_n, this->triplet_mat.val_mem(), mpl::contiguous_layout<T>{coo_elem}));
107 }
108 else {
109 requests.push(comm_world.ibcast(comm_n, this->triplet_mat.row_mem() + accu_elem, mpl::contiguous_layout<uword>{dist_elem[comm_n]}));
110 requests.push(comm_world.ibcast(comm_n, this->triplet_mat.col_mem() + accu_elem, mpl::contiguous_layout<uword>{dist_elem[comm_n]}));
111 requests.push(comm_world.ibcast(comm_n, this->triplet_mat.val_mem() + accu_elem, mpl::contiguous_layout<T>{dist_elem[comm_n]}));
112 accu_elem += dist_elem[comm_n];
113 }
114
115 requests.waitall();
116#endif
117 csc_condense();
118 }
119
120 void csc_condense() override { this->triplet_mat.csc_condense(); }
121
122 void csr_condense() override { this->triplet_mat.csr_condense(); }
123};
124
125#endif
126
A MetaMat class that holds matrices.
Definition MetaMat.hpp:74
triplet_form< T, uword > triplet_mat
Definition MetaMat.hpp:113
bool factored
Definition MetaMat.hpp:76
A SparseMat class that holds matrices.
Definition SparseMat.hpp:34
void zeros() override
Definition SparseMat.hpp:46
T * memptr() override
Definition SparseMat.hpp:67
T operator()(const uword in_row, const uword in_col) const override
Access element (read-only), returns zero if out-of-bound.
Definition SparseMat.hpp:58
void allreduce() override
Definition SparseMat.hpp:92
Mat< T > operator*(const Mat< T > &in_mat) const override
Definition SparseMat.hpp:85
const T * memptr() const override
Definition SparseMat.hpp:65
SparseMat(const uword in_row, const uword in_col, const uword in_elem=0)
Definition SparseMat.hpp:41
T max() const override
Definition SparseMat.hpp:56
void csc_condense() override
Definition SparseMat.hpp:120
void nullify(const uword idx) override
Definition SparseMat.hpp:51
void scale_accu(const T scalar, const triplet_form< T, uword > &in_mat) override
Definition SparseMat.hpp:78
T & at(const uword in_row, const uword in_col) override
Access element with bound check.
Definition SparseMat.hpp:60
void csr_condense() override
Definition SparseMat.hpp:122
void scale_accu(const T scalar, const shared_ptr< MetaMat< T > > &in_mat) override
Definition SparseMat.hpp:69
int direct_solve(Mat< T > &X, Mat< T > &&B) override
Definition SparseMat.hpp:38
bool is_empty() const override
Definition SparseMat.hpp:44
void operator*=(const T scalar) override
Definition SparseMat.hpp:87
Definition triplet_form.hpp:62
void zeros()
Definition triplet_form.hpp:179
data_t max() const
Definition triplet_form.hpp:174
void hack_size(const index_t in_elem)
Adjusts the size of the container by reserving space and updating the element count.
Definition triplet_form.hpp:221
void csc_condense()
Definition triplet_form.hpp:238
bool is_empty() const
Definition triplet_form.hpp:172
data_t & at(index_t, index_t)
Definition triplet_form.hpp:415
void csr_condense()
Definition triplet_form.hpp:233
const index_t n_elem
Definition triplet_form.hpp:130
void init(const index_t in_elem)
Definition triplet_form.hpp:184
auto nullify(const index_t idx)
Definition triplet_form.hpp:203
void assemble(const Mat< data_t > &, const Col< uword > &)
Definition triplet_form.hpp:537
bool approx_equal(const T x, const T y, int ulp=2)
Definition utility.h:97
constexpr auto comm_rank
Definition suanPan.h:235
constexpr auto comm_size
Definition suanPan.h:236