11#include <kernel/lafem/forward.hpp>
12#include <kernel/lafem/container.hpp>
13#include <kernel/lafem/dense_vector.hpp>
14#include <kernel/lafem/sparse_matrix_banded.hpp>
15#include <kernel/lafem/sparse_matrix_bcsr.hpp>
16#include <kernel/lafem/sparse_layout.hpp>
17#include <kernel/lafem/arch/scale_row_col.hpp>
18#include <kernel/lafem/arch/scale.hpp>
19#include <kernel/lafem/arch/axpy.hpp>
20#include <kernel/lafem/arch/apply.hpp>
21#include <kernel/lafem/arch/norm.hpp>
22#include <kernel/lafem/arch/diagonal.hpp>
23#include <kernel/lafem/arch/lumping.hpp>
24#include <kernel/lafem/arch/row_norm.hpp>
25#include <kernel/adjacency/graph.hpp>
26#include <kernel/adjacency/permutation.hpp>
27#include <kernel/util/statistics.hpp>
28#include <kernel/util/time_stamp.hpp>
58 template <
typename DT_,
typename IT_ = Index>
72 typedef IT_ IndexType;
90 _num_rows(matrix.
rows()),
98 _col_ptr =
new IT_[_num_cols];
100 for(
Index i(0); i < _num_cols; ++i)
102 _col_ptr[i] = _deadcode;
109 if(_col_ptr !=
nullptr)
115 template<
typename LocalMatrix_,
typename RowMapping_,
typename ColMapping_>
116 void operator()(
const LocalMatrix_& loc_mat,
const RowMapping_& row_map,
117 const ColMapping_& col_map, DT_ alpha = DT_(1))
120 for(
int i(0); i < row_map.get_num_local_dofs(); ++i)
123 const Index ix = row_map.get_index(i);
126 for(IT_ k(_row_ptr[ix]); k < _row_ptr[ix + 1]; ++k)
128 _col_ptr[_col_idx[k]] = k;
132 for(
int j(0); j < col_map.get_num_local_dofs(); ++j)
135 const Index jx = col_map.get_index(j);
138 ASSERTM(_col_ptr[jx] != _deadcode,
"invalid column index");
141 _data[_col_ptr[jx]] += alpha * loc_mat[i][j];
148 for(IT_ k(_row_ptr[ix]); k < _row_ptr[ix + 1]; ++k)
150 _col_ptr[_col_idx[k]] = _deadcode;
167 typedef DT_ DataType;
168 typedef IT_ IndexType;
186 _num_rows(matrix.
rows()),
194 _col_ptr =
new IT_[_num_cols];
196 for(
Index i(0); i < _num_cols; ++i)
198 _col_ptr[i] = _deadcode;
205 if(_col_ptr !=
nullptr)
211 template<
typename LocalMatrix_,
typename RowMapping_,
typename ColMapping_>
212 void operator()(LocalMatrix_& loc_mat,
const RowMapping_& row_map,
213 const ColMapping_& col_map, DT_ alpha = DT_(1))
216 for(
int i(0); i < row_map.get_num_local_dofs(); ++i)
219 const Index ix = row_map.get_index(i);
222 for(IT_ k(_row_ptr[ix]); k < _row_ptr[ix + 1]; ++k)
224 _col_ptr[_col_idx[k]] = k;
228 for(
int j(0); j < col_map.get_num_local_dofs(); ++j)
231 const Index jx = col_map.get_index(j);
234 ASSERTM(_col_ptr[jx] != _deadcode,
"invalid column index");
237 loc_mat[i][j] += alpha * _data[_col_ptr[jx]];
244 for(IT_ k(_row_ptr[ix]); k < _row_ptr[ix + 1]; ++k)
246 _col_ptr[_col_idx[k]] = _deadcode;
271 Index & _used_elements()
292 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
296 template <
typename DataType2_,
typename IndexType2_>
299 static constexpr bool is_global =
false;
300 static constexpr bool is_local =
true;
327 Container<DT_, IT_> (rows_in * columns_in)
346 Container<DT_, IT_> (rows_in * columns_in)
354 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_elements()));
357 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_rows() + 1));
360 this->
_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
374 this->
_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
375 this->
_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
376 this->
_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
381 this->
_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
392 template <
typename MT_>
410 const Index num_rows = graph.get_num_nodes_domain();
413 IT_ * prow_ptr(this->
row_ptr());
414 IT_ * pcol_idx(this->
col_ind());
416 FEAT_PRAGMA_OMP(parallel
for)
417 for(
Index i = 0; i <= num_rows; ++i)
418 prow_ptr[i] = IT_(dom_ptr[i]);
420 FEAT_PRAGMA_OMP(parallel
for)
421 for(
Index i = 0; i < num_nnze; ++i)
422 pcol_idx[i] = IT_(img_idx[i]);
467 Container<DT_, IT_>(rows_in * columns_in)
498 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
502 deserialize<DT2_, IT2_>(input);
526 this->
move(std::forward<SparseMatrixCSR>(other));
542 t.
clone(*
this, clone_mode);
554 template<
typename DT2_,
typename IT2_>
567 template <
typename DT2_,
typename IT2_>
580 template <
typename DT2_,
typename IT2_>
590 if (other.used_elements() == 0)
593 this->
_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
595 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_elements()));
597 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_rows() + 1));
601 IT_ * tcol_ind(
nullptr);
602 IT_ * trow_ptr(
nullptr);
609 const DT_ * cval(other.val());
610 const IT_ * coffsets(other.offsets());
611 const Index cnum_of_offsets(other.num_of_offsets());
612 const Index crows(other.rows());
616 while (k < cnum_of_offsets && coffsets[k] + 1 < crows)
623 for (
Index i(k + 1); i > 0;)
628 for (
Index j(cnum_of_offsets + 1); j > 0;)
634 other.end_offset(j) + 1));
636 other.end_offset(j-1) + 1));
637 for (
Index l(start); l < end; ++l)
639 for (
Index a(i); a < j; ++a)
641 tval[ue] = cval[a * crows + l];
642 tcol_ind[ue] = IT_(l + coffsets[a] + 1 - crows);
645 trow_ptr[l + 1] = ue;
658 template <
typename DT2_,
typename IT2_,
int BlockHeight_,
int BlockW
idth_>
663 this->
_scalar_index.push_back(other.template rows<Perspective::pod>() * other.template columns<Perspective::pod>());
664 this->
_scalar_index.push_back(other.template rows<Perspective::pod>());
665 this->
_scalar_index.push_back(other.template columns<Perspective::pod>());
666 this->
_scalar_index.push_back(other.template used_elements<Perspective::pod>());
668 if (other.template used_elements<Perspective::pod>() == 0)
671 this->
_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
673 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_elements()));
675 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_rows() + 1));
679 IT_ * tcol_ind(
nullptr);
680 IT_ * trow_ptr(
nullptr);
686 trow_ptr[0] = IT_(0);
687 for (
Index orow(0) ; orow < other.rows() ; ++orow)
689 for (
int row(0) ; row < BlockHeight_ ; ++row)
691 for(
Index ocol(other.row_ptr()[orow]) ; ocol < other.row_ptr()[orow + 1] ; ++ocol)
694 for (
int col(0) ; col < BlockWidth_ ; ++col)
696 tval[ait] = tbm(row,col);
697 tcol_ind[ait] = other.col_ind()[ocol] * (IT_)BlockWidth_ + (IT_)col;
701 trow_ptr[orow *
Index(BlockHeight_) +
Index(row) + 1] = (IT_)ait;
713 template <
typename MT_>
716 XASSERT(a.template used_elements<Perspective::pod>() > 0);
721 const Index arows(ta.template rows<Perspective::pod>());
722 const Index acolumns(ta.template columns<Perspective::pod>());
723 const Index aused_elements(ta.template used_elements<Perspective::pod>());
730 IT_ * pcol_ind(tcol_ind.
elements());
731 IT_ * prow_ptr(trow_ptr.
elements());
733 for (
Index i(0); i < arows; ++i)
735 prow_ptr[i + 1] = IT_(a.get_length_of_line(i));
738 prow_ptr[0] = IT_(0);
740 for (
Index i(1); i < arows + 1; ++i)
742 prow_ptr[i] += prow_ptr[i - 1];
745 for (
Index i(0); i < arows; ++i)
747 ta.set_line(i, pval + prow_ptr[i], pcol_ind + prow_ptr[i], 0);
775 template <
typename MT_>
778 const Index arows(this->
template rows<Perspective::pod>());
780 const DT_ * pval(this->
val());
781 const IT_ * prow_ptr(this->
row_ptr());
783 for (
Index i(0); i < arows; ++i)
785 const DT_ * temp(pval + prow_ptr[i]);
786 a.set_line_reverse(i, temp);
810 this->
_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
811 this->
_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
812 this->
_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
817 this->
_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
830 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
846 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
860 std::ios_base::openmode bin = std::ifstream::in | std::ifstream::binary;
862 bin = std::ifstream::in;
863 std::ifstream file(filename.c_str(), bin);
864 if (! file.is_open())
865 XABORTM(
"Unable to open Matrix file " + filename);
888 std::map<IT_, std::map<IT_, DT_> > entries;
892 std::getline(file, line);
893 const bool general((line.find(
"%%MatrixMarket matrix coordinate real general") != String::npos) ?
true :
false);
894 const bool symmetric((line.find(
"%%MatrixMarket matrix coordinate real symmetric") != String::npos) ?
true :
false);
896 if (
symmetric ==
false && general ==
false)
898 XABORTM(
"Input-file is not a compatible mtx-file");
903 std::getline(file,line);
905 XABORTM(
"Input-file is empty");
907 String::size_type begin(line.find_first_not_of(
" "));
908 if (line.at(begin) !=
'%')
912 String::size_type begin(line.find_first_not_of(
" "));
913 line.erase(0, begin);
914 String::size_type end(line.find_first_of(
" "));
915 String srow(line, 0, end);
919 begin = line.find_first_not_of(
" ");
920 line.erase(0, begin);
921 end = line.find_first_of(
" ");
922 String scol(line, 0, end);
932 std::getline(file, line);
936 String::size_type begin(line.find_first_not_of(
" "));
937 line.erase(0, begin);
938 String::size_type end(line.find_first_of(
" "));
939 String srow(line, 0, end);
940 IT_ row((IT_)atol(srow.c_str()));
944 begin = line.find_first_not_of(
" ");
945 line.erase(0, begin);
946 end = line.find_first_of(
" ");
947 String scol(line, 0, end);
948 IT_ col((IT_)atol(scol.c_str()));
952 begin = line.find_first_not_of(
" ");
953 line.erase(0, begin);
954 end = line.find_first_of(
" ");
955 String sval(line, 0, end);
956 DT_ tval((DT_)atof(sval.c_str()));
958 entries[IT_(row)].insert(std::pair<IT_, DT_>(col, tval));
962 entries[IT_(col)].insert(std::pair<IT_, DT_>(row, tval));
967 _used_elements() = ue;
969 this->
_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
971 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_elements()));
973 this->
_indices.push_back(MemoryPool::template allocate_memory<IT_>(
rows() + 1));
976 DT_ * tval = this->
val();
977 IT_ * tcol_ind = this->
col_ind();
978 IT_ * trow_ptr = this->
row_ptr();
982 for (
auto row : entries)
984 trow_ptr[row_idx] = idx;
985 for (
auto col : row.second )
987 tcol_ind[idx] = col.first;
988 tval[idx] = col.second;
994 trow_ptr[
rows()] = IT_(ue);
1001 this->
template _deserialize<double, std::uint64_t>(
FileMode::fm_csr, file);
1004 XABORTM(
"Filemode not supported!");
1020 std::ios_base::openmode bin = std::ofstream::out | std::ofstream::binary;
1022 bin = std::ofstream::out;
1024 char* buff =
nullptr;
1030 file.open(filename.c_str(), bin);
1031 if(! file.is_open())
1032 XABORTM(
"Unable to open Matrix file " + filename);
1060 file <<
"%%MatrixMarket matrix coordinate real symmetric\n";
1061 std::vector<IT_> rowv;
1062 std::vector<IT_> colv;
1063 std::vector<DT_> valv;
1064 for (
Index row(0) ; row <
rows() ; ++row)
1066 const IT_ end(this->
row_ptr()[row + 1]);
1067 for (IT_ i(this->
row_ptr()[row]) ; i < end ; ++i)
1069 const IT_ col(this->
col_ind()[i]);
1072 rowv.push_back(IT_(row + 1));
1073 colv.push_back(col + 1);
1074 valv.push_back(this->
val()[i]);
1078 file << this->
rows() <<
" " << this->
columns() <<
" " << valv.size() <<
"\n";
1079 for (
Index i(0) ; i < valv.size() ; ++i)
1081 file << rowv.at(i) <<
" " << colv.at(i) <<
" " <<
stringify_fp_sci(valv.at(i)) <<
"\n";
1086 file <<
"%%MatrixMarket matrix coordinate real general\n";
1095 for (
Index row(0) ; row <
rows() ; ++row)
1097 const IT_ end(this->
row_ptr()[row + 1]);
1098 for (IT_ i(this->
row_ptr()[row]) ; i < end ; ++i)
1121 XABORTM(
"Filemode not supported!");
1138 MemoryPool::synchronize();
1140 const IT_ *
const trow_ptr(this->
row_ptr());
1141 const IT_ *
const tcol_ind(this->
col_ind());
1143 for (
Index i(trow_ptr[row]) ; i < trow_ptr[row+1] ; ++i)
1145 if (
Index(tcol_ind[i]) == col)
1146 return this->
val()[i];
1147 if (
Index(tcol_ind[i]) > col)
1168 template <Perspective = Perspective::native>
1179 template <Perspective = Perspective::native>
1190 template <Perspective = Perspective::native>
1231 DT_
const *
val()
const
1271 for (
Index row(0) ; row <
rows() ; ++row)
1311 for (
Index row(0) ; row <
rows() ; ++row)
1316 if (this->
row_ptr()[row+1] > 0)
1356 return "SparseMatrixCSR";
1367 this->_copy_content(x, full);
1383 const DT_ alpha = DT_(1))
1385 XASSERTM(x.
rows() == this->rows(),
"Matrix rows do not match!");
1386 XASSERTM(x.
columns() == this->columns(),
"Matrix columns do not match!");
1392 Arch::Axpy::value(this->
val(), alpha, x.
val(), this->used_elements());
1395 Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
1406 XASSERTM(x.
rows() == this->rows(),
"Row count does not match!");
1407 XASSERTM(x.
columns() == this->columns(),
"Column count does not match!");
1413 Arch::Scale::value(this->
val(), x.
val(), alpha, this->used_elements());
1416 Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
1432 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1445 ASSERTM(row_norms.
size() == this->rows(),
"Matrix/Vector dimension mismatch");
1453 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1464 ASSERTM(row_norms.
size() == this->rows(),
"Matrix/Vector dimension mismatch");
1472 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1496 ASSERTM(row_norms.
size() == this->rows(),
"Matrix/Vector dimension mismatch");
1497 ASSERTM(scal.
size() == this->rows(),
"Matrix/scalings dimension mismatch");
1506 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1525 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1546 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1566 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1586 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1605 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1622 if(this->
size() == 0 && x.
size() == 0 && this->get_elements().size() == 0 && this->get_indices().size() == 0 && x.
get_elements().size() == 0 && x.
get_indices().size() == 0)
1636 col_ind_a =
const_cast<IT_*
>(this->
col_ind());
1637 row_ptr_a =
const_cast<IT_*
>(this->
row_ptr());
1638 col_ind_b =
const_cast<IT_*
>(x.
col_ind());
1639 row_ptr_b =
const_cast<IT_*
>(x.
row_ptr());
1644 if (col_ind_a[i] != col_ind_b[i])
1652 for (
Index i(0) ; i < this->
rows() + 1; ++i)
1654 if (row_ptr_a[i] != row_ptr_b[i])
1694 const IT_ * ptxcol_ind(x.
col_ind());
1695 const IT_ * ptxrow_ptr(x.
row_ptr());
1696 const DT_ * ptxval(x.
val());
1702 IT_ * ptcol_ind(tcol_ind.
elements());
1704 IT_ * ptrow_ptr(trow_ptr.
elements());
1708 for (
Index i(0); i < txused_elements; ++i)
1710 ++ptrow_ptr[ptxcol_ind[i] + 1];
1713 for (
Index i(1); i < txcolumns - 1; ++i)
1715 ptrow_ptr[i + 1] += ptrow_ptr[i];
1718 for (
Index i(0); i < txrows; ++i)
1720 for (IT_ k(ptxrow_ptr[i]); k < ptxrow_ptr[i+1]; ++k)
1722 const IT_ l(ptxcol_ind[k]);
1723 const IT_ j(ptrow_ptr[l]);
1724 ptval[j] = ptxval[k];
1725 ptcol_ind[j] = IT_(i);
1730 for (
Index i(txcolumns); i > 0; --i)
1732 ptrow_ptr[i] = ptrow_ptr[i - 1];
1747 XASSERTM(x.
rows() == this->rows(),
"Row count does not match!");
1748 XASSERTM(x.
columns() == this->columns(),
"Column count does not match!");
1750 XASSERTM(s.
size() == this->rows(),
"Vector size does not match!");
1755 Arch::ScaleRows::csr(this->
val(), x.
val(), this->col_ind(), this->row_ptr(),
1756 s.
elements(), this->rows(), this->columns(), this->used_elements());
1759 Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
1770 XASSERTM(x.
rows() == this->rows(),
"Row count does not match!");
1771 XASSERTM(x.
columns() == this->columns(),
"Column count does not match!");
1773 XASSERTM(s.
size() == this->columns(),
"Vector size does not match!");
1778 Arch::ScaleCols::csr(this->
val(), x.
val(), this->col_ind(), this->row_ptr(),
1779 s.
elements(), this->rows(), this->columns(), this->used_elements());
1782 Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
1795 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
1796 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
1806 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1810 this->val(), this->col_ind(), this->row_ptr(), this->rows(), this->columns(), this->used_elements(),
false);
1813 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1826 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
1827 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
1837 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1841 this->val(), this->col_ind(), this->row_ptr(), this->rows(), this->columns(), this->used_elements(),
true);
1844 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1857 template<
int BlockSize_>
1860 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
1861 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
1871 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1875 Arch::Apply::template csrsb<BlockSize_, DT_, IT_>(
1876 r.template elements<Perspective::pod>(), DT_(1.), x.template elements<Perspective::pod>(), DT_(0.), r.template elements<Perspective::pod>(),
1877 this->val(), this->col_ind(), this->row_ptr(), this->rows(), this->columns(), this->
used_elements());
1880 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1898 const DT_ alpha = DT_(1))
const
1900 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
1901 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
1902 XASSERTM(y.
size() == this->rows(),
"Vector size of y does not match!");
1913 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1917 this->val(), this->col_ind(), this->row_ptr(), this->rows(), this->columns(), this->used_elements(),
false);
1920 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1938 const DT_ alpha = DT_(1))
const
1940 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
1941 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
1942 XASSERTM(y.
size() == this->columns(),
"Vector size of y does not match!");
1953 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1957 this->val(), this->col_ind(), this->row_ptr(), this->rows(), this->columns(), this->used_elements(),
true);
1960 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1976 template<
int BlockSize_>
1981 const DT_ alpha = DT_(1))
const
1983 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
1984 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
1985 XASSERTM(y.
size() == this->rows(),
"Vector size of y does not match!");
1996 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1999 Arch::Apply::template csrsb<BlockSize_, DT_, IT_>(
2000 r.template elements<Perspective::pod>(), alpha, x.template elements<Perspective::pod>(), DT_(1), y.template elements<Perspective::pod>(),
2001 this->val(), this->col_ind(), this->row_ptr(), this->rows(), this->columns(), this->
used_elements());
2004 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
2043 const DT_ alpha = DT_(1),
2044 const bool allow_incomplete =
false)
2053 DT_* data_x = this->
val();
2054 const DT_* data_d = d.
val();
2055 const DT_* data_a = a.
val();
2056 const DT_* data_b = b.
val();
2057 const IT_* row_ptr_x = this->
row_ptr();
2058 const IT_* col_idx_x = this->
col_ind();
2059 const IT_* row_ptr_d = d.
row_ptr();
2060 const IT_* col_idx_d = d.
col_ind();
2061 const IT_* row_ptr_a = a.
row_ptr();
2062 const IT_* col_idx_a = a.
col_ind();
2063 const IT_* row_ptr_b = b.
row_ptr();
2064 const IT_* col_idx_b = b.
col_ind();
2067 for(IT_ i(0); i < IT_(this->
rows()); ++i)
2070 for(IT_ ik(row_ptr_d[i]); ik < row_ptr_d[i+1]; ++ik)
2073 const IT_ k = col_idx_d[ik];
2076 for(IT_ kl(row_ptr_a[k]); kl < row_ptr_a[k+1]; ++kl)
2079 const IT_ l = col_idx_a[kl];
2082 const DT_ omega = alpha * data_d[ik] * data_a[kl];
2088 IT_ ij = row_ptr_x[i];
2089 IT_ lj = row_ptr_b[l];
2090 while(lj < row_ptr_b[l+1])
2092 if(ij >= row_ptr_x[i+1])
2097 if(allow_incomplete)
2100 XABORTM(
"Incomplete output matrix structure");
2102 else if(col_idx_x[ij] == col_idx_b[lj])
2105 data_x[ij] += omega * data_b[lj];
2109 else if(col_idx_x[ij] < col_idx_b[lj])
2120 if(allow_incomplete)
2123 XABORTM(
"Incomplete output matrix structure");
2170 const DT_ alpha = DT_(1),
2171 const bool allow_incomplete =
false)
2180 DT_* data_x = this->
val();
2181 const DT_* data_d = d.
val();
2183 const DT_* data_b = b.
val();
2184 const IT_* row_ptr_x = this->
row_ptr();
2185 const IT_* col_idx_x = this->
col_ind();
2186 const IT_* row_ptr_d = d.
row_ptr();
2187 const IT_* col_idx_d = d.
col_ind();
2188 const IT_* row_ptr_b = b.
row_ptr();
2189 const IT_* col_idx_b = b.
col_ind();
2192 for(IT_ i(0); i < IT_(this->
rows()); ++i)
2195 for(IT_ ik(row_ptr_d[i]); ik < row_ptr_d[i+1]; ++ik)
2198 const IT_ k = col_idx_d[ik];
2201 const DT_ omega = alpha * data_d[ik] * data_a[k];
2207 IT_ ij = row_ptr_x[i];
2208 IT_ kj = row_ptr_b[k];
2209 while(kj < row_ptr_b[k+1])
2211 if(ij >= row_ptr_x[i+1])
2216 if(allow_incomplete)
2219 XABORTM(
"Incomplete output matrix structure");
2221 else if(col_idx_x[ij] == col_idx_b[kj])
2224 data_x[ij] += omega * data_b[kj];
2228 else if(col_idx_x[ij] < col_idx_b[kj])
2239 if(allow_incomplete)
2242 XABORTM(
"Incomplete output matrix structure");
2289 const DT_ alpha = DT_(1),
2290 const bool allow_incomplete =
false)
2299 DT_* data_x = this->
val();
2300 const auto* data_d = d.
val();
2302 const auto* data_b = b.
val();
2303 const IT_* row_ptr_x = this->
row_ptr();
2304 const IT_* col_idx_x = this->
col_ind();
2305 const IT_* row_ptr_d = d.
row_ptr();
2306 const IT_* col_idx_d = d.
col_ind();
2307 const IT_* row_ptr_b = b.
row_ptr();
2308 const IT_* col_idx_b = b.
col_ind();
2311 for(IT_ i(0); i < IT_(this->
rows()); ++i)
2314 for(IT_ ik(row_ptr_d[i]); ik < row_ptr_d[i+1]; ++ik)
2317 const IT_ k = col_idx_d[ik];
2321 for(
int l = 0; l < bs_; ++l)
2322 omega[l] = alpha * data_d[ik](0,l) * data_a[k][l];
2328 IT_ ij = row_ptr_x[i];
2329 IT_ kj = row_ptr_b[k];
2330 while(kj < row_ptr_b[k+1])
2332 if(ij >= row_ptr_x[i+1])
2337 if(allow_incomplete)
2340 XABORTM(
"Incomplete output matrix structure");
2342 else if(col_idx_x[ij] == col_idx_b[kj])
2345 for(
int l = 0; l < bs_; ++l)
2346 data_x[ij] += omega[l] * data_b[kj](l,0);
2350 else if(col_idx_x[ij] < col_idx_b[kj])
2361 if(allow_incomplete)
2364 XABORTM(
"Incomplete output matrix structure");
2405 const DT_ alpha = DT_(1),
2406 const bool allow_incomplete =
false)
2414 DT_* data_x = this->
val();
2415 const DT_* data_d = d.
val();
2416 const DT_* data_b = b.
val();
2417 const IT_* row_ptr_x = this->
row_ptr();
2418 const IT_* col_idx_x = this->
col_ind();
2419 const IT_* row_ptr_d = d.
row_ptr();
2420 const IT_* col_idx_d = d.
col_ind();
2421 const IT_* row_ptr_b = b.
row_ptr();
2422 const IT_* col_idx_b = b.
col_ind();
2425 for(IT_ i(0); i < IT_(this->
rows()); ++i)
2428 for(IT_ ik(row_ptr_d[i]); ik < row_ptr_d[i+1]; ++ik)
2431 const IT_ k = col_idx_d[ik];
2434 const DT_ omega = alpha * data_d[ik];
2440 IT_ ij = row_ptr_x[i];
2441 IT_ kj = row_ptr_b[k];
2442 while(kj < row_ptr_b[k+1])
2444 if(ij >= row_ptr_x[i+1])
2449 if(allow_incomplete)
2452 XABORTM(
"Incomplete output matrix structure");
2454 else if(col_idx_x[ij] == col_idx_b[kj])
2457 data_x[ij] += omega * data_b[kj];
2461 else if(col_idx_x[ij] < col_idx_b[kj])
2472 if(allow_incomplete)
2475 XABORTM(
"Incomplete output matrix structure");
2486 XASSERTM(lump.
size() ==
rows(),
"lump vector size does not match matrix row count!");
2518 XASSERTM(diag.
size() ==
rows(),
"diag size does not match matrix row count!");
2519 XASSERTM(diag_indices.
size() ==
rows(),
"diag_indices size does not match matrix row count!");
2522 const IT_ *
const dindices(diag_indices.
elements());
2523 const DT_ *
const tval(this->
val());
2527 const Index index(dindices[row]);
2528 tdiag[row] = (index !=
used_elements()) ? tval[index] : DT_(0);
2564 XASSERTM(diag_indices.
size() ==
rows(),
"diag size does not match matrix row count!");
2579 return diag_indices;
2585 if (perm_row.
size() == 0 && perm_col.
size() == 0)
2588 XASSERTM(perm_row.
size() == this->rows(),
"Container rows does not match permutation size");
2589 XASSERTM(perm_col.
size() == this->columns(),
"Container columns does not match permutation size");
2592 IT_ * temp_row_ptr =
new IT_[
rows() + 1];
2601 temp_row_ptr[0] = 0;
2602 for (
Index row(0) ; row < this->
rows() ; ++row)
2607 for (
Index i(new_start), j(this->
row_ptr()[perm_pos[row]]) ; i < new_start + row_size ; ++i, ++j)
2609 temp_col_ind[i] = this->
col_ind()[j];
2610 temp_val[i] = this->
val()[j];
2613 new_start += row_size;
2614 temp_row_ptr[row+1] = (IT_)new_start;
2622 ::memcpy(this->
row_ptr(), temp_row_ptr, (
rows() + 1) *
sizeof(IT_));
2626 this->
col_ind()[i] = (IT_)perm_pos[temp_col_ind[i]];
2629 delete[] temp_row_ptr;
2630 delete[] temp_col_ind;
2636 for (
Index row(0) ; row <
rows() ; ++row)
2640 for (
Index i(1), j ; i < row_size ; ++i)
2642 swap_key = this->
col_ind()[i + offset];
2643 swap_val = this->
val()[i + offset];
2645 while (j > 0 && this->
col_ind()[j - 1 + offset] > swap_key)
2648 this->
val()[j + offset] = this->
val()[j - 1 + offset];
2651 this->
col_ind()[j + offset] = swap_key;
2652 this->
val()[j + offset] = swap_val;
2667 std::vector<IT_> row_entries(this->
rows(), IT_(0));
2668 for (
Index row(0) ; row < this->
rows() ; ++row)
2674 row_entries.at(row) += IT_(1);
2680 for (
auto& n : row_entries)
2691 new_row_ptr(0, IT_(0));
2692 for (
Index row(0) ; row < this->
rows() ; ++row)
2694 new_row_ptr(row + 1, new_row_ptr(row) + row_entries.at(row));
2697 row_entries.clear();
2702 for (
Index row(0) ; row < this->
rows() ; ++row)
2708 new_col_ind(counter, this->
col_ind()[el]);
2709 new_val(counter, this->
val()[el]);
2732 const IT_ * prow_ptr(this->
row_ptr());
2733 return Index(prow_ptr[row + 1] - prow_ptr[row]);
2739 void set_line(
const Index row, DT_ *
const pval_set, IT_ *
const pcol_set,
2740 const Index col_start,
const Index stride = 1)
const
2742 const IT_ * prow_ptr(this->
row_ptr());
2743 const IT_ * pcol_ind(this->
col_ind());
2744 const DT_ * pval(this->
val());
2747 const Index end((
Index(prow_ptr[row + 1] - prow_ptr[row])));
2748 for (
Index i(0); i < end; ++i)
2750 pval_set[i * stride] = pval[start + i];
2751 pcol_set[i * stride] = pcol_ind[start + i] + IT_(col_start);
2755 void set_line_reverse(
const Index row,
const DT_ *
const pval_set,
const Index stride = 1)
2757 const IT_ * prow_ptr(this->
row_ptr());
2758 DT_ * pval(this->
val());
2761 const Index end((
Index(prow_ptr[row + 1] - prow_ptr[row])));
2762 for (
Index i(0); i < end; ++i)
2764 pval[start + i] = pval_set[i * stride];
2789 XASSERTM(domain_node <
rows(),
"Domain node index out of range");
2796 XASSERTM(domain_node <
rows(),
"Domain node index out of range");
2826 extern template class SparseMatrixCSR<float, std::uint32_t>;
2827 extern template class SparseMatrixCSR<double, std::uint32_t>;
2828 extern template class SparseMatrixCSR<float, std::uint64_t>;
2829 extern template class SparseMatrixCSR<double, std::uint64_t>;
#define ASSERT(expr)
Debug-Assertion macro definition.
#define XABORTM(msg)
Abortion macro definition with custom message.
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Adjacency Graph implementation.
Index * get_domain_ptr()
Returns the domain pointer array.
Index * get_image_idx()
Returns the image node index array.
Index get_num_indices() const
Returns the total number indices.
Index size() const
returns the size of the permutation
Index * get_perm_pos()
returns the permute-position array
Permutation inverse() const
Computes the inverse permutation.
const std::vector< IT_ * > & get_indices() const
Returns a list of all Index arrays.
std::vector< DT_ * > _elements
List of pointers to all datatype dependent arrays.
Index used_elements() const
Returns the number of effective stored elements.
const std::vector< DT_ * > & get_elements() const
Returns a list of all data arrays.
std::vector< Index > _elements_size
List of corresponding datatype array sizes.
Index size() const
Returns the containers size.
void assign(const Container< DT2_, IT2_ > &other)
Assignment operation.
std::vector< IT_ * > _indices
List of pointers to all IT_ dependent arrays.
void clone(const Container &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
void move(Container &&other)
Assignment move operation.
virtual void clear()
Free all allocated arrays.
std::vector< Index > _indices_size
List of corresponding IT_ array sizes.
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
std::vector< Index > _scalar_index
List of scalars with datatype index.
Blocked Dense data vector class template.
void copy(const DenseVectorBlocked &x, bool full=false)
Performs .
auto elements() const -> const typename Intern::DenseVectorBlockedPerspectiveHelper< DT_, BlockSize_, perspective_ >::Type *
Retrieve a pointer to the data array.
Index size() const
The number of elements.
Dense data vector class template.
DT_ * elements()
Get a pointer to the data array.
void copy(const VT_ &a)
Performs .
Config class for serialize parameter.
Layout scheme for sparse matrix containers.
CSR based blocked sparse matrix.
Index rows() const
Retrieve matrix row count.
IT_ * col_ind()
Retrieve column indices array.
IT_ * row_ptr()
Retrieve row start index array.
Index columns() const
Retrieve matrix column count.
auto val() const -> const typename Intern::BCSRPerspectiveHelper< DT_, BlockHeight_, BlockWidth_, perspective_ >::Type *
Retrieve non zero element array.
Index rows() const
Retrieve matrix row count.
Index used_elements() const
Retrieve non zero element count.
Index columns() const
Retrieve matrix column count.
Gather-Axpy operation for SparseMatrixCSR.
Scatter-Axpy operation for SparseMatrixCSR.
void row_norm2(VectorTypeL &row_norms) const
Computes the 2-norm for every row.
void extract_diag(VectorTypeL &diag) const
extract main diagonal vector from matrix
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
void add_double_mat_product(const LAFEM::SparseMatrixCSR< DT_, IT_ > &d, const LAFEM::DenseVector< DT_, IT_ > &a, const LAFEM::SparseMatrixCSR< DT_, IT_ > &b, const DT_ alpha=DT_(1), const bool allow_incomplete=false)
Adds a double-matrix product onto this matrix.
DT_ norm_frobenius() const
Calculates the Frobenius norm of this matrix.
SparseMatrixCSR & operator=(SparseMatrixCSR &&other)
Move operator.
void bandwidth_row(Index &bandw, Index &bandw_i) const
Retrieve maximum bandwidth among all rows.
void radius_row(Index &radius, Index &radius_i) const
Retrieve maximum radius among all rows.
void scale(const SparseMatrixCSR &x, const DT_ alpha)
Calculate .
Index get_num_nodes_domain() const
void extract_diag_indices(DenseVector< IT_, IT_ > &diag_indices) const
extract main diagonal vector from matrix
DenseVector< DT_, IT_ > VectorTypeL
Compatible L-vector type.
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void clone(const SparseMatrixCSR< DT2_, IT2_ > &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Index get_num_nodes_image() const
void copy(const SparseMatrixCSR &x, bool full=false)
Performs .
DT_ DataType
Our datatype.
void read_from(FileMode mode, const String &filename)
Read in matrix from file.
SparseMatrixCSR transpose() const
Calculate .
DT_ ValueType
Value type, meaning the type of each 'block'.
SparseMatrixCSR(const Adjacency::Graph &graph)
Constructor.
void add_mat_mat_product(const LAFEM::SparseMatrixCSR< DT_, IT_ > &d, const LAFEM::SparseMatrixCSR< DT_, IT_ > &b, const DT_ alpha=DT_(1), const bool allow_incomplete=false)
Adds a matrix-matrix product onto this matrix.
DT_ max_element() const
Retrieve the maximum value of this matrix.
DT_ max_abs_element() const
Retrieve the absolute maximum value of this matrix.
void add_double_mat_product(const LAFEM::SparseMatrixCSR< DT_, IT_ > &d, const LAFEM::SparseMatrixCSR< DT_, IT_ > &a, const LAFEM::SparseMatrixCSR< DT_, IT_ > &b, const DT_ alpha=DT_(1), const bool allow_incomplete=false)
Adds a double-matrix product onto this matrix.
DT_ operator()(Index row, Index col) const
Retrieve specific matrix element.
void convert(const SparseMatrixCSR< DT2_, IT2_ > &other)
Conversion method.
void axpy(const SparseMatrixCSR &x, const DT_ alpha=DT_(1))
Calculate .
SparseMatrixCSR(SparseMatrixCSR &&other)
Move Constructor.
VectorTypeL extract_diag() const
extract main diagonal vector from matrix
void row_norm2sqr(VectorTypeL &row_norms) const
Computes the square of the 2-norm for every row.
void lump_rows(VectorTypeL &lump) const
SparseMatrixCSR(std::vector< char > input)
Constructor.
void apply(DenseVectorBlocked< DT_, IT_, BlockSize_ > &r, const DenseVectorBlocked< DT_, IT_, BlockSize_ > &x) const
Calculate .
DT_ max_rel_diff(const SparseMatrixCSR &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
std::vector< char > serialize(const LAFEM::SerialConfig &config=SerialConfig()) const
Serialization of complete container entity.
void convert(const MT_ &a)
Conversion method.
SparseMatrixCSR(FileMode mode, std::istream &file)
Constructor.
ImageIterator image_begin(Index domain_node) const
void bandwidth_column(Index &bandw, Index &bandw_i) const
Retrieve maximum bandwidth among all columns.
void write_out(FileMode mode, const String &filename, bool symmetric=false) const
Write out matrix to file.
void permute(Adjacency::Permutation &perm_row, Adjacency::Permutation &perm_col)
Permutate matrix rows and columns according to the given Permutations.
DT_ min_element() const
Retrieve the minimum value of this matrix.
SparseMatrixCSR(Index rows_in, Index columns_in)
Constructor.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
IT_ * col_ind()
Retrieve column indices array.
DT_ * val()
Retrieve non zero element array.
DenseVector< DT_, IT_ > VectorTypeR
Compatible R-vector type.
Index rows() const
Retrieve matrix row count.
void deserialize(std::vector< char > input)
Deserialization of complete container entity.
SparseMatrixCSR clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
SparseLayout< IT_, layout_id > layout() const
Retrieve convenient sparse matrix layout object.
Index get_length_of_line(const Index row) const
Returns the number of NNZ-elements of the selected row.
DT_ min_abs_element() const
Retrieve the absolute minimum value of this matrix.
SparseMatrixCSR(const Index rows_in, const Index columns_in, DenseVector< IT_, IT_ > &col_ind_in, DenseVector< DT_, IT_ > &val_in, DenseVector< IT_, IT_ > &row_ptr_in)
Constructor.
Index columns() const
Retrieve matrix column count.
void extract_diag(VectorTypeL &diag, DenseVector< IT_, IT_ > &diag_indices) const
extract main diagonal vector from matrix
void add_double_mat_product(const LAFEM::SparseMatrixBCSR< DT_, IT_, 1, bs_ > &d, const LAFEM::DenseVectorBlocked< DT_, IT_, bs_ > &a, const LAFEM::SparseMatrixBCSR< DT_, IT_, bs_, 1 > &b, const DT_ alpha=DT_(1), const bool allow_incomplete=false)
Adds a double-matrix product onto this matrix.
void row_norm2sqr(VectorTypeL &row_norms, const VectorTypeR &scal) const
Computes the square of the 2-norm for every row, where every row is scaled by a vector.
void scale_rows(const SparseMatrixCSR &x, const DenseVector< DT_, IT_ > &s)
Calculate .
VectorTypeL lump_rows() const
Returns the lumped rows vector.
static constexpr SparseLayoutId layout_id
Our used layout type.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void read_from(FileMode mode, std::istream &file)
Read in matrix from stream.
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
void radius_column(Index &radius, Index &radius_i) const
Retrieve maximum radius among all column.
SparseMatrixCSR(Index rows_in, Index columns_in, Index used_elements_in)
Constructor.
bool same_layout(const SparseMatrixCSR &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
Index used_elements() const
Retrieve non zero element count.
SparseMatrixCSR(FileMode mode, const String &filename)
Constructor.
void shrink(DT_ eps)
Shrink matrix and drop small values.
void scale_cols(const SparseMatrixCSR &x, const DenseVector< DT_, IT_ > &s)
Calculate .
IT_ * row_ptr()
Retrieve row start index array.
SparseMatrixCSR()
Constructor.
void write_out(FileMode mode, std::ostream &file, bool symmetric=false) const
Write out matrix to file.
DenseVector< IT_, IT_ > extract_diag_indices() const
extract main diagonal vector from matrix
void apply(DenseVectorBlocked< DT_, IT_, BlockSize_ > &r, const DenseVectorBlocked< DT_, IT_, BlockSize_ > &x, const DenseVectorBlocked< DT_, IT_, BlockSize_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void convert_reverse(MT_ &a) const
Reverse Conversion method.
friend std::ostream & operator<<(std::ostream &lhs, const SparseMatrixCSR &b)
SparseMatrixCSR streaming operator.
SparseMatrixCSR(const SparseLayout< IT_, layout_id > &layout_in)
Constructor.
ImageIterator image_end(Index domain_node) const
void transpose(const SparseMatrixCSR &x)
Calculate .
void convert(const SparseMatrixBCSR< DT2_, IT2_, BlockHeight_, BlockWidth_ > &other)
Conversion method.
IT_ IndexType
Our indextype.
void convert(const Adjacency::Graph &graph)
Conversion method.
void convert(const SparseMatrixBanded< DT2_, IT2_ > &other)
Conversion method.
SparseMatrixCSR(const MT_ &other)
Constructor.
static String name()
Returns a descriptive string.
const IT_ * ImageIterator
ImageIterator typedef for Adjactor interface implementation.
static void copy(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void release_memory(void *address)
release memory or decrease reference counter
static void increase_memory(void *address)
increase memory counter
static void add_flops(Index flops)
Add an amount of flops to the global flop counter.
String class implementation.
double elapsed(const TimeStamp &before) const
Calculates the time elapsed between two time stamps.
Tiny Matrix class template.
Tiny Vector class template.
constexpr std::size_t FileOutStreamBufferSize
OutStreamBufferSize.
@ symmetric
matrix with symmetric structure and values
T_ abs(T_ x)
Returns the absolute value.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
String stringify(const T_ &item)
Converts an item into a String.
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
std::uint64_t Index
Index data type.