Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MatrixPartitionerRuntime.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/* MatrixPartitionerRuntime.h (C) 2000-2026 */
9/* */
10/* Runtime-configurable wrapper around matrix partitioner. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_MATRIXPARTITIONERRUNTIME_H
13#define ARCCORE_ALINA_MATRIXPARTITIONERRUNTIME_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 <memory>
27
28#include "arccore/alina/AlinaUtils.h"
29#include "arccore/alina/SimpleMatrixPartitioner.h"
30#if defined(ARCCORE_ALINA_HAVE_PARMETIS)
31#include "arccore/alina/ParmetisMatrixPartitioner.h"
32#endif
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane::Alina
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43enum class eMatrixPartitionerType
44{
45 merge
46#ifdef ARCCORE_ALINA_HAVE_PARMETIS
47 ,
48 parmetis
49#endif
50};
51
52inline std::ostream&
53operator<<(std::ostream& os, eMatrixPartitionerType s)
54{
55 switch (s) {
56 case eMatrixPartitionerType::merge:
57 return os << "merge";
58#ifdef ARCCORE_ALINA_HAVE_PARMETIS
59 case eMatrixPartitionerType::parmetis:
60 return os << "parmetis";
61#endif
62 default:
63 return os << "???";
64 }
65}
66
67inline std::istream&
68operator>>(std::istream& in, eMatrixPartitionerType& s)
69{
70 std::string val;
71 in >> val;
72
73 if (val == "merge")
74 s = eMatrixPartitionerType::merge;
75#ifdef ARCCORE_ALINA_HAVE_PARMETIS
76 else if (val == "parmetis")
77 s = eMatrixPartitionerType::parmetis;
78#endif
79 else
80 throw std::invalid_argument("Invalid partitioner value. Valid choices are: "
81 "merge"
82#ifdef ARCCORE_ALINA_HAVE_PARMETIS
83 ", parmetis"
84#endif
85 ".");
86
87 return in;
88}
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
95template <class Backend>
96struct MatrixPartitionerRuntime
97{
98 typedef DistributedMatrix<Backend> matrix;
99 typedef PropertyTree params;
100
101 eMatrixPartitionerType t;
102 void* handle;
103
104 MatrixPartitionerRuntime(params prm = params())
105 : t(prm.get("type",
106#if defined(ARCCORE_ALINA_HAVE_PARMETIS)
107 eMatrixPartitionerType::parmetis
108#else
109 merge
110#endif
111 ))
112 , handle(0)
113 {
114 if (!prm.erase("type"))
115 ARCCORE_ALINA_PARAM_MISSING("type");
116
117 switch (t) {
118 case eMatrixPartitionerType::merge: {
120 handle = static_cast<void*>(new R(prm));
121 } break;
122#ifdef ARCCORE_ALINA_HAVE_PARMETIS
123 case eMatrixPartitionerType::parmetis: {
125 handle = static_cast<void*>(new R(prm));
126 } break;
127#endif
128 default:
129 throw std::invalid_argument("Unsupported partition type");
130 }
131 }
132
133 ~MatrixPartitionerRuntime()
134 {
135 switch (t) {
136 case eMatrixPartitionerType::merge: {
138 delete static_cast<R*>(handle);
139 } break;
140#ifdef ARCCORE_ALINA_HAVE_PARMETIS
141 case eMatrixPartitionerType::parmetis: {
143 delete static_cast<R*>(handle);
144 } break;
145#endif
146 default:
147 break;
148 }
149 }
150
151 bool is_needed(const matrix& A) const
152 {
153 switch (t) {
154 case eMatrixPartitionerType::merge: {
156 return static_cast<const R*>(handle)->is_needed(A);
157 }
158#ifdef ARCCORE_ALINA_HAVE_PARMETIS
159 case eMatrixPartitionerType::parmetis: {
161 return static_cast<const R*>(handle)->is_needed(A);
162 }
163#endif
164 default:
165 throw std::invalid_argument("Unsupported partition type");
166 }
167 }
168
169 std::shared_ptr<matrix> operator()(const matrix& A, unsigned block_size = 1) const
170 {
171 switch (t) {
172 case eMatrixPartitionerType::merge: {
174 return static_cast<const R*>(handle)->operator()(A, block_size);
175 }
176#ifdef ARCCORE_ALINA_HAVE_PARMETIS
177 case eMatrixPartitionerType::parmetis: {
179 return static_cast<const R*>(handle)->operator()(A, block_size);
180 }
181#endif
182 default:
183 throw std::invalid_argument("Unsupported partition type");
184 }
185 }
186};
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191} // namespace Arcane::Alina
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
196#endif
Distributed Matrix using message passing.
Simple matrix partitioner merging consecutive domains together.