11#include <kernel/util/math.hpp>
12#include <kernel/lafem/forward.hpp>
13#include <kernel/lafem/container.hpp>
14#include <kernel/lafem/dense_vector.hpp>
15#include <kernel/lafem/sparse_layout.hpp>
16#include <kernel/lafem/arch/scale.hpp>
17#include <kernel/lafem/arch/axpy.hpp>
18#include <kernel/lafem/arch/apply.hpp>
19#include <kernel/lafem/arch/norm.hpp>
20#include <kernel/adjacency/graph.hpp>
75 template <
typename DT_,
typename IT_ = Index>
89 typedef IT_ IndexType;
97 Index _num_of_offsets;
107 _num_rows(matrix.
rows()),
115 _col_ptr =
new IT_[_num_cols];
117 for(
Index i(0); i < _num_cols; ++i)
119 _col_ptr[i] = _deadcode;
126 if(_col_ptr !=
nullptr)
132 template<
typename LocalMatrix_,
typename RowMapping_,
typename ColMapping_>
133 void operator()(
const LocalMatrix_& loc_mat,
const RowMapping_& row_map,
134 const ColMapping_& col_map, DT_ alpha = DT_(1))
137 for(
int i(0); i < row_map.get_num_local_dofs(); ++i)
140 const Index ix = row_map.get_index(i);
143 for(IT_ k(0); k < _num_of_offsets; ++k)
145 if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
147 _col_ptr[_offsets[k] + ix + 1 - _num_rows] = IT_(k * _num_rows + ix);
152 for(
int j(0); j < col_map.get_num_local_dofs(); ++j)
155 const Index jx = col_map.get_index(j);
158 ASSERTM(_col_ptr[jx] != _deadcode,
"invalid column index");
161 _data[_col_ptr[jx]] += alpha * loc_mat[i][j];
168 for(IT_ k(0); k < _num_of_offsets; ++k)
170 if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
172 _col_ptr[_offsets[k] + ix + 1 - _num_rows] = _deadcode;
190 typedef DT_ DataType;
191 typedef IT_ IndexType;
199 Index _num_of_offsets;
209 _num_rows(matrix.
rows()),
217 _col_ptr =
new IT_[_num_cols];
219 for(
Index i(0); i < _num_cols; ++i)
221 _col_ptr[i] = _deadcode;
228 if(_col_ptr !=
nullptr)
234 template<
typename LocalMatrix_,
typename RowMapping_,
typename ColMapping_>
235 void operator()(LocalMatrix_& loc_mat,
const RowMapping_& row_map,
236 const ColMapping_& col_map, DT_ alpha = DT_(1))
239 for(
int i(0); i < row_map.get_num_local_dofs(); ++i)
242 const Index ix = row_map.get_index(i);
245 for(IT_ k(0); k < _num_of_offsets; ++k)
247 if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
249 _col_ptr[_offsets[k] + ix + 1 - _num_rows] = IT_(k * _num_rows + ix);
254 for(
int j(0); j < col_map.get_num_local_dofs(); ++j)
257 const Index jx = col_map.get_index(j);
260 ASSERTM(_col_ptr[jx] != _deadcode,
"invalid column index");
263 loc_mat[i][j] += alpha * _data[_col_ptr[jx]];
270 for(IT_ k(0); k < _num_of_offsets; ++k)
272 if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
274 _col_ptr[_offsets[k] + ix + 1 - _num_rows] = _deadcode;
299 Index & _used_elements()
304 Index & _num_of_offsets()
328 const IT_ *
const _offsets;
331 ImageIterator() : _k(IT_(0)), _s(IT_(0)), _offsets(
nullptr) {}
339 _offsets = other._offsets;
345 return this->_k != other._k;
354 Index operator*()
const
356 return Index(_s + _offsets[_k]);
360 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
364 template <
typename DataType2_,
typename IndexType2_>
391 this->
_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
392 this->
_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
393 this->
_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
415 Container<DT_, IT_>(rows_in * columns_in)
417 if (val_in.
size() != rows_in * offsets_in.
size())
419 XABORTM(
"Size of values does not match to number of offsets and row count!");
425 Index tused_elements(0);
427 for (
Index i(0); i < offsets_in.
size(); ++i)
431 if (toffset +
Index(2) > rows_in + columns_in)
433 XABORTM(
"Offset out of matrix!");
436 tused_elements += columns_in +
Math::min(rows_in, columns_in + rows_in - toffset - 1) -
Math::max(columns_in + rows_in - toffset - 1, columns_in);
460 template <
typename MT_>
477 Index num_rows = graph.get_num_nodes_domain();
478 Index num_cols = graph.get_num_nodes_image();
483 std::set<IT_> moffsets;
485 for(
Index row(0); row < num_rows; ++row)
487 for(
Index j(dom_ptr[row]); j < dom_ptr[row+1]; ++j)
489 moffsets.insert(IT_(num_rows - 1 + img_idx[j] - row));
494 auto * ptoffsets = toffsets.
elements();
497 for (
auto off : moffsets)
499 ptoffsets[idx] = off;
504 toffsets_mem.
convert(toffsets);
545 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
549 deserialize<DT2_, IT2_>(input);
573 this->
move(std::forward<SparseMatrixBanded>(other));
589 t.
clone(*
this, clone_mode);
601 template<
typename DT2_,
typename IT2_>
627 this->
_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
628 this->
_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
629 this->
_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
647 template <
typename DT2_,
typename IT2_>
653 template <
typename DT2_,
typename IT2_>
656 XASSERT(csr.template used_elements<Perspective::pod>() > 0);
658 std::set<IT_> offset_set;
661 for (
Index row(0) ; row < nrows ; ++row)
666 IT_ off = IT_(csr.
col_ind()[i] - row + nrows - 1);
667 offset_set.insert(off);
671 DenseVector<DT_, IT_> val_new(
Index(offset_set.size()) * nrows, DT_(0));
672 for (
Index row(0) ; row < nrows ; ++row)
677 Index offset = (col - row + nrows - 1);
678 Index band =
Index(std::distance(offset_set.begin(), offset_set.find(IT_(offset))));
679 val_new.elements()[band * nrows + row] = csr.
val()[i];
683 DenseVector<IT_, IT_> offsets_new(
Index(offset_set.size()));
684 auto it_offset = offset_set.begin();
685 for (
Index i(0) ; i < offset_set.size() ; ++i, ++it_offset)
687 offsets_new(i, *it_offset);
691 SparseMatrixBanded<DT_, IT_> temp(nrows, ncolumns, val_new, offsets_new);
692 this->
move(std::move(temp));
704 std::ios_base::openmode bin = std::ofstream::out | std::ofstream::binary;
706 bin = std::ofstream::out;
708 char* buff =
nullptr;
714 file.open(filename.c_str(), bin);
716 XABORTM(
"Unable to open Matrix file " + filename);
733 if (! std::is_same<DT_, double>::value)
734 std::cout<<
"Warning: You are writing out a banded matrix that is not double precision!\n";
736 this->
template _serialize<double, std::uint64_t>(
FileMode::fm_bm, file);
739 XABORTM(
"Filemode not supported!");
756 MemoryPool::synchronize();
763 if (row + toffset +
Index(1) == col + trows)
765 return this->
val()[i * trows + row];
786 template <Perspective = Perspective::native>
797 template <Perspective = Perspective::native>
808 template <Perspective = Perspective::native>
834 DT_
const *
val()
const
861 return "SparseMatrixBanded";
872 this->_copy_content(x, full);
886 const DT_ alpha = DT_(1))
888 XASSERTM(x.
rows() == this->rows(),
"Matrix rows do not match!");
889 XASSERTM(x.
columns() == this->columns(),
"Matrix columns do not match!");
896 Arch::Axpy::value(this->
val(), alpha, x.
val(), this->rows() * this->num_of_offsets());
899 Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
910 XASSERTM(x.
rows() == this->rows(),
"Matrix rows do not match!");
911 XASSERTM(x.
columns() == this->columns(),
"Matrix columns do not match!");
918 Arch::Scale::value(this->
val(), x.
val(), alpha, this->rows() * this->num_of_offsets());
921 Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
939 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
952 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
953 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
955 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
967 this->num_of_offsets(),
972 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
983 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
984 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
986 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
991 Arch::Apply::banded_transposed(r.
elements(),
998 this->num_of_offsets(),
1003 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1017 const DT_ alpha = DT_(1))
const
1019 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
1020 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
1021 XASSERTM(y.
size() == this->rows(),
"Vector size of y does not match!");
1023 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1042 this->num_of_offsets(),
1047 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1061 const DT_ alpha = DT_(1))
const
1063 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
1064 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
1065 XASSERTM(y.
size() == this->columns(),
"Vector size of y does not match!");
1067 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(),
"Vector x and r must not share the same memory!");
1079 Arch::Apply::banded_transposed(r.
elements(),
1086 this->num_of_offsets(),
1091 Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
1098 XASSERTM(diag.
size() ==
rows(),
"diag size does not match matrix row count!");
1126 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
1146 Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
1161 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)
1175 offsets_a =
const_cast<IT_*
>(this->
offsets());
1176 offsets_b =
const_cast<IT_*
>(x.
offsets());
1182 if (offsets_a[i] != offsets_b[i])
1203 template <
typename DT2_ = DT_,
typename IT2_ = IT_>
1206 return this->
template _serialize<DT2_, IT2_>(
FileMode::fm_bm, config);
1217 std::ios_base::openmode bin = std::ifstream::in | std::ifstream::binary;
1219 bin = std::ifstream::in;
1220 std::ifstream file(filename.c_str(), bin);
1221 if (! file.is_open())
1222 XABORTM(
"Unable to open Matrix file " + filename);
1238 this->
template _deserialize<double, std::uint64_t>(
FileMode::fm_bm, file);
1241 XABORTM(
"Filemode not supported!");
1258 template <
typename ITX_>
1277 template <
typename ITX_>
1281 if (i ==
Index (-1))
1328 const IT_ * toffsets(
offsets());
1332 for(IT_ k(0); k < tnum_of_offsets; ++k)
1334 if(toffsets[k] + domain_node + 1 >= trows)
1344 const IT_ * toffsets(
offsets());
1348 for(IT_ k(0); k < tnum_of_offsets; ++k)
1350 if(toffsets[k] + domain_node + 1 >= 2 * trows)
1355 return ImageIterator(tnum_of_offsets, domain_node + 1 - trows, toffsets);
#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.
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.
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.
std::vector< Index > _indices_size
List of corresponding IT_ array sizes.
std::vector< Index > _scalar_index
List of scalars with datatype index.
Dense data vector class template.
void convert(const DenseVector< DT2_, IT2_ > &other)
Conversion method.
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.
Gather-Axpy operation for SparseMatrixBanded.
ImageIterator class for Adjactor interface implementation.
Scatter-Axpy operation for SparseMatrixBanded.
void extract_diag(VectorTypeL &diag) const
SparseMatrixBanded clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
SparseMatrixBanded & operator=(SparseMatrixBanded &&other)
Move operator.
void read_from(FileMode mode, std::istream &file)
Read in matrix from stream.
friend std::ostream & operator<<(std::ostream &lhs, const SparseMatrixBanded &b)
SparseMatrixBanded streaming operator.
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
DT_ ValueType
our value type
void convert(const SparseMatrixBanded< DT2_, IT2_ > &other)
Conversion method.
Index rows() const
Retrieve matrix row count.
bool same_layout(const SparseMatrixBanded &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
SparseMatrixBanded(const SparseLayout< IT_, layout_id > &layout_in)
Constructor.
void copy(const SparseMatrixBanded &x, bool full=false)
Performs .
DT_ DataType
Our datatype.
SparseLayout< IT_, layout_id > layout() const
Retrieve convenient sparse matrix layout object.
DenseVector< DataType, IT_ > VectorTypeR
Compatible R-vector type.
SparseMatrixBanded(const Index rows_in, const Index columns_in, DenseVector< DT_, IT_ > &val_in, DenseVector< IT_, IT_ > &offsets_in)
Constructor.
void deserialize(std::vector< char > input)
Deserialization of complete container entity.
IT_ * offsets()
Retrieve offsets array.
Index start_offset(const Index i) const
Returns first row-index of the diagonal matching to the offset i.
IT_ IndexType
Our indextype.
void write_out(FileMode mode, const String &filename) const
Write out matrix to file.
Index used_elements() const
Retrieve non zero element count.
static constexpr SparseLayoutId layout_id
Our used layout type.
SparseMatrixBanded(FileMode mode, String filename)
Constructor.
Index end_offset(const Index i) const
Returns last row-index of the diagonal matching to the offset i.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
DT_ * val()
Retrieve element array.
Index _start_offset(const Index i, const ITX_ *const offsets, const Index rows_in, const Index columns_in, const Index noo) const
Returns first row-index of the diagonal matching to the offset i.
VectorTypeL extract_diag() const
extract main diagonal vector from matrix
DT_ operator()(Index row, Index col) const
Retrieve specific matrix element.
DenseVector< DataType, IT_ > VectorTypeL
Compatible L-vector type.
void read_from(FileMode mode, const String &filename)
Read in matrix from file.
DT_ max_rel_diff(const SparseMatrixBanded &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
Index num_of_offsets() const
Retrieve number of offsets.
Index get_num_nodes_image() const
SparseMatrixBanded(FileMode mode, std::istream &file)
Constructor.
Index _end_offset(const Index i, const ITX_ *const offsets, const Index rows_in, const Index columns_in, const Index noo) const
Returns last row-index of the diagonal matching to the offset i.
void write_out(FileMode mode, std::ostream &file) const
Write out matrix to file.
SparseMatrixBanded(const Adjacency::Graph &graph)
Constructor.
DT_ norm_frobenius() const
Calculates the Frobenius norm of this matrix.
void clone(const SparseMatrixBanded< DT2_, IT2_ > &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
std::vector< char > serialize(const LAFEM::SerialConfig &config=SerialConfig()) const
Serialization of complete container entity.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
ImageIterator image_begin(Index domain_node) const
SparseMatrixBanded()
Constructor.
Index get_num_nodes_domain() const
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
ImageIterator image_end(Index domain_node) const
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
SparseMatrixBanded(std::vector< char > input)
Constructor.
void axpy(const SparseMatrixBanded &x, const DT_ alpha=DT_(1))
Calculate .
SparseMatrixBanded(const MT_ &other)
Constructor.
void scale(const SparseMatrixBanded &x, const DT_ alpha)
Calculate .
SparseMatrixBanded(SparseMatrixBanded &&other)
Move Constructor.
Index columns() const
Retrieve matrix column count.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
static String name()
Returns a descriptive string.
IT_ * col_ind()
Retrieve column indices array.
DT_ * val()
Retrieve non zero element array.
Index rows() const
Retrieve matrix row count.
Index columns() const
Retrieve matrix column count.
IT_ * row_ptr()
Retrieve row start index array.
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.
constexpr std::size_t FileOutStreamBufferSize
OutStreamBufferSize.
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.
std::uint64_t Index
Index data type.