Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
LoadBalanceMngInternal.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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.cc (C) 2000-2024 */
9/* */
10/* Classe interne gérant l'équilibre de charge des maillages. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/LoadBalanceMngInternal.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/MultiArray2.h"
19#include "arcane/utils/ITraceMng.h"
20
21#include "arcane/core/IMesh.h"
22#include "arcane/core/IModule.h"
23#include "arcane/core/ItemPrinter.h"
25
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
40: public IProxyItemVariable
41{
42 public:
43
46
48 {
49 return 1;
50 }
51 Integer getPos() const
52 {
53 return 0;
54 }
55
56 protected:
57
58 void deleteMe() {}
59};
60
62static ProxyItemVariableNull nullProxy;
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
71template <typename DataType> class ProxyItemVariable
72: public IProxyItemVariable
73{
74 public:
75
76 explicit ProxyItemVariable(IVariable* var, Integer pos = 0)
77 : m_var(var)
78 , m_pos(pos)
79 {
80 }
82
84 {
85 return static_cast<Real>(m_var[i]);
86 }
87 Integer getPos() const
88 {
89 return m_pos;
90 }
91
92 private:
93
95 Integer m_pos;
96};
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
107{
108 if (!var)
109 return &nullProxy;
110 switch (var->dataType()) {
111 case DT_Real:
112 return new ProxyItemVariable<Real>(var, pos);
113 break;
114 case DT_Int32:
115 return new ProxyItemVariable<Int32>(var, pos);
116 break;
117 default:
118 // TODO : throw an exception
119 return &nullProxy;
120 }
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126CriteriaMng::
127CriteriaMng(bool use_legacy_init)
128: m_nb_cells_as_criterion(!use_legacy_init)
129, m_cell_comm(use_legacy_init)
130, m_need_compute_comm(use_legacy_init)
131, m_criteria(new PartitionerMemoryInfo())
132{
133 resetCriteria();
134};
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142void CriteriaMng::
143init(IMesh* mesh)
144{
145 MeshHandle mesh_handle = mesh->handle();
147
148 m_cell_new_owner = new VariableCellInt32(VariableBuildInfo(mesh_handle, "CellFamilyNewOwner", IVariable::PExecutionDepend | IVariable::PNoDump));
149 m_comm_costs = new VariableFaceReal(VariableBuildInfo(mesh_handle, "LbMngCommCost", vflags));
150 m_mass_over_weight = new VariableCellReal(VariableBuildInfo(mesh_handle, "LbMngOverallMass", vflags));
151 m_mass_res_weight = new VariableCellReal(VariableBuildInfo(mesh_handle, "LbMngResidentMass", vflags));
152 m_event_weights = new VariableCellArrayReal(VariableBuildInfo(mesh_handle, "LbMngMCriteriaWgt", vflags));
153
154 m_comm_costs->fill(1);
155 m_mass_over_weight->fill(1);
156 m_mass_res_weight->fill(1);
157 m_is_init = true;
158 m_mesh = mesh;
159}
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
164void CriteriaMng::
165resetCriteria()
166{
167 m_mass_vars.clear();
168 m_comm_vars.clear();
169 m_event_vars.resize(1); // First slot booked by MemoryOverAll
170
171 clearVariables();
172}
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
176
177void CriteriaMng::
178clearVariables()
179{
180 m_event_weights = nullptr;
181 m_mass_res_weight = nullptr;
182 m_mass_over_weight = nullptr;
183 m_comm_costs = nullptr;
184 m_is_init = false;
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
190Integer CriteriaMng::
191nbCriteria()
192{
193 Integer count;
194
195 count = m_event_vars.size();
196 count -= ((m_use_mass_as_criterion) ? 0 : 1); // First event is mass !
197 count += ((m_nb_cells_as_criterion) ? 1 : 0);
198 return count;
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204ArrayView<StoreIProxyItemVariable> CriteriaMng::
205criteria()
206{
207 if (m_use_mass_as_criterion) {
208 StoreIProxyItemVariable cvar(m_mass_over_weight->variable());
209 m_event_vars[0] = cvar;
210 return m_event_vars;
211 }
212 return m_event_vars.subView(1, m_event_vars.size());
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218void CriteriaMng::
219computeCriteria()
220{
221 if (needComputeComm() || useMassAsCriterion()) { // Memory useful only for communication cost or mass lb criterion
222 m_criteria->computeMemory(m_mesh->variableMng());
223 _computeResidentMass();
224 }
225 if (needComputeComm()) {
226 _computeComm();
227 }
228 if (useMassAsCriterion()) {
229 _computeOverallMass();
230 }
231 _computeEvents();
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
237void CriteriaMng::
238_computeOverallMass()
239{
240 VariableCellReal& mass_over_weigth = *m_mass_over_weight;
241 ENUMERATE_CELL (icell, m_mesh->ownCells()) {
242 mass_over_weigth[icell] = m_criteria->getOverallMemory(*icell);
243 }
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249void CriteriaMng::
250_computeComm()
251{
252 VariableFaceReal& comm_costs = *m_comm_costs;
253
254 Integer penalty = 2; // How many times we do synchronization ?
255
256 if (!m_comm_vars.empty())
257 comm_costs.fill(0);
258
259 for (auto& commvar : m_comm_vars) {
260 ENUMERATE_FACE (iface, m_mesh->ownFaces()) {
261 comm_costs[iface] += commvar[iface] * m_criteria->getResidentMemory(commvar.getPos());
262 }
263 }
264 if (m_cell_comm) {
265 VariableCellReal& mass_res_weight = *m_mass_res_weight;
266 ENUMERATE_CELL (icell, m_mesh->ownCells()) {
267 Real mem = mass_res_weight[icell];
268 for (Face face : icell->faces()) {
269 comm_costs[face] += mem * penalty;
270 }
271 }
272 }
273
274 // Make sure that ghosts contribution is used
275 IVariable* ivar = m_comm_costs->variable();
276 ivar->itemFamily()->reduceFromGhostItems(ivar, Parallel::ReduceSum);
277 m_comm_costs->synchronize();
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283void CriteriaMng::
284_computeResidentMass()
285{
286 VariableCellReal& mass_res_weight = *m_mass_res_weight;
287 ENUMERATE_CELL (icell, m_mesh->ownCells()) {
288 mass_res_weight[icell] = m_criteria->getResidentMemory(*icell);
289 }
290}
291
292/*---------------------------------------------------------------------------*/
293/*---------------------------------------------------------------------------*/
294
295void CriteriaMng::
296_computeEvents()
297{
298 ARCANE_CHECK_POINTER(m_mesh);
299
300 ITraceMng* tm = m_mesh->traceMng();
301 m_event_weights->resize(nbCriteria());
302
303 ArrayView<StoreIProxyItemVariable> event_vars = criteria();
304
305 const Int32 nb_event_var = event_vars.size();
306 const Int32 nb_criteria = nbCriteria();
307
308 tm->info() << "CriteriaMng: Compute Events nb_criteria=" << nb_criteria << " nb_event_var=" << nb_event_var;
309
310 VariableCellArrayReal& event_weights = *(m_event_weights);
311 // Si aucun poids de spécifier et qu'on prend les mailles comme critère, alors
312 // remplit directement les poids (sinon ils ne seront pas remplis)
313 if (nb_event_var == 0 && m_nb_cells_as_criterion) {
314 ENUMERATE_CELL (icell, m_mesh->ownCells()) {
315 event_weights(icell, 0) = 1.0;
316 }
317 }
318 else {
319 for (Integer i = 0; i < event_vars.size(); ++i) {
320 ENUMERATE_CELL (icell, m_mesh->ownCells()) {
321 Integer count = i;
322 if (m_nb_cells_as_criterion) {
323 count += 1;
324 event_weights(icell, 0) = 1;
325 }
326 event_weights(icell, count) = event_vars[i][icell];
327 }
328 }
329 }
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
338LoadBalanceMngInternal::
339LoadBalanceMngInternal(bool mass_as_criterion, bool is_legacy_init)
340: m_default_mass_criterion(mass_as_criterion)
341, m_is_legacy_init(is_legacy_init)
342{}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347CriteriaMng& LoadBalanceMngInternal::
348_getCriteria(IMesh* mesh)
349{
350 auto x = m_mesh_criterion.find(mesh);
351 if (x != m_mesh_criterion.end())
352 return *(x->second.get());
353 auto c = createRef<CriteriaMng>(m_is_legacy_init);
354 auto v = m_mesh_criterion.emplace(mesh, c);
355 x = v.first;
356 return *(x->second.get());
357}
358
359/*---------------------------------------------------------------------------*/
360/*---------------------------------------------------------------------------*/
361
362void LoadBalanceMngInternal::
363reset(IMesh* mesh)
364{
365 _getCriteria(mesh).resetCriteria();
366 if(mesh) {
367 mesh->traceMng()->debug() << "LoadBalanceInternal -- Mesh : " << mesh->name() << " -- reset()";
368 }
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
374void LoadBalanceMngInternal::
375initAccess(IMesh* mesh)
376{
377 if (!mesh)
378 ARCANE_FATAL("Null mesh");
379
380 m_mesh_handle = mesh->handle();
381
382 CriteriaMng& mesh_criterion = _getCriteria(mesh);
383 mesh_criterion.init(mesh);
384 mesh_criterion.defaultMassCriterion(m_default_mass_criterion);
385
386 mesh->traceMng()->info() << "LoadBalanceMngInternal::initAccess():"
387 << " use_memory=" << mesh_criterion.useMassAsCriterion()
388 << " use_nb_cell=" << mesh_criterion.useNbCellsAsCriterion()
389 << " nb_criteria=" << mesh_criterion.nbCriteria();
390
391 // Si aucun critère n'est défini, utilise le nombre de mailles.
392 // Il faut au moins un critère sinon il n'y aura pas de poids dans le graphe de partitionnement.
393 if (mesh_criterion.nbCriteria() == 0)
394 mesh_criterion.setNbCellsAsCriterion(true);
395
396 mesh_criterion.computeCriteria();
397
398 mesh->traceMng()->debug() << "LoadBalanceInternal -- Mesh : " << mesh->name() << " -- initAccess()";
399}
400
401/*---------------------------------------------------------------------------*/
402/*---------------------------------------------------------------------------*/
403
404void LoadBalanceMngInternal::
405endAccess()
406{
407 IMesh* mesh = m_mesh_handle.mesh();
408 if (!mesh)
409 return;
410
411 _getCriteria(mesh).clearVariables();
412
413 mesh->traceMng()->debug() << "LoadBalanceInternal -- Mesh : " << mesh->name() << " -- clearVariables()";
414}
415
416/*---------------------------------------------------------------------------*/
417/*---------------------------------------------------------------------------*/
418
419void LoadBalanceMngInternal::
420addMass(VariableCellInt32& count, IMesh* mesh, const String& entity)
421{
422 CriteriaMng& criterion = _getCriteria(mesh);
423 StoreIProxyItemVariable cvar(count.variable(), criterion.addEntity(entity));
424 criterion.addMass(cvar);
425 mesh->traceMng()->debug() << "Set mass (name=" << count.name() << ") criterion to mesh (name=" << mesh->name() << ")";
426}
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430
431void LoadBalanceMngInternal::
432addCriterion(VariableCellInt32& count, IMesh* mesh)
433{
434 StoreIProxyItemVariable cvar(count.variable());
435 _getCriteria(mesh).addCriterion(cvar);
436 mesh->traceMng()->debug() << "Set criterion (name=" << count.name() << ") criterion to mesh (name=" << mesh->name() << ")";
437}
438
439/*---------------------------------------------------------------------------*/
440/*---------------------------------------------------------------------------*/
441
442void LoadBalanceMngInternal::
443addCriterion(VariableCellReal& count, IMesh* mesh)
444{
445 //std::cerr << "Adding var " << count.variable()->fullName() << " ref # " << count.variable()->nbReference() << std::endl;
446 StoreIProxyItemVariable cvar(count.variable());
447 //std::cerr << "Adding var (2)" << count.variable()->fullName() << " ref # " << count.variable()->nbReference() << std::endl;
448 _getCriteria(mesh).addCriterion(cvar);
449 mesh->traceMng()->debug() << "Set criterion (name=" << count.name() << ") criterion to mesh (name=" << mesh->name() << ")";
450}
451
452/*---------------------------------------------------------------------------*/
453/*---------------------------------------------------------------------------*/
454
455void LoadBalanceMngInternal::
456addCommCost(VariableFaceInt32& count, IMesh* mesh, const String& entity)
457{
458 CriteriaMng& criterion = _getCriteria(mesh);
459 StoreIProxyItemVariable cvar(count.variable(), criterion.addEntity(entity));
460 criterion.addCommCost(cvar);
461 mesh->traceMng()->debug() << "Set CommCost (name=" << count.name() << ") criterion to mesh (name=" << mesh->name() << ")";
462}
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467Integer LoadBalanceMngInternal::
468nbCriteria(IMesh* mesh)
469{
470 return _getCriteria(mesh).nbCriteria();
471}
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
476void LoadBalanceMngInternal::
477setMassAsCriterion(IMesh* mesh, bool active)
478{
479 _getCriteria(mesh).setMassCriterion(active);
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
485void LoadBalanceMngInternal::
486setNbCellsAsCriterion(IMesh* mesh, bool active)
487{
488 _getCriteria(mesh).setNbCellsAsCriterion(active);
489}
490
491/*---------------------------------------------------------------------------*/
492/*---------------------------------------------------------------------------*/
493
494void LoadBalanceMngInternal::
495setCellCommContrib(IMesh* mesh, bool active)
496{
497 _getCriteria(mesh).setCellCommContrib(active);
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503bool LoadBalanceMngInternal::
504cellCommContrib(IMesh* mesh)
505{
506 if(m_mesh_criterion.find(mesh) == m_mesh_criterion.end()){
507 return true;
508 }
509 return _getCriteria(mesh).cellCommContrib();
510}
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
515void LoadBalanceMngInternal::
516setComputeComm(IMesh* mesh, bool active)
517{
518 _getCriteria(mesh).setComputeComm(active);
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
523
524const VariableFaceReal& LoadBalanceMngInternal::
525commCost(IMesh* mesh)
526{
527 return _getCriteria(mesh).commCost();
528}
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
532
533const VariableCellReal& LoadBalanceMngInternal::
534massWeight(IMesh* mesh)
535{
536 return _getCriteria(mesh).massWeight();
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
542const VariableCellReal& LoadBalanceMngInternal::
543massResWeight(IMesh* mesh)
544{
545 return _getCriteria(mesh).massResWeight();
546}
547
548/*---------------------------------------------------------------------------*/
549/*---------------------------------------------------------------------------*/
550
551const VariableCellArrayReal& LoadBalanceMngInternal::
552mCriteriaWeight(IMesh* mesh)
553{
554 return _getCriteria(mesh).criteriaWeight();
555}
556
557/*---------------------------------------------------------------------------*/
558/*---------------------------------------------------------------------------*/
559
560void LoadBalanceMngInternal::
561notifyEndPartition()
562{
563 IMesh* mesh = m_mesh_handle.mesh();
564 _getCriteria(mesh).fillCellNewOwner();
565}
566
567/*---------------------------------------------------------------------------*/
568/*---------------------------------------------------------------------------*/
569
570} // End namespace Arcane
571
572/*---------------------------------------------------------------------------*/
573/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
virtual CellGroup ownCells()=0
Groupe de toutes les mailles propres au domaine.
virtual FaceGroup ownFaces()=0
Groupe de toutes les faces propres au domaine.
virtual IVariableMng * variableMng() const =0
Gestionnaire de variable associé
Interface proxy pour accéder aux variables définissant les poids.
Interface d'une variable.
Definition IVariable.h:54
@ PTemporary
Indique que la variable est temporaire.
Definition IVariable.h:126
@ PExecutionDepend
Indique que la valeur de la variable est dépendante de l'exécution.
Definition IVariable.h:106
@ PNoDump
Indique que la variable ne doit pas être sauvegardée.
Definition IVariable.h:72
Enumérateur sur une liste d'entités.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
IMesh * mesh() const
Maillage associé.
Classe de gestion des critèes de partitionnement.
Implementation "nulle" de l'interface IProxyItemVariable. Permet d'avoir une variable référence unita...
Integer getPos() const
Accès au numéro de la famille associée.
void deleteMe()
Détruit cet objet.
Real operator[](ItemEnumerator) const
Accès à la valeur associée à une entité du maillage, sous forme d'un Real.
Implementation de l'interface IProxyItemVariable.
Integer getPos() const
Accès au numéro de la famille associée.
Real operator[](ItemEnumerator i) const
Accès à la valeur associée à une entité du maillage, sous forme d'un Real.
static IProxyItemVariable * proxyItemVariableFactory(IVariable *var, Integer pos=0)
Factory pour la constructions selon le type de variable initiale.
virtual TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium)=0
Flot pour un message de debug.
ITraceMng * traceMng() const
Gestionnaire de trace.
MeshVariableScalarRefT< Cell, Real > VariableCellReal
Grandeur au centre des mailles de type réel.
MeshVariableScalarRefT< Face, Int32 > VariableFaceInt32
Grandeur aux faces de type entier 32 bits.
MeshVariableScalarRefT< Face, Real > VariableFaceReal
Grandeur aux faces de type réel.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Grandeur au centre des mailles de type entier 32 bits.
MeshVariableArrayRefT< Cell, Real > VariableCellArrayReal
Grandeur au centre des mailles de type tableau de réel.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ DT_Int32
Donnée de type entier 32 bits.
Definition DataTypes.h:43
@ DT_Real
Donnée de type réel.
Definition DataTypes.h:41
Int32 Integer
Type représentant un entier.