Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
LoadBalanceMngInternal.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/* LoadBalanceMngInternal.h (C) 2000-2024 */
9/* */
10/* Internal class managing the load balance of meshes. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_IMPL_INTERNAL_LOADBALANCEMNGINTERNAL_H
13#define ARCANE_IMPL_INTERNAL_LOADBALANCEMNGINTERNAL_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/core/internal/ILoadBalanceMngInternal.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IVariable.h"
21#include "arcane/core/VariableBuildInfo.h"
23#include "arcane/core/IVariableMng.h"
24#include "arcane/core/VariableTypes.h"
25#include "arcane/core/CommonVariables.h"
26#include "arcane/core/VariableCollection.h"
27#include "arcane/core/IItemFamily.h"
28#include "arcane/core/IParallelMng.h"
29
30#include "arcane/utils/ObjectImpl.h"
31#include "arcane/utils/AutoRef.h"
32#include "arcane/utils/ScopedPtr.h"
33#include "arcane/utils/FatalErrorException.h"
34#include "arcane/utils/ArgumentException.h"
35
36#include <unordered_map>
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41namespace Arcane
42{
43
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
56class ARCANE_IMPL_EXPORT IProxyItemVariable
57: public ObjectImpl
58{
59 public:
60
61 virtual ~IProxyItemVariable() {}
62
64 virtual Real operator[](ItemEnumerator i) const = 0;
65
67 virtual Integer getPos() const = 0;
68};
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
79class ARCANE_IMPL_EXPORT StoreIProxyItemVariable
80{
81 public:
82
83 StoreIProxyItemVariable(IVariable* var = nullptr, Integer pos = 0)
84 {
86 }
87
88 StoreIProxyItemVariable(const StoreIProxyItemVariable& src)
89 {
90 if (m_var != src.m_var)
91 m_var = src.m_var;
92 }
93
96 {
97 return ((*m_var)[i]);
98 }
99
101 {
102 /* if (m_var != src.m_var) */
103 m_var = src.m_var;
104 return *this;
105 }
106
107 Integer getPos() const
108 {
109 return m_var->getPos();
110 }
111
112 protected:
113
115 static IProxyItemVariable* proxyItemVariableFactory(IVariable* var, Integer pos = 0);
116
117 private:
118
121};
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
135{
136 public:
137
140 : m_family_names(IK_Unknown + 1, "__special__") // +1 because some variables are associated with IK_Unknown
141 {
142 m_family_names[IK_Cell] = "Cell";
143 m_family_names[IK_Face] = "Face";
144 m_family_names[IK_Edge] = "Edge";
145 m_family_names[IK_Node] = "Node";
146 }
147 ~PartitionerMemoryInfo() = default;
148
150 Integer addEntity(const String& entity)
151 {
152 Integer pos;
153 pos = _findEntity(entity);
154 if (pos < 0) {
155 pos = m_family_names.size();
156 m_family_names.add(entity);
157 }
158 return pos;
159 }
160
161 // Calculates the memory consumption for each entity type.
162 // The cells then benefit from the contributions of other adjacent entities.
163 void computeMemory(IVariableMng* varMng)
164 {
165 Int32 length = m_family_names.size();
166 m_overall_memory.resize(length);
167 m_resident_memory.resize(length);
168 m_buffer.id = -1;
169 m_overall_memory.fill(0);
170 m_resident_memory.fill(0);
171
172 // For each variable, compute the size for one object.
173 for (VariableCollectionEnumerator vc(varMng->usedVariables()); ++vc;) {
174 const IVariable* var = *vc;
175 Integer memory = 0;
176 try {
177 if (var->dataType() != DT_String)
178 memory = dataTypeSize(var->dataType());
179 }
180 catch (const ArgumentException&) {
181 memory = 0; // Cannot know memory used for that ...
182 continue;
183 }
184 Int32 family_index = -1;
185 Integer kind = var->itemKind();
186 if (kind == IK_Particle) { // Not the same counter for all items
187 family_index = _findEntity(var->itemFamilyName());
188 if (family_index >= 0) {
189 m_overall_memory[family_index] += memory;
190 }
191 }
192 m_overall_memory[kind] += memory;
193
194 int properties = var->property();
195 if ((properties & IVariable::PNoExchange) ||
196 (properties & IVariable::PNoNeedSync) ||
197 (properties & IVariable::PTemporary) ||
198 (properties & IVariable::PSubDomainPrivate)) {
199 continue;
200 }
201 m_resident_memory[kind] += memory;
202 if (family_index >= 0) {
203 m_resident_memory[family_index] += memory;
204 }
205 }
206 }
207
209 Real getOverallMemory(const String& entity) const
210 {
211 Integer pos = _findEntity(entity);
212 if (pos >= 0)
213 return getOverallMemory(pos);
214 else
215 return 0;
216 }
217 Real getOverallMemory(Integer offset) const
218 {
219 return m_overall_memory[offset];
220 }
221 Real getOverallMemory(const Cell& cell)
222 {
223 _computeMemCell(cell);
224 return m_buffer.overall_memory;
225 }
226
228 Real getResidentMemory(const String& entity) const
229 {
230 Integer pos = _findEntity(entity);
231 if (pos >= 0)
232 return getResidentMemory(pos);
233 else
234 return 0;
235 }
236 Real getResidentMemory(Integer offset) const
237 {
238 return m_resident_memory[offset];
239 }
240 Real getResidentMemory(const Cell& cell)
241 {
242 _computeMemCell(cell);
243 return m_buffer.resident_memory;
244 }
245
247 Integer operator[](const String& entity) const
248 {
249 return _findEntity(entity);
250 }
251 const String& operator[](unsigned int i) const
252 {
253 return m_family_names[i];
254 }
255
256 private:
257
258 Integer _findEntity(const String& entity) const
259 {
260 for (int i = 0; i < m_family_names.size(); ++i) {
261 if (m_family_names[i] == entity)
262 return i;
263 }
264 return -1;
265 }
266
267 // For cells, we calculate the memory contribution of nodes, edges, and faces.
268 void _computeMemCell(Cell cell)
269 {
270 Real contrib;
271 if (cell.localId() == m_buffer.id) // already computed
272 return;
273 m_buffer.id = cell.localId();
274 m_buffer.overall_memory = m_overall_memory[IK_Cell];
275 m_buffer.resident_memory = m_resident_memory[IK_Cell];
276
277 contrib = _computeMemContrib<Node>(cell.nodes());
278 m_buffer.overall_memory += contrib * m_overall_memory[IK_Node];
279 m_buffer.resident_memory += contrib * m_resident_memory[IK_Node];
280
281 contrib = _computeMemContrib<Face>(cell.faces());
282 m_buffer.overall_memory += contrib * m_overall_memory[IK_Face];
283 m_buffer.resident_memory += contrib * m_resident_memory[IK_Face];
284
285 contrib = _computeMemContrib<Edge>(cell.edges());
286 m_buffer.overall_memory += contrib * m_overall_memory[IK_Edge];
287 m_buffer.resident_memory += contrib * m_resident_memory[IK_Edge];
288 }
289
291 template <typename ItemKind>
293 {
294 Real contrib = 0.0;
295 //ItemEnumeratorT<ItemKind> iterator = list.enumerator();
296 for (const auto& item : list) {
297 contrib += 1.0 / (Real)(item.nbCell());
298 }
299 return contrib;
300 }
301
302 UniqueArray<String> m_family_names;
303 UniqueArray<Int32> m_overall_memory;
304 UniqueArray<Int32> m_resident_memory;
305
307 struct MemInfo
308 {
309 Int32 id = -1;
310 Real overall_memory = 0;
311 Real resident_memory = 0;
312 };
313 MemInfo m_buffer;
314};
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
319class CriteriaMng
320{
321 public:
322
323 CriteriaMng(bool use_legacy_init);
324
325 public:
326
327 void init(IMesh* mesh);
328
329 void defaultMassCriterion(bool mass_criterion)
330 {
331 if (!m_is_edited_mass_criterion)
332 m_use_mass_as_criterion = mass_criterion;
333 }
334
335 void setMassCriterion(bool mass_criterion)
336 {
337 m_is_edited_mass_criterion = true;
338 m_use_mass_as_criterion = mass_criterion;
339 }
340
341 bool useMassAsCriterion() const { return m_use_mass_as_criterion; }
342 bool useNbCellsAsCriterion() const { return m_nb_cells_as_criterion; }
343
344 void resetCriteria();
345 void clearVariables();
346
347 void addCriterion(const StoreIProxyItemVariable& criterion)
348 {
349 m_event_vars.add(criterion);
350 }
351
352 Integer nbCriteria();
354
355 const VariableCellArrayReal& criteriaWeight() const
356 {
357 return *m_event_weights;
358 }
359
360 void addCommCost(const StoreIProxyItemVariable& comm_cost) { m_comm_vars.add(comm_cost); }
361 const VariableCellReal& massResWeight() const { return *m_mass_res_weight; }
362 const VariableCellReal& massWeight() const { return *m_mass_over_weight; }
363
364 void fillCellNewOwner()
365 {
366 if (!m_cell_new_owner.isNull())
367 m_cell_new_owner->fill(m_mesh->parallelMng()->commRank(), m_mesh->ownCells());
368 }
369
370 const VariableFaceReal& commCost() const { return *m_comm_costs; }
371
372 void setComputeComm(bool active) { m_need_compute_comm = active; }
373 bool cellCommContrib() const { return m_cell_comm; }
374 void setCellCommContrib(bool active) { m_cell_comm = active; }
375 void setNbCellsAsCriterion(bool active) { m_nb_cells_as_criterion = active; }
376 void addMass(const StoreIProxyItemVariable& mass) { m_mass_vars.add(mass); }
377 bool needComputeComm() const { return m_need_compute_comm; }
378 bool isInit() const { return m_is_init; }
379 Integer addEntity(const String& entity) { return m_criteria->addEntity(entity); }
380 void computeCriteria();
381
382 private:
383
384 void _computeOverallMass();
385 void _computeComm();
386 void _computeResidentMass();
387 void _computeEvents();
388
389 private:
390
394
395 bool m_use_mass_as_criterion = false;
396 bool m_nb_cells_as_criterion = true;
397 bool m_cell_comm = false;
398 bool m_need_compute_comm = false;
399 bool m_is_edited_mass_criterion = false;
400 bool m_is_init = false;
401
402 ScopedPtrT<VariableFaceReal> m_comm_costs;
403 ScopedPtrT<VariableCellReal> m_mass_over_weight;
404 ScopedPtrT<VariableCellReal> m_mass_res_weight;
405 ScopedPtrT<VariableCellArrayReal> m_event_weights;
406 ScopedPtrT<VariableCellInt32> m_cell_new_owner; // SdC This variable is a problem when using a custom mesh
407
408 IMesh* m_mesh = nullptr;
410};
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
415class ARCANE_IMPL_EXPORT LoadBalanceMngInternal
417{
418 public:
419
420 explicit LoadBalanceMngInternal(bool mass_as_criterion, bool is_legacy_init);
421
422 public:
423
424 void addMass(VariableCellInt32& count, IMesh* mesh, const String& entity) override;
425 void addCriterion(VariableCellInt32& count, IMesh* mesh) override;
426 void addCriterion(VariableCellReal& count, IMesh* mesh) override;
427 void addCommCost(VariableFaceInt32& count, IMesh* mesh, const String& entity) override;
428
429 void setMassAsCriterion(IMesh* mesh, bool active) override;
430 void setNbCellsAsCriterion(IMesh* mesh, bool active) override;
431 void setCellCommContrib(IMesh* mesh, bool active) override;
432 void setComputeComm(IMesh* mesh, bool active) override;
433 const VariableFaceReal& commCost(IMesh* mesh) override;
434 const VariableCellReal& massWeight(IMesh* mesh) override;
435 const VariableCellReal& massResWeight(IMesh* mesh) override;
436 const VariableCellArrayReal& mCriteriaWeight(IMesh* mesh) override;
437
438 bool cellCommContrib(IMesh* mesh) override;
439 Integer nbCriteria(IMesh* mesh) override;
440
441 void reset(IMesh* mesh) override;
442 void initAccess(IMesh* mesh) override;
443 void endAccess() override;
444 void notifyEndPartition() override;
445
446 private:
447
448 MeshHandle m_mesh_handle;
449 bool m_default_mass_criterion = false;
450 bool m_is_legacy_init = false;
451 std::unordered_map<IMesh*, Ref<CriteriaMng>> m_mesh_criterion;
452
453 private:
454
455 CriteriaMng& _getCriteria(IMesh* mesh);
456};
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
461} // End namespace Arcane
462
463/*---------------------------------------------------------------------------*/
464/*---------------------------------------------------------------------------*/
465
466#endif
Types and macros for iterating over mesh entities.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
void fill(ConstReferenceType value)
Fills the array with the value value.
void resize(Int64 s)
Changes the number of elements in the array to s.
Encapsulation of a pointer with a reference counter.
Definition AutoRef.h:43
Internal API of ILoadBalanceMng to Arcane.
Interface proxy to access variables defining weights.
virtual Real operator[](ItemEnumerator i) const =0
Access to the value associated with a mesh entity, in the form of a Real.
virtual Integer getPos() const =0
Access to the associated family number.
Variable manager interface.
virtual VariableCollection usedVariables()=0
List of used variables.
Interface of a variable.
Definition IVariable.h:40
virtual eDataType dataType() const =0
Data type managed by the variable (Real, Integer, ...).
virtual String itemFamilyName() const =0
Name of the associated family (null if none).
@ PNoExchange
Indicates that the variable should not be exchanged.
Definition IVariable.h:130
@ PTemporary
Indicates that the variable is temporary.
Definition IVariable.h:114
@ PSubDomainPrivate
Indicates that the variable is private to the subdomain.
Definition IVariable.h:89
@ PNoNeedSync
Indicates that the variable is not necessarily synchronized.
Definition IVariable.h:70
virtual int property() const =0
Returns the properties of the variable.
virtual eItemKind itemKind() const =0
Kind of mesh entities on which the variable is based.
Enumerator over a list of entities.
Handle on a mesh.
Definition MeshHandle.h:48
Class for managing partitioning criteria.
Integer operator[](const String &entity) const
Management of entities and their names.
PartitionerMemoryInfo()
Construction based on the IVariableMng.
Real _computeMemContrib(ItemConnectedListViewTypeT< ItemKind > list)
Calculates the contribution of an entity to adjacent cells.
Integer addEntity(const String &entity)
Adds an entity and assigns it a number. The same name is not duplicated.
Real getResidentMemory(const String &entity) const
Returns the "resident" (to be transferred) memory associated with an entity.
Real getOverallMemory(const String &entity) const
Returns the total memory associated with an entity.
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
Class for accessing the proxy without dereferencing in the code.
AutoRefT< IProxyItemVariable > m_var
Pointer to the variable.
Real operator[](ItemEnumerator i) const
Access to the value associated with a mesh entity, in the form of a Real.
static IProxyItemVariable * proxyItemVariableFactory(IVariable *var, Integer pos=0)
Factory for construction based on the initial variable type.
1D data vector with value semantics (STL style).
MeshVariableScalarRefT< Face, Real > VariableFaceReal
Real type quantity at face.
MeshVariableScalarRefT< Cell, Real > VariableCellReal
Real type quantity at cell center.
MeshVariableArrayRefT< Cell, Real > VariableCellArrayReal
Quantity at the cell center of real array type.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Quantity at the cell center of 32-bit integer type.
MeshVariableScalarRefT< Face, Int32 > VariableFaceInt32
Quantity at the face of 32-bit integer type.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
ARCANE_DATATYPE_EXPORT Integer dataTypeSize(eDataType type)
Size of data type type (which must be different from DT_String).
Definition DataTypes.cc:111
Int32 Integer
Type representing an integer.
@ IK_Particle
Particle mesh entity.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Unknown
Unknown or uninitialized mesh entity.
@ IK_Face
Face mesh entity.
@ IK_Edge
Edge mesh entity.
double Real
Type representing a real number.
ItemConnectedListViewT< ItemType > ItemConnectedListViewTypeT
Generic list of connected entities.
Definition ItemTypes.h:358
@ DT_String
UTF-8 character string data type.
Definition DataTypes.h:47
@ Cell
The mesh is AMR by cell.
Definition MeshKind.h:53
std::int32_t Int32
Signed integer type of 32 bits.
Cache system for accessing memory related to a cell.