Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcaneLoadBalanceModule.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* ArcaneLoadBalanceModule.cc (C) 2000-2010 */
9/* */
10/* Module d'équilibrage de charge. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/EntryPoint.h"
17#include "arcane/ISubDomain.h"
18#include "arcane/IParallelMng.h"
19#include "arcane/ModuleFactory.h"
20#include "arcane/IMeshPartitioner.h"
21#include "arcane/ServiceUtils.h"
22#include "arcane/CommonVariables.h"
23#include "arcane/ITimeStats.h"
24#include "arcane/ITimeLoopMng.h"
25#include "arcane/ITimeHistoryMng.h"
26#include "arcane/IMesh.h"
27#include "arcane/IMeshModifier.h"
28#include "arcane/ItemPrinter.h"
29#include "arcane/IItemFamily.h"
30
31#include "arcane/std/ArcaneLoadBalance_axl.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36ARCANE_BEGIN_NAMESPACE
37
38#define OLD_LOADBALANCE
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
47{
48 public:
49
52
53 public:
54
55 virtual VersionInfo versionInfo() const { return VersionInfo(1,0,0); }
56
57 public:
58
59 void checkLoadBalance();
60 void loadBalanceInit();
61
62 private:
63
64 VariableScalarReal m_elapsed_computation_time;
69#ifdef OLD_LOADBALANCE
70 Integer m_nb_weight;
71 UniqueArray<float> m_cells_weight;
72#endif // OLD_LOADBALANCE
73
74 private:
75
76 void _checkInit();
77 Real _computeImbalance();
78#ifdef OLD_LOADBALANCE
79 void _computeWeights(RealConstArrayView compute_times,Real max_compute_time);
80#endif // OLD_LOADBALANCE
81};
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86ARCANE_REGISTER_MODULE_ARCANELOADBALANCE(ArcaneLoadBalanceModule);
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91ArcaneLoadBalanceModule::
92ArcaneLoadBalanceModule(const ModuleBuildInfo& mb)
94, m_elapsed_computation_time(VariableBuildInfo(this,"ArcaneLoadBalanceElapsedComputationTime",
95 IVariable::PNoDump|IVariable::PNoRestore))
96, m_computation_time(0.0)
97#ifdef OLD_LOADBALANCE
98 , m_nb_weight(2)
99#endif // OLD_LOADBALANCE
100{
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106ArcaneLoadBalanceModule::
107~ArcaneLoadBalanceModule()
108{
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114void ArcaneLoadBalanceModule::
115loadBalanceInit()
116{
117 m_elapsed_computation_time = 0;
118 _checkInit();
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
124void ArcaneLoadBalanceModule::
125_checkInit()
126{
127 if (options()->period()==0 || !options()->active()){
128 info() << "Load balance deactivated.";
129 return;
130 }
131
132 if (!subDomain()->parallelMng()->isParallel()){
133 info() << "Load balance required but inactive during serial execution";
134 return;
135 }
136
137 info() << "Load balance active with maximum unbalance: "
138 << options()->maxImbalance();
139 // Indique au maillage qu'il peut évoluer
140 defaultMesh()->modifier()->setDynamic(true);
141}
142
143/*---------------------------------------------------------------------------*/
144/*---------------------------------------------------------------------------*/
145
148{
150 Integer global_iteration = sd->commonVariables().globalIteration();
151 int period = options()->period();
152 if (period==0)
153 return;
154 if (global_iteration==0)
155 return;
156 if ((global_iteration % period) != 0)
157 return;
158
159 Real imbalance = _computeImbalance();
160
161 if (!options()->active())
162 return;
163 if (imbalance<options()->maxImbalance())
164 return;
165 Real min_cpu_time = options()->minCpuTime();
167 return;
168
170 info() << "Programme un repartitionnement du maillage";
171#ifdef OLD_LOADBALANCE
172 IMeshPartitioner* p = options()->partitioner();
173 _computeWeights(p->computationTimes(),p->maximumComputationTime());
174 p->setCellsWeight(m_cells_weight,m_nb_weight);
175#endif // OLD_LOADBALANCE
176 subDomain()->timeLoopMng()->registerActionMeshPartition(options()->partitioner());
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181#ifdef OLD_LOADBALANCE
187{
189 IMesh* mesh = this->mesh();
190 IParallelMng* pm = sd->parallelMng();
191 Int32 nb_sub_domain = pm->commSize();
192 CellGroup own_cells = mesh->ownCells();
194 Integer nb_own_cell = own_cells.size();
195 Integer nb_weight = m_nb_weight;
196
198 //Integer total_nb_cell = 0;
199
200 // compute_times[0] contient le temps global (sans tracking)
201 // compute_times[1] contient le temps de tracking
202 //Real max_compute_time = maximumComputationTime();
203 //RealConstArrayView compute_times = computationTimes();
204 bool has_compute_time = compute_times.size()!=0;
205 bool has_cell_time = compute_times.size()==2;
207 max_compute_time = 1.0;
208 Real compute_times0 = 1.0;
209 Real compute_times1 = 0.0;
210 if (has_compute_time){
212 if (has_cell_time)
214 }
215
216 bool dump_info = true;
217
220
221 if (dump_info){
222 info() << " MAX_COMPUTE=" << max_compute_time;
223 info() << " COMPUTE 0=" << compute_times0;
224 info() << " COMPUTE 1=" << compute_times1;
225 info() << " TIME RATIO 0=" << time_ratio;
226 info() << " TIME RATIO 2=" << time_ratio2;
227 }
229
230 if (dump_info){
231 info() << " PROPORTIONAL TIME=" << proportional_time;
232 }
233
234 Real max_weight = 0.0;
236 m_cells_weight.resize(cell_family->maxLocalId()*nb_weight);
238 const Cell& cell = *iitem;
239 Real v0 = proportional_time;
240 Real w = (v0);
241 if (dump_info && iitem.index()<10){
242 info() << "Weight " << ItemPrinter(cell)
243 << " v0=" << v0
244 << " w=" << w;
245 }
246 // Pour test si on a un deuxieme poids, le multiplie par i+1;
247 for( Integer i=0; i<nb_weight; ++i ){
248 m_cells_weight[(nb_weight*iitem->localId())+i] = (float)(w*((Real)(i+1)));
249 }
250 if (w>max_weight)
251 max_weight = w;
252 }
253
254 Real total_max_weight = pm->reduce(Parallel::ReduceMax,max_weight);
256 total_max_weight = 1.0;
257
258 if (dump_info){
259 info() << " TOTAL MAX WEIGHT=" << total_max_weight;
260 }
261
263 for( Integer i=0; i<nb_weight; ++i ){
264 Integer idx = (nb_weight*iitem->localId())+i;
265 m_cells_weight[idx] = (float)(m_cells_weight[idx] / total_max_weight);
266 }
267 }
268}
269#endif // OLD_LOADBALANCE
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
274Real ArcaneLoadBalanceModule::
275_computeImbalance()
276{
277 //TODO: rendre la méthode compatible avec le retour-arrière
280
281 // Temps écoulé depuis le début de l'exécution
282 Real elapsed_computation_time = time_stats->elapsedTime(TP_Computation);
283 Real computation_time = elapsed_computation_time - m_elapsed_computation_time();
284
285 m_elapsed_computation_time = elapsed_computation_time;
286
287 if (options()->statistics()){
288 // Optionnel:
289 // Récupère le temps de calcul de chaque sous-domaine pour en sortir
290 // les historiques.
291 // TODO: dans ce cas, le reduce standard pour le min et le max est
292 // inutilise -> le supprimer
293 Integer nb_sub_domain = pm->commSize();
299 thm->addValue("SubDomainComputeTime",compute_times);
300 }
301
302 Real reduce_times[2];
303 reduce_times[0] = computation_time;
304 reduce_times[1] = -computation_time;
305 // Tous les replicats doivent avoir les mêmes infos de temps pour tous lancer
306 // le repartitionnement (même si au final un seul réplica fait le repartionnement,
307 // l'opération de demande doit être collective)
308 subDomain()->allReplicaParallelMng()->reduce(Parallel::ReduceMin,RealArrayView(2,reduce_times));
309 Real min_computation_time = reduce_times[0];
310 Real max_computation_time = -reduce_times[1];
311 if (math::isZero(max_computation_time))
312 max_computation_time = 1.;
313 if (math::isZero(min_computation_time))
314 min_computation_time = 1.;
315 RealUniqueArray computation_times(1);
316 computation_times[0] = computation_time;
317
318 m_computation_time += max_computation_time;
319
320 Real ratio = computation_time / max_computation_time;
321 Real imbalance = (max_computation_time - min_computation_time) / min_computation_time;
322 info() << "Computing time used (" << pm->commRank() << ") :"
323 << " nb_owncell=" << ownCells().size()
324 << " current=" << computation_time
325 << " min=" << min_computation_time
326 << " max=" << max_computation_time
327 << " ratio=" << ratio
328 << " imbalance=" << imbalance
329 << " full-compute=" << m_computation_time;
330
331 IMeshPartitioner* p = options()->partitioner();
332 p->setMaximumComputationTime(max_computation_time);
333 p->setComputationTimes(computation_times);
334 p->setImbalance(imbalance);
335 p->setMaxImbalance(options()->maxImbalance());
336 return imbalance;
337}
338
339/*---------------------------------------------------------------------------*/
340/*---------------------------------------------------------------------------*/
341
342ARCANE_END_NAMESPACE
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
ISubDomain * subDomain() const override
Sous-domaine associé au module.
IMesh * defaultMesh() const override
Maillage par défaut pour ce module.
IParallelMng * parallelMng() const override
Gestionnaire du parallélisme par échange de message.
Generation de la classe de base du Module.
CaseOptionsArcaneLoadBalance * options() const
Options du jeu de données du module.
Module d'équilibrage de charge.
void _computeWeights(RealConstArrayView compute_times, Real max_compute_time)
Calcule le poids de chaque maille et le range dans m_cells_weight.
Real m_computation_time
Temps de calcul depuis le dernier équilibrage Note: cette valeur doit être synchronisée.
virtual VersionInfo versionInfo() const
Version du module.
Maille d'un maillage.
Definition Item.h:1178
Interface d'une famille d'entités.
virtual CellGroup ownCells()=0
Groupe de toutes les mailles propres au domaine.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Interface d'un partitionneur de maillage.
virtual IMeshModifier * modifier()=0
Interface de modification associée.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Effectue un regroupement sur tous les processeurs. Il s'agit d'une opération collective....
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
virtual ITimeStats * timeStats() const =0
Statistiques des temps d'exécution.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual ITimeLoopMng * timeLoopMng()=0
Retourne le gestionnaire de la boucle en temps.
virtual ITimeHistoryMng * timeHistoryMng()=0
Retourne le gestionnaire d'historique.
virtual IParallelMng * allReplicaParallelMng() const =0
Retourne le gestionnaire de parallélisme pour tous les réplicats.
Classe gérant un historique de valeurs.
Interface gérant les statistiques sur les temps d'exécution.
Definition ITimeStats.h:48
Interface d'une variable.
Definition IVariable.h:54
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
CellGroup ownCells() const
Retourne le groupe contenant toutes les mailles propres à ce domaine.
Informations pour construire un module.
Paramètres nécessaires à la construction d'une variable.
Informations sur une version.
Definition VersionInfo.h:46
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
bool isZero(const BuiltInProxy< _Type > &a)
Teste si une valeur est exactement égale à zéro.
UniqueArray< Real > RealUniqueArray
Tableau dynamique à une dimension de réels.
Definition UtilsTypes.h:521
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:644
ArrayView< Real > RealArrayView
Equivalent C d'un tableau à une dimension de réels.
Definition UtilsTypes.h:617