14 namespace sparse_detail {
41 n = matrix.find_n(i, j);
42 matrix.unsafe_set_hint(i, j, n, matrix.get_hint(i, j, n));
43 ptr = &matrix.unsafe_ref_hint(n);
51 matrix.set_hint(i, j, n, *ptr);
152 inline bool is_zero(
double a) {
159 inline bool is_zero(
float a) {
166 inline bool is_zero(std::complex<float> a) {
167 return a.real() == 0.0f && a.imag() == 0.0f;
173 inline bool is_zero(std::complex<double> a) {
174 return a.real() == 0.0 && a.imag() == 0.0;
181 return a.
real == 0.0f && a.
imag == 0.0f;
188 return a.
real == 0.0 && a.
imag == 0.0;
197 template <
typename T>
198 bool is_non_zero(T value) {
199 return !is_zero(value);
210 template <
typename T, sparse_storage SS,
size_t D>
218 template <
typename T,
size_t D>
221 static constexpr
size_t n_dimensions =
D;
241 using base_type::_dimensions;
242 using base_type::_size;
249 using base_type::check_invariants;
250 using base_type::release;
256 template <
typename It>
257 void build_from_iterable(
const It&
iterable) {
259 for (
auto v : iterable) {
260 if (sparse_detail::is_non_zero(v)) {
268 _row_index = base_type::template allocate<index_type>(nnz);
269 _col_index = base_type::template allocate<index_type>(nnz);
271 auto it = iterable.begin();
274 for (
size_t i = 0;
i <
rows(); ++
i) {
276 if (sparse_detail::is_non_zero(*it)) {
292 void reserve_hint(
size_t hint) {
293 cpp_assert(hint < nnz + 1,
"Invalid hint for reserve_hint");
296 auto new_memory =
allocate(nnz + 1);
297 auto new_row_index = base_type::template allocate<index_type>(nnz + 1);
298 auto new_col_index = base_type::template allocate<index_type>(nnz + 1);
302 std::copy_n(_memory, nnz, new_memory);
303 std::copy_n(_row_index, nnz, new_row_index);
304 std::copy_n(_col_index, nnz, new_col_index);
307 std::copy(_memory, _memory + hint, new_memory);
308 std::copy(_row_index, _row_index + hint, new_row_index);
309 std::copy(_col_index, _col_index + hint, new_col_index);
312 std::copy(_memory + hint, _memory + nnz, new_memory + hint + 1);
313 std::copy(_row_index + hint, _row_index + nnz, new_row_index + hint + 1);
314 std::copy(_col_index + hint, _col_index + nnz, new_col_index + hint + 1);
317 release(_memory, nnz);
318 release(_row_index, nnz);
319 release(_col_index, nnz);
321 _memory = new_memory;
322 _col_index = new_col_index;
323 _row_index = new_row_index;
325 cpp_assert(hint == 0,
"Invalid hint for reserve_hint");
328 _row_index = base_type::template allocate<index_type>(nnz + 1);
329 _col_index = base_type::template allocate<index_type>(nnz + 1);
338 void erase_hint(
size_t n) {
339 cpp_assert(nnz > 0,
"Invalid erase_hint call (no non-zero elements");
342 release(_memory, nnz);
343 release(_row_index, nnz);
344 release(_col_index, nnz);
347 _row_index =
nullptr;
348 _col_index =
nullptr;
350 auto new_memory =
allocate(nnz - 1);
351 auto new_row_index = base_type::template allocate<index_type>(nnz - 1);
352 auto new_col_index = base_type::template allocate<index_type>(nnz - 1);
355 std::copy_n(_memory, nnz - 1, new_memory);
356 std::copy_n(_row_index, nnz - 1, new_row_index);
357 std::copy_n(_col_index, nnz - 1, new_col_index);
359 std::copy(_memory, _memory + n, new_memory);
360 std::copy(_row_index, _row_index + n, new_row_index);
361 std::copy(_col_index, _col_index + n, new_col_index);
363 std::copy(_memory + n + 1, _memory + nnz, new_memory + n);
364 std::copy(_row_index + n + 1, _row_index + nnz, new_row_index + n);
365 std::copy(_col_index + n + 1, _col_index + nnz, new_col_index + n);
368 release(_memory, nnz);
369 release(_row_index, nnz);
370 release(_col_index, nnz);
372 _memory = new_memory;
373 _row_index = new_row_index;
374 _col_index = new_col_index;
385 size_t find_n(
size_t i,
size_t j)
const noexcept {
386 for (
size_t n = 0; n < nnz; ++
n) {
388 if (_row_index[n] ==
i && _col_index[n] ==
j) {
393 if ((_row_index[n] ==
i && _col_index[n] >
j) || _row_index[n] >
i) {
405 void unsafe_set_hint(
size_t i,
size_t j,
size_t n,
value_type value) {
407 if (n < nnz && _row_index[n] == i && _col_index[n] == j) {
422 value_type get_hint(
size_t i,
size_t j,
size_t n)
const noexcept
requires(n_dimensions == 2) {
423 if (n < nnz && _row_index[n] == i && _col_index[n] == j) {
433 void set_hint(
size_t i,
size_t j,
size_t n,
value_type value) {
435 if (_row_index[n] == i && _col_index[n] == j) {
438 if (sparse_detail::is_non_zero(value)) {
439 unsafe_set_hint(i, j, n, value);
446 if (sparse_detail::is_non_zero(value)) {
447 unsafe_set_hint(i, j, n, value);
453 if (sparse_detail::is_non_zero(value)) {
454 unsafe_set_hint(i, j, n, value);
469 const value_type& unsafe_ref_hint(
size_t n)
const {
478 template <not_generator E>
479 void inherit(
const E& e) {
480 cpp_assert(n_dimensions == etl::dimensions(e),
"Invalid number of dimensions");
484 for (
size_t d = 0; d < n_dimensions; ++d) {
486 _size *= _dimensions[d];
491 using base_type::columns;
493 using base_type::rows;
494 using base_type::size;
509 template <size_c... S>
511 :
base_type(util::size(sizes...), {{
static_cast<size_t>(sizes)...}}), _memory(
nullptr), _row_index(
nullptr), _col_index(
nullptr), nnz(0) {
519 template <
typename... S>
521 :
base_type(util::size(std::make_index_sequence<(sizeof...(S) - 1)>(), sizes...),
522 dyn_detail::sizes(std::make_index_sequence<(sizeof...(S) - 1)>(), sizes...)) {
523 static_assert(
sizeof...(S) == D + 1,
"Invalid number of dimensions");
525 auto list = cpp::last_value(sizes...);
526 build_from_iterable(list);
533 template <
typename S1,
typename... S>
535 :
base_type(util::size(std::make_index_sequence<(sizeof...(S))>(), s1, sizes...),
536 dyn_detail::sizes(std::make_index_sequence<(sizeof...(S))>(), s1, sizes...)) {
537 auto list = cpp::last_value(sizes...).template list<value_type>();
538 build_from_iterable(list);
554 validate_assign(*
this, rhs);
570 template <etl_expr E>
579 validate_assign(*
this, e);
584 if (e.alias(*
this)) {
617 value_type get(
size_t i,
size_t j)
const noexcept(assert_nothrow) {
618 cpp_assert(i <
dim(0),
"Out of bounds");
619 cpp_assert(j <
dim(1),
"Out of bounds");
621 auto n = find_n(i, j);
622 return get_hint(i, j, n);
632 cpp_assert(i <
dim(0),
"Out of bounds");
633 cpp_assert(j <
dim(1),
"Out of bounds");
635 return {*
this,
i, j};
645 cpp_assert(i <
dim(0),
"Out of bounds");
646 cpp_assert(j <
dim(1),
"Out of bounds");
648 return {*
this,
i, j};
659 cpp_assert(n < size(),
"Out of bounds");
672 cpp_assert(n < size(),
"Out of bounds");
694 size_t non_zeros() const noexcept {
705 cpp_assert(i <
dim(0),
"Out of bounds");
706 cpp_assert(j <
dim(1),
"Out of bounds");
708 auto n = find_n(i, j);
709 set_hint(i, j, n, value);
723 void unsafe_set(
size_t i,
size_t j,
value_type value) {
724 cpp_assert(i <
dim(0),
"Out of bounds");
725 cpp_assert(j <
dim(1),
"Out of bounds");
727 auto n = find_n(i, j);
729 unsafe_set_hint(i, j, n, value);
737 void erase(
size_t i,
size_t j) {
738 cpp_assert(i <
dim(0),
"Out of bounds");
739 cpp_assert(j <
dim(1),
"Out of bounds");
741 auto n = find_n(i, j);
743 if (n < nnz && _row_index[n] == i && _col_index[n] == j) {
753 template <
typename E>
754 bool alias(
const E& rhs)
const noexcept {
755 if constexpr (is_sparse_matrix<E>) {
758 return rhs.alias(*
this);
768 template <
typename V>
769 void visit([[maybe_unused]] V&& visitor)
const {}
776 release(_memory, nnz);
777 release(_row_index, nnz);
778 release(_col_index, nnz);
802 template <
typename L>
811 template <
typename L>
820 template <
typename L>
829 template <
typename L>
838 template <
typename L>
847 template <
typename L>
859 os <<
"SM[" << matrix.dim(0);
861 for (
size_t i = 1; i <
D; ++
i) {
862 os <<
"," << matrix.dim(i);
Simple collection of values to initialize a dyn matrix.
Definition: dyn_base.hpp:36
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:217
sparse_reference & operator*=(value_type rhs)
Multiply by a new value the proxy reference.
Definition: sparse.hpp:95
Complex number implementation.
Definition: complex.hpp:31
sparse_reference & operator=(value_type rhs)
Sets a new value to the proxy reference.
Definition: sparse.hpp:65
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: dyn_matrix_view.hpp:197
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:244
value_type * raw_pointer_type
A raw pointer type.
Definition: sparse.hpp:24
value_t< sub_type > value_type
The value contained in the expression.
Definition: dyn_matrix_view.hpp:31
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:235
size_t n
hint
Definition: sparse.hpp:31
const_memory_t< sub_type > const_memory_type
The const memory access type.
Definition: dyn_matrix_view.hpp:33
value_type & raw_reference_type
A raw reference type.
Definition: sparse.hpp:25
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:208
D D
The number of dimensions.
Definition: dyn_matrix_view.hpp:24
Define traits to get vectorization information for types when no vector mode is available.
Definition: no_vectorization.hpp:16
order
Storage order of a matrix.
Definition: order.hpp:15
index_type * index_memory_type
The memory type to the COO index.
Definition: sparse.hpp:235
raw_pointer_type ptr
Pointer to the element.
Definition: sparse.hpp:32
memory_t< sub_type > memory_type
The memory acess type.
Definition: dyn_matrix_view.hpp:32
dyn_base< this_type, T, D > base_type
The base type.
Definition: sparse.hpp:227
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
auto dim(E &&value, size_t i) -> detail::identity_helper< E, dim_view< detail::build_identity_type< E >, D >>
Return a view representing the ith Dth dimension.
Definition: view_expression_builder.hpp:25
Coordinate Format (COO)
Definition: sparse.hpp:220
M matrix_type
The matrix type.
Definition: sparse.hpp:22
std::ostream & operator<<(std::ostream &os, const etl::complex< T > &c)
Outputs a textual representation of the complex number in the given stream.
Definition: complex.hpp:576
size_t columns(const E &expr)
Returns the number of columns of the given ETL expression.
Definition: helpers.hpp:78
void ensure_cpu_up_to_date() const
Ensures that the GPU memory is allocated and that the GPU memory is up to date (to undefined value)...
Definition: dyn_matrix_view.hpp:271
sparse_storage
Enumeration for sparse storage formats.
Definition: sparse_storage.hpp:20
typename matrix_type::value_type value_type
The value type.
Definition: sparse.hpp:23
void std_mod_evaluate(Expr &&expr, Result &&result)
Compound modulo evaluation of the expr into result.
Definition: evaluator.hpp:1271
const_return_type operator()(size_t j) const
Access to the element at the given position.
Definition: dyn_matrix_view.hpp:89
matrix_type & matrix
Reference to the matrix.
Definition: sparse.hpp:28
value_type read_flat(size_t j) const noexcept
Returns the value at the given index This function never has side effects.
Definition: dyn_matrix_view.hpp:111
void std_mul_evaluate(Expr &&expr, Result &&result)
Compound multiply evaluation of the expr into result.
Definition: evaluator.hpp:1233
Base class and utilities for dyn matrix implementations.
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: dyn_matrix_view.hpp:263
requires(D > 0) struct dyn_base
Matrix with run-time fixed dimensions.
Definition: dyn_base.hpp:113
sparse_reference & operator-=(value_type rhs)
Subtract a new value from the proxy reference.
Definition: sparse.hpp:85
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: dyn_matrix_view.hpp:280
Definition: expr_fwd.hpp:59
sparse_reference & operator%=(value_type rhs)
Modulo by a new value the proxy reference.
Definition: sparse.hpp:115
value_type real
The real part.
Definition: complex.hpp:34
void std_sub_evaluate(Expr &&expr, Result &&result)
Compound subtract evaluation of the expr into result.
Definition: evaluator.hpp:1214
std::array< size_t, n_dimensions > dimension_storage_impl
The type used to store the dimensions.
Definition: sparse.hpp:231
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
sparse_reference & operator/=(value_type rhs)
Divide by a new value the proxy reference.
Definition: sparse.hpp:105
size_t index_type
The type used to store the COO index.
Definition: sparse.hpp:234
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: dyn_matrix_view.hpp:71
sparse_reference & operator+=(value_type rhs)
Adds a new value to the proxy reference.
Definition: sparse.hpp:75
auto allocate(size_t size, mangling_faker< S >=mangling_faker< S >())
Allocate an array of the given size for the given type.
Definition: allocator.hpp:80
Traits to test if the constructor is an initializer list constructor.
Definition: dyn_base.hpp:89
size_t j
The second index.
Definition: sparse.hpp:30
size_t rows(const E &expr)
Returns the number of rows of the given ETL expression.
Definition: helpers.hpp:58
value_type imag
The imaginary part.
Definition: complex.hpp:35
Sparse matrix implementation.
Definition: sparse.hpp:211
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
size_t i
The first index.
Definition: sparse.hpp:29
void std_div_evaluate(Expr &&expr, Result &&result)
Compound divide evaluation of the expr into result.
Definition: evaluator.hpp:1252
sparse_reference(matrix_type &matrix, size_t i, size_t j)
Constructs a new sparse_reference.
Definition: sparse.hpp:40
~sparse_reference()
Destruct the proxy reference and updates the matrix to the correct value.
Definition: sparse.hpp:49
A proxy representing a reference to an element of a sparse matrix.
Definition: sparse.hpp:21
std::add_const_t< value_type > & const_raw_reference_type
A raw const reference type.
Definition: sparse.hpp:26
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226