Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
BackendInterface.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* BackendInterface.h (C) 2000-2026 */
9/* */
10/* Backend interface required for AMG. . */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_BACKENDINTERFACE_H
13#define ARCCORE_ALINA_BACKENDINTERFACE_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include <cmath>
27
28#include <type_traits>
29
30#include "arccore/alina/ValueTypeInterface.h"
31#include "arccore/alina/AlinaUtils.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Alina::backend
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
53
60
65
71template <class SBackend, class PBackend>
72struct backends_compatible : std::is_same<SBackend, PBackend>
73{};
74
76template <class T, class Enable = void>
78{
79 typedef typename T::value_type type;
80};
81
83template <class T, class Enable = void>
85{
86 typedef typename T::col_type type;
87};
88
90template <class T, class Enable = void>
92{
93 typedef typename T::ptr_type type;
94};
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
103template <class Matrix, class Enable = void>
105{
106 static size_t get(const Matrix& A)
107 {
108 return A.rows();
109 }
110};
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
118template <class Matrix, class Enable = void>
120{
121 static size_t get(const Matrix& A)
122 {
123 return A.cols();
124 }
125};
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
134template <class T, class Enable = void>
136{
137
138 // Use bytes() method when available.
139 template <class U>
140 static auto get_impl(const U& t, int) -> decltype(t.bytes())
141 {
142 return t.bytes();
143 }
144
145 // Fallback to zero.
146 template <class U>
147 static size_t get_impl(const U&, ...)
148 {
149 return 0;
150 }
151
152 static size_t get(const T& t)
153 {
154 return get_impl(t, 0);
155 }
156};
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161template <class Matrix, class Enable = void>
163{
164 typedef typename Matrix::PTR_DATA_NOT_IMPLEMENTED type;
165};
166
167template <class Matrix, class Enable = void>
169{
170 typedef typename Matrix::COL_DATA_NOT_IMPLEMENTED type;
171};
172
173template <class Matrix, class Enable = void>
175{
176 typedef typename Matrix::VAL_DATA_NOT_IMPLEMENTED type;
177};
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
186template <class Matrix, class Enable = void>
188{
189 static size_t get(const Matrix& A)
190 {
191 return A.nonzeros();
192 }
193};
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
202template <class Matrix, class Enable = void>
204{
205 typedef typename Matrix::ROW_NONZEROS_NOT_IMPLEMENTED type;
206};
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
216template <class Matrix, class Enable = void>
218{
219 typedef typename Matrix::row_iterator type;
220};
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
231template <class Matrix, class Enable = void>
233{
234 static typename row_iterator<Matrix>::type
235 get(const Matrix& A, size_t row)
236 {
237 return A.row_begin(row);
238 }
239};
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
248template <class Alpha, class Matrix, class Vector1, class Beta, class Vector2, class Enable = void>
250{
251 typedef typename Matrix::SPMV_NOT_IMPLEMENTED type;
252};
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
261template <class Matrix, class Vector1, class Vector2, class Vector3, class Enable = void>
263{
264 typedef typename Matrix::RESIDUAL_NOT_IMPLEMENTED type;
265};
266
272template <class Vector, class Enable = void>
274{
275 typedef typename Vector::CLEAR_NOT_IMPLEMENTED type;
276};
277
283template <class Vector1, class Vector2, class Enable = void>
285{
286 typedef typename Vector1::COPY_NOT_IMPLEMENTED type;
287};
288
294template <class Vector1, class Vector2, class Enable = void>
296{
297 typedef typename Vector1::INNER_PRODUCT_NOT_IMPLEMENTED type;
298};
299
305template <class A, class Vector1, class B, class Vector2, class Enable = void>
307{
308 typedef typename Vector1::AXPBY_NOT_IMPLEMENTED type;
309};
310
316template <class A, class Vector1, class B, class Vector2, class C, class Vector3, class Enable = void>
318{
319 typedef typename Vector1::AXPBYPCZ_NOT_IMPLEMENTED type;
320};
321
327template <class Alpha, class Vector1, class Vector2, class Beta, class Vector3, class Enable = void>
329{
330 typedef typename Vector1::VMUL_NOT_IMPLEMENTED type;
331};
332
336template <class MatrixValue, class Vector, bool IsConst, class Enable = void>
338{
339 typedef typename MatrixValue::REINTERPRET_AS_RHS_NOT_IMPLEMENTED type;
340};
341
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
348template <class Matrix>
349size_t nbRow(const Matrix& matrix)
350{
351 return rows_impl<Matrix>::get(matrix);
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
358template <class Matrix>
359size_t nbColumn(const Matrix& matrix)
360{
361 return cols_impl<Matrix>::get(matrix);
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
368template <class T>
369size_t bytes(const T& t)
370{
371 return bytes_impl<T>::get(t);
372}
373
374/*---------------------------------------------------------------------------*/
375/*---------------------------------------------------------------------------*/
376
377template <class Matrix>
378typename ptr_data_impl<Matrix>::type
379ptr_data(const Matrix& matrix)
380{
381 return ptr_data_impl<Matrix>::get(matrix);
382}
383
384template <class Matrix>
385typename col_data_impl<Matrix>::type
386col_data(const Matrix& matrix)
387{
388 return col_data_impl<Matrix>::get(matrix);
389}
390
391template <class Matrix>
392typename val_data_impl<Matrix>::type
393val_data(const Matrix& matrix)
394{
395 return val_data_impl<Matrix>::get(matrix);
396}
397
399template <class Matrix>
400size_t nonzeros(const Matrix& matrix)
401{
402 return nonzeros_impl<Matrix>::get(matrix);
403}
404
406template <class Matrix>
407typename row_iterator<Matrix>::type
408row_begin(const Matrix& matrix, size_t row)
409{
410 return row_begin_impl<Matrix>::get(matrix, row);
411}
412
414template <class Matrix>
415size_t row_nonzeros(const Matrix& A, size_t row)
416{
417 return row_nonzeros_impl<Matrix>::get(A, row);
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
427template <class Alpha, class Matrix, class Vector1, class Beta, class Vector2>
428void spmv(Alpha alpha, const Matrix& A, const Vector1& x,
429 Beta beta, Vector2& y)
430{
431 ARCCORE_ALINA_TIC("spmv");
433 ARCCORE_ALINA_TOC("spmv");
434}
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
443template <class Matrix, class Vector1, class Vector2, class Vector3>
444void residual(const Vector1& rhs, const Matrix& A, const Vector2& x, Vector3& r)
445{
446 ARCCORE_ALINA_TIC("residual");
448 ARCCORE_ALINA_TOC("residual");
449}
450
451/*---------------------------------------------------------------------------*/
452/*---------------------------------------------------------------------------*/
454template <class Vector>
455void clear(Vector& x)
456{
457 ARCCORE_ALINA_TIC("clear");
459 ARCCORE_ALINA_TOC("clear");
460}
461
462/*---------------------------------------------------------------------------*/
463/*---------------------------------------------------------------------------*/
464
466template <class Vector1, class Vector2>
467void copy(const Vector1& x, Vector2& y)
468{
469 ARCCORE_ALINA_TIC("copy");
471 ARCCORE_ALINA_TOC("copy");
472}
473
474/*---------------------------------------------------------------------------*/
475/*---------------------------------------------------------------------------*/
476
478template <class Vector1, class Vector2>
479typename math::inner_product_impl<typename value_type<Vector1>::type>::return_type
480inner_product(const Vector1& x, const Vector2& y)
481{
482 typedef typename math::inner_product_impl<
483 typename value_type<Vector1>::type>::return_type result_type;
484
485 ARCCORE_ALINA_TIC("inner_product");
486 result_type p = inner_product_impl<Vector1, Vector2>::get(x, y);
487 ARCCORE_ALINA_TOC("inner_product");
488
489 return p;
490}
491
492/*---------------------------------------------------------------------------*/
493/*---------------------------------------------------------------------------*/
498template <class A, class Vector1, class B, class Vector2>
499void axpby(A a, Vector1 const& x, B b, Vector2& y)
500{
501 ARCCORE_ALINA_TIC("axpby");
503 ARCCORE_ALINA_TOC("axpby");
504}
505
506/*---------------------------------------------------------------------------*/
507/*---------------------------------------------------------------------------*/
513template <class A, class Vector1, class B, class Vector2, class C, class Vector3>
514void axpbypcz(A a, Vector1 const& x, B b, Vector2 const& y, C c, Vector3& z)
515{
516 ARCCORE_ALINA_TIC("axpbypcz");
518 ARCCORE_ALINA_TOC("axpbypcz");
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
528template <class Alpha, class Vector1, class Vector2, class Beta, class Vector3>
529void vmul(Alpha alpha, const Vector1& x, const Vector2& y, Beta beta, Vector3& z)
530{
531 ARCCORE_ALINA_TIC("vmul");
533 ARCCORE_ALINA_TOC("vmul");
534}
535
536/*---------------------------------------------------------------------------*/
537/*---------------------------------------------------------------------------*/
538
540template <class MatrixValue, class Vector>
541typename reinterpret_as_rhs_impl<MatrixValue,
542 typename std::decay<Vector>::type,
543 std::is_const<typename std::remove_reference<Vector>::type>::value>::return_type
544reinterpret_as_rhs(Vector&& x)
545{
546 return reinterpret_as_rhs_impl<MatrixValue,
547 typename std::decay<Vector>::type,
548 std::is_const<typename std::remove_reference<Vector>::type>::value>::get(std::forward<Vector>(x));
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
555template <class Backend, template <class> class Relaxation, class Enable = void>
556struct relaxation_is_supported : std::true_type
557{};
558
560template <class Backend, template <class> class Coarsening, class Enable = void>
561struct coarsening_is_supported : std::true_type
562{};
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
571template <class Coefs, class Vecs, class Coef, class Vec>
572void lin_comb(size_t n, const Coefs& c, const Vecs& v, const Coef& alpha, Vec& y)
573{
574 axpby(c[0], *v[0], alpha, y);
575 size_t i = 1;
576 for (; i + 1 < n; i += 2)
577 axpbypcz(c[i], *v[i], c[i + 1], *v[i + 1], math::identity<Coef>(), y);
578
579 for (; i < n; ++i)
580 axpby(c[i], *v[i], math::identity<Coef>(), y);
581}
582
583/*---------------------------------------------------------------------------*/
584/*---------------------------------------------------------------------------*/
585
586} // namespace Arcane::Alina::backend
587
588namespace Arcane::Alina::detail
589{
590
591// Backend with scalar value_type of highest precision.
592template <class B>
593struct common_scalar_backend<B, B, typename std::enable_if<math::static_rows<typename B::value_type>::value == 1>::type>
594{
595 typedef B type;
596};
597
598}
599
600/*---------------------------------------------------------------------------*/
601/*---------------------------------------------------------------------------*/
602
603#endif
Matrix class, to be used by user.
Implementation for linear combination of two vectors.
Implementation for linear combination of three vectors.
Metafunction that checks if two backends are compatible.
Implementation for function returning number of bytes allocated for a matrix/vector.
Implementation for zeroing out a vector.
Is the coarsening supported by the backend?
Metafunction that returns column type of a matrix.
Implementation for function returning the number of columns in a matrix.
Implementation for vector copy.
Implementation for inner product.
Implementation for function returning the number of nonzeros in a matrix.
Metafunction that returns pointer type of a matrix.
Reinterpret the vector to be compatible with the matrix value type.
Is the relaxation supported by the backend?
Implementation for residual error compuatation.
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.
Implementation for matrix-vector product.
Metafunction that returns value type of a matrix or a vector type.
Implementation for element-wize vector product.