11#ifndef ARCCORE_ALINA_ADAPTERS_H
12#define ARCCORE_ALINA_ADAPTERS_H
27#include "arccore/alina/AlinaUtils.h"
28#include "arccore/alina/BuiltinBackend.h"
29#include "arccore/alina/ValueTypeInterface.h"
30#include "arccore/alina/MatrixOperationsImpl.h"
31#include "arccore/alina/CuthillMcKeeReorderer.h"
40namespace Arcane::Alina::backend
46template <
typename N,
typename PRng,
typename CRng,
typename VRng>
49 typedef std::decay_t<decltype(std::declval<VRng>()[0])> type;
52template <
typename N,
typename PRng,
typename CRng,
typename VRng>
55 static size_t get(
const std::tuple<N, PRng, CRng, VRng>& A)
57 return std::get<0>(A);
61template <
typename N,
typename PRng,
typename CRng,
typename VRng>
64 static size_t get(
const std::tuple<N, PRng, CRng, VRng>& A)
66 return std::get<0>(A);
70template <
typename N,
typename PRng,
typename CRng,
typename VRng>
73 static size_t get(
const std::tuple<N, PRng, CRng, VRng>& A)
75 return std::get<1>(A)[std::get<0>(A)];
79template <
typename N,
typename PRng,
typename CRng,
typename VRng>
86 typedef std::decay_t<decltype(std::declval<CRng>()[0])> col_type;
87 typedef std::decay_t<decltype(std::declval<VRng>()[0])> val_type;
89 type(
const std::tuple<N, PRng, CRng, VRng>& A,
size_t row)
90 : m_col(std::begin(std::get<2>(A)))
91 , m_end(std::begin(std::get<2>(A)))
92 , m_val(std::begin(std::get<3>(A)))
94 typedef std::decay_t<decltype(std::declval<PRng>()[0])>
ptr_type;
96 ptr_type row_begin = std::get<1>(A)[row];
97 ptr_type row_end = std::get<1>(A)[row + 1];
104 operator bool()
const
106 return m_col != m_end;
121 val_type value()
const
128 typedef decltype(std::begin(std::declval<VRng>())) val_iterator;
129 typedef decltype(std::begin(std::declval<CRng>())) col_iterator;
137template <
typename N,
typename PRng,
typename CRng,
typename VRng>
140 typedef std::tuple<N, PRng, CRng, VRng> Matrix;
141 static typename row_iterator<Matrix>::type
142 get(
const Matrix&
matrix,
size_t row)
144 return typename row_iterator<Matrix>::type(
matrix, row);
148template <
typename N,
typename PRng,
typename CRng,
typename VRng>
151 typedef std::tuple<N, PRng, CRng, VRng> Matrix;
153 static size_t get(
const Matrix& A,
size_t row)
155 return std::get<1>(A)[row + 1] - std::get<1>(A)[row];
159template <
typename N,
typename PRng,
typename CRng,
typename VRng>
162 typedef std::tuple<N, PRng, CRng, VRng> Matrix;
163 typedef std::decay_t<decltype(std::declval<PRng>()[0])> ptr_type;
164 typedef const ptr_type* type;
165 static type get(
const Matrix& A)
167 return &std::get<1>(A)[0];
171template <
typename N,
typename PRng,
typename CRng,
typename VRng>
174 typedef std::tuple<N, PRng, CRng, VRng> Matrix;
175 typedef std::decay_t<decltype(std::declval<CRng>()[0])> col_type;
176 typedef const col_type* type;
177 static type get(
const Matrix& A)
179 return &std::get<2>(A)[0];
183template <
typename N,
typename PRng,
typename CRng,
typename VRng>
186 typedef std::tuple<N, PRng, CRng, VRng> Matrix;
187 typedef std::decay_t<decltype(std::declval<VRng>()[0])> val_type;
188 typedef const val_type* type;
189 static type get(
const Matrix& A)
191 return &std::get<3>(A)[0];
203namespace Arcane::Alina::adapter
209template <
class Matrix,
class BlockType>
210struct block_matrix_adapter
212 typedef BlockType value_type;
217 block_matrix_adapter(
const Matrix& A)
221 backend::nbRow(A) % BlockSize == 0 &&
222 backend::nbColumn(A) % BlockSize == 0,
223 "Matrix size is not divisible by block size!");
228 return backend::nbRow(A) / BlockSize;
233 return backend::nbColumn(A) / BlockSize;
236 size_t nonzeros()
const
239 return backend::nonzeros(A) / (BlockSize * BlockSize);
244 typedef typename backend::row_iterator<Matrix>::type Base;
245 typedef ptrdiff_t col_type;
246 typedef BlockType val_type;
248 std::array<char,
sizeof(Base) * BlockSize> buf;
255 row_iterator(
const Matrix& A, col_type row)
258 base =
reinterpret_cast<Base*
>(buf.data());
259 for (
int i = 0; i < BlockSize; ++i) {
260 new (base + i) Base(backend::row_begin(A, row * BlockSize + i));
263 col_type col = base[i].col() / BlockSize;
269 cur_col = std::min<col_type>(cur_col, col);
279 cur_val = math::zero<val_type>();
280 col_type end = (cur_col + 1) * BlockSize;
281 for (
int i = 0; i < BlockSize; ++i) {
282 for (; base[i] &&
static_cast<ptrdiff_t
>(base[i].col()) < end; ++base[i]) {
283 cur_val(i, base[i].col() % BlockSize) = base[i].value();
290 for (
int i = 0; i < BlockSize; ++i)
294 operator bool()
const
299 row_iterator& operator++()
305 col_type end = (cur_col + 1) * BlockSize;
306 for (
int i = 0; i < BlockSize; ++i) {
308 col_type col = base[i].col() / BlockSize;
314 cur_col = std::min<col_type>(cur_col, col);
322 cur_val = math::zero<val_type>();
323 end = (cur_col + 1) * BlockSize;
324 for (
int i = 0; i < BlockSize; ++i) {
325 for (; base[i] &&
static_cast<ptrdiff_t
>(base[i].col()) < end; ++base[i]) {
326 cur_val(i, base[i].col() % BlockSize) = base[i].value();
338 val_type value()
const
354template <
class BlockType,
class Matrix>
355block_matrix_adapter<Matrix, BlockType> block_matrix(
const Matrix& A)
357 return block_matrix_adapter<Matrix, BlockType>(A);
363template <
class Matrix>
364std::shared_ptr<CSRMatrix<
typename math::element_of<
365 typename backend::value_type<Matrix>::type>::type,
366 typename backend::col_type<Matrix>::type,
367 typename backend::ptr_type<Matrix>::type>>
368unblock_matrix(
const Matrix& B)
370 typedef typename backend::value_type<Matrix>::type Block;
371 typedef typename math::element_of<Block>::type Scalar;
372 typedef typename backend::col_type<Matrix>::type Col;
373 typedef typename backend::ptr_type<Matrix>::type Ptr;
375 const int brows = math::static_rows<Block>::value;
376 const int bcols = math::static_cols<Block>::value;
378 static_assert(brows > 1 || bcols > 1,
"Can not unblock scalar matrix!");
380 auto A = std::make_shared<CSRMatrix<Scalar, Col, Ptr>>();
382 A->set_size(backend::nbRow(B) * brows, backend::nbColumn(B) * bcols);
385 const ptrdiff_t nb = backend::nbRow(B);
388 for (ptrdiff_t ib = begin; ib < (begin + size); ++ib) {
389 auto w = backend::row_nonzeros(B, ib);
390 for (ptrdiff_t i = 0, ia = ib * brows; i < brows; ++i, ++ia) {
391 A->ptr[ia + 1] = w * bcols;
400 for (ptrdiff_t ib = begin; ib < (begin + size); ++ib) {
401 for (
auto b = backend::row_begin(B, ib); b; ++b) {
405 for (ptrdiff_t i = 0, ia = ib * brows; i < brows; ++i, ++ia) {
406 auto row_head = A->ptr[ia];
407 for (
int j = 0; j < bcols; ++j) {
408 A->col[row_head] = c * bcols + j;
409 A->val[row_head] = v(i, j);
412 A->ptr[ia] = row_head;
418 std::rotate(A->ptr.data(), A->ptr.data() + A->nbRow(), A->ptr.data() + A->nbRow() + 1);
427template <
class Matrix>
428struct complex_adapter
431 "value type should be complex");
437 complex_adapter(
const Matrix& A)
443 return 2 * backend::nbRow(A);
448 return 2 * backend::nbColumn(A);
451 size_t nonzeros()
const
453 return 4 * backend::nonzeros(A);
458 typedef typename backend::row_iterator<Matrix>::type Base;
459 typedef typename Base::col_type col_type;
461 row_iterator(
const Base& base,
bool row_real)
467 operator bool()
const
469 return static_cast<bool>(base);
472 row_iterator& operator++()
474 col_real = !col_real;
484 return base.col() * 2;
486 return base.col() * 2 + 1;
489 value_type value()
const
493 return std::real(base.value());
495 return -std::imag(base.value());
499 return std::imag(base.value());
501 return std::real(base.value());
514 return row_iterator(backend::row_begin(A, i / 2), i % 2 == 0);
518template <
class Matrix>
519complex_adapter<Matrix> complex_matrix(
const Matrix& A)
521 return complex_adapter<Matrix>(A);
524template <
class DataType,
class Range>
527 DataType* b =
reinterpret_cast<DataType*
>(&rng[0]);
528 size_t s = 2 * std::size(rng);
540template <
class RowBuilder>
543 typedef typename RowBuilder::val_type value_type;
544 typedef typename RowBuilder::col_type col_type;
546 RowBuilder build_row;
548 matrix_builder(
const RowBuilder& row_builder)
549 : build_row(row_builder)
552 size_t rows()
const {
return build_row.rows(); }
553 size_t cols()
const {
return build_row.rows(); }
554 size_t nonzeros()
const {
return build_row.nonzeros(); }
558 typedef RowBuilder::col_type col_type;
559 typedef RowBuilder::val_type val_type;
561 typedef std::vector<col_type>::const_iterator col_iterator;
562 typedef std::vector<val_type>::const_iterator val_iterator;
564 row_iterator(
const RowBuilder& build_row,
size_t i)
567 build_row(i, m_col, m_val);
570 operator bool()
const
572 return m_col.size() - ptr;
575 row_iterator& operator++()
586 val_type value()
const
594 std::vector<col_type> m_col;
595 std::vector<value_type> m_val;
608template <
class RowBuilder>
609matrix_builder<RowBuilder> make_matrix(
const RowBuilder& row_builder)
611 return matrix_builder<RowBuilder>(row_builder);
617template <
class Matrix>
618struct reordered_matrix
620 typedef backend::value_type<Matrix>::type value_type;
621 typedef backend::row_iterator<Matrix>::type base_iterator;
624 const ptrdiff_t* perm;
625 const ptrdiff_t* iperm;
627 reordered_matrix(
const Matrix& A,
const ptrdiff_t* perm,
const ptrdiff_t* iperm)
635 return backend::nbRow(A);
640 return backend::nbColumn(A);
643 size_t nonzeros()
const
645 return backend::nonzeros(A);
651 const ptrdiff_t* iperm;
653 row_iterator(
const base_iterator& base,
const ptrdiff_t* iperm)
658 operator bool()
const
663 row_iterator& operator++()
669 ptrdiff_t col()
const
671 return iperm[base.col()];
674 value_type value()
const
682 return row_iterator(backend::row_begin(A, perm[i]), iperm);
696template <
class BaseIterator>
697class permutation_iterator
701 typedef std::random_access_iterator_tag iterator_category;
702 typedef typename std::iterator_traits<BaseIterator>::value_type value_type;
703 typedef typename std::iterator_traits<BaseIterator>::difference_type difference_type;
704 typedef typename std::iterator_traits<BaseIterator>::reference reference;
705 typedef value_type* pointer;
707 permutation_iterator()
712 permutation_iterator(BaseIterator base,
const ptrdiff_t* perm)
717 reference operator*()
const
719 return m_base[*m_perm];
722 reference operator[](difference_type i)
const
724 return m_base[m_perm[i]];
727 permutation_iterator& operator++()
733 permutation_iterator operator++(
int)
735 permutation_iterator tmp(*
this);
740 permutation_iterator& operator--()
746 permutation_iterator operator--(
int)
748 permutation_iterator tmp(*
this);
753 permutation_iterator& operator+=(difference_type n)
759 permutation_iterator& operator-=(difference_type n)
765 friend permutation_iterator operator+(permutation_iterator it, difference_type n)
771 friend permutation_iterator operator+(difference_type n, permutation_iterator it)
777 friend permutation_iterator operator-(permutation_iterator it, difference_type n)
783 friend difference_type operator-(
const permutation_iterator& a,
const permutation_iterator& b)
785 return a.m_perm - b.m_perm;
788 friend bool operator==(
const permutation_iterator& a,
const permutation_iterator& b)
790 return a.m_perm == b.m_perm;
793 friend bool operator!=(
const permutation_iterator& a,
const permutation_iterator& b)
795 return a.m_perm != b.m_perm;
798 friend bool operator<(
const permutation_iterator& a,
const permutation_iterator& b)
800 return a.m_perm < b.m_perm;
803 friend bool operator<=(
const permutation_iterator& a,
const permutation_iterator& b)
805 return a.m_perm <= b.m_perm;
808 friend bool operator>(
const permutation_iterator& a,
const permutation_iterator& b)
810 return a.m_perm > b.m_perm;
813 friend bool operator>=(
const permutation_iterator& a,
const permutation_iterator& b)
815 return a.m_perm >= b.m_perm;
821 const ptrdiff_t* m_perm;
827template <
class Vector>
828struct reordered_vector
831 typedef std::conditional_t<std::is_const_v<Vector>,
const raw_value_type, raw_value_type> value_type;
834 const ptrdiff_t* perm;
836 reordered_vector(
Vector& x,
const ptrdiff_t* perm)
846 value_type& operator[](
size_t i)
const
879template <
class ordering = CuthillMcKeeReorderer<false>>
884 template <
class Matrix>
885 explicit reorder(
const Matrix& A)
886 : n(backend::nbRow(A))
890 ordering::get(A, perm);
892 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
898 template <
class Matrix>
900 operator()(
const Matrix& A)
const
905 template <
class Vector>
907 operator()(
Vector& x)
const
912 template <
class Vector>
914 operator()(
const Vector& x)
const
919 template <
class Vector1,
class Vector2>
920 void forward(
const Vector1& x,
Vector2& y)
const
923 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
929 template <
class Vector1,
class Vector2>
930 void inverse(
const Vector1& x,
Vector2& y)
const
933 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
948template <
class Matrix,
class Scale>
951 typedef typename backend::value_type<Matrix>::type value_type;
952 typedef typename backend::value_type<Scale>::type scale_type;
957 scaled_matrix(
const Matrix& A,
const Scale& s)
962 size_t rows()
const {
return backend::nbRow(A); }
963 size_t cols()
const {
return backend::nbColumn(A); }
964 size_t nonzeros()
const {
return backend::nonzeros(A); }
968 typedef typename backend::row_iterator<Matrix>::type Base;
973 row_iterator(
const Matrix& A,
const Scale& s,
size_t i)
979 value_type value()
const
981 return si *
static_cast<const Base*
>(
this)->value() * s[this->col()];
994template <
class Backend,
class Scale>
997 typedef typename Backend::params backend_params;
999 const std::shared_ptr<Scale> s;
1000 const backend_params& bprm;
1002 scaled_problem(std::shared_ptr<Scale> s,
const backend_params& bprm = backend_params())
1007 template <
class Matrix>
1013 template <
class Vector>
1014 std::shared_ptr<typename Backend::vector> rhs(
const Vector& v)
const
1016 auto t = Backend::copy_vector(v, bprm);
1021 template <
class Vector>
1022 void operator()(
Vector& x)
const
1024 typedef typename backend::value_type<Vector>::type value_type;
1025 typedef typename math::scalar_of<value_type>::type scalar_type;
1027 const auto one = math::identity<scalar_type>();
1028 const auto zero = math::zero<scalar_type>();
1031 backend::vmul(one, *s, x, zero, x);
1034 backend::vmul(one, *Backend::copy_vector(*s, bprm), x, zero, x);
1042template <
class Backend,
class Matrix>
1046 typename backend::value_type<Matrix>::type>::type>>
1047scale_diagonal(
const Matrix& A,
1048 const typename Backend::params& bprm =
typename Backend::params())
1050 typedef typename backend::value_type<Matrix>::type value_type;
1051 typedef typename math::scalar_of<value_type>::type scalar_type;
1052 ptrdiff_t n = backend::nbRow(A);
1053 auto s = std::make_shared<std::vector<scalar_type>>(n);
1056 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
1057 for (
auto a = backend::row_begin(A, i); a; ++a) {
1059 (*s)[i] = math::inverse(sqrt(math::norm(a.value())));
1072template <
typename Ptr,
typename Col,
typename Val>
1073std::shared_ptr<CSRMatrix<Val>>
1074zero_copy(
size_t nrows,
size_t ncols, Ptr* ptr, Col* col, Val* val)
1077 static_assert(std::is_integral_v<Ptr>,
"Unsupported Ptr type");
1078 static_assert(std::is_integral_v<Col>,
"Unsupported Col type");
1079 static_assert(
sizeof(Ptr) ==
sizeof(
Int32),
"Unsupported Ptr type");
1080 static_assert(
sizeof(Col) ==
sizeof(
Int32),
"Unsupported Col type");
1082 auto A = std::make_shared<CSRMatrix<Val>>();
1085 A->setNbNonZero(nrows ? ptr[nrows] : 0);
1087 A->ptr.setPointerZeroCopy(ptr);
1088 A->col.setPointerZeroCopy(col);
1089 A->val.setPointerZeroCopy(val);
1091 A->own_data =
false;
1099template <
typename Ptr,
typename Col,
typename Val>
1100std::shared_ptr<CSRMatrix<Val>>
1101zero_copy(
size_t n, Ptr* ptr, Col* col, Val* val)
1103 return zero_copy(n, n, ptr, col, val);
1109template <
typename Ptr,
typename Col,
typename Val>
1110std::shared_ptr<CSRMatrix<Val, Col, Ptr>>
1111zero_copy_direct(
size_t nrows,
size_t ncols, Ptr* ptr, Col* col, Val* val)
1113 auto A = std::make_shared<CSRMatrix<Val, Col, Ptr>>();
1116 A->setNbNonZero(nrows ? ptr[nrows] : 0);
1118 A->ptr.setPointerZeroCopy(
const_cast<Ptr*
>(ptr));
1119 A->col.setPointerZeroCopy(
const_cast<Col*
>(col));
1120 A->val.setPointerZeroCopy(
const_cast<Val*
>(val));
1122 A->own_data =
false;
1130template <
typename Ptr,
typename Col,
typename Val>
1131std::shared_ptr<CSRMatrix<Val, Col, Ptr>>
1132zero_copy_direct(
size_t n, Ptr* ptr, Col* col, Val* val)
1134 return zero_copy_direct(n, n, ptr, col, val);
1145namespace Arcane::Alina::backend
1147template <
class Vector>
1153namespace Arcane::Alina::backend::detail
1156template <
class Matrix,
class BlockType>
1161template <
class Matrix>
1166template <
class RowBuilder>
1171template <
typename N,
typename PRng,
typename CRng,
typename VRng>
1176template <
class Matrix>
Itérateur d'accès aléatoire sur une séquence vue à travers une permutation.
NUMA-aware vector container.
Informations d'exécution d'une boucle.
Matrix class, to be used by user.
Vue d'un tableau d'éléments de type T.
Classe gérant un vecteur de dimension 2 de type T.
Vector class, to be used by user.
void arccoreParallelFor(const ComplexForLoopRanges< RankValue, IndexType_ > &loop_ranges, const ForLoopRunInfo &run_info, const LambdaType &lambda_function, const ReducerArgs &... reducer_args)
Applique en concurrence la fonction lambda lambda_function sur l'intervalle d'itération donné par loo...
std::int32_t Int32
Type entier signé sur 32 bits.
Génère les lignes de matrice au besoin à l'aide d'un fonctionnel fourni par l'utilisateur.
Implementation for function returning the number of columns in a matrix.
Implementation for function returning the number of nonzeros in a matrix.
Metafunction that returns pointer type of a matrix.
Implementation for function returning row iterator for a matrix.
Metafunction returning the row iterator type for a matrix type.
Implementation for function returning the number of nonzeros in a matrix row.
Implementation for function returning the number of rows in a matrix.
Metafunction that returns value type of a matrix or a vector type.
Scalar type of a non-scalar type.
Number of rows for statically sized matrix types.