Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
ModuleMaster.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/* ModuleMaster.cc (C) 2000-2015 */
9/* */
10/* Module maître. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/Iterator.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/Array.h"
19#include "arcane/utils/Enumerator.h"
20#include "arcane/utils/Collection.h"
21#include "arcane/utils/IOnlineDebuggerService.h"
22
23#include "arcane/ModuleMaster.h"
24#include "arcane/EntryPoint.h"
25#include "arcane/CaseOptionsMain.h"
26#include "arcane/ITimeHistoryMng.h"
27#include "arcane/IVariableMng.h"
28#include "arcane/ISubDomain.h"
29#include "arcane/IApplication.h"
30#include "arcane/IModuleMng.h"
31#include "arcane/ITimeLoopMng.h"
32#include "arcane/IParallelMng.h"
33#include "arcane/ICaseMng.h"
34#include "arcane/IModuleMng.h"
35#include "arcane/ModuleBuildInfo.h"
36#include "arcane/ITimeLoopService.h"
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41ARCANE_BEGIN_NAMESPACE
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46extern "C++" ARCANE_CORE_EXPORT IModuleMaster*
47arcaneCreateModuleMaster(ISubDomain* sd)
48{
49 ModuleBuildInfo mbi(sd,sd->defaultMeshHandle(),"ArcaneMasterInternal");
50 ModuleMaster* m = new ModuleMaster(mbi);
51 return m;
52}
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57ModuleMaster::
58ModuleMaster(const ModuleBuildInfo& mb)
60, CommonVariables(this)
61, m_case_options_main(0)
62, m_nb_loop(0)
63, m_old_cpu_time(0.0)
64, m_old_elapsed_time(0.0)
65, m_is_first_loop(true)
66, m_thm_mem_used(0.0)
67, m_thm_diff_cpu(0.0)
68, m_thm_global_cpu_time(0.0)
69, m_thm_diff_elapsed(0.0)
70, m_thm_global_elapsed_time(0.0)
71, m_thm_global_time(0.0)
72, m_has_thm_dump_at_iteration(false)
73{
75
76 addEntryPoint(this,"ArcaneTimeLoopBegin",
79 addEntryPoint(this,"ArcaneTimeLoopEnd",
82 addEntryPoint(this,"ArcaneMasterStartInit",
85 addEntryPoint(this,"ArcaneMasterInit",
88 addEntryPoint(this,"ArcaneMasterContinueInit",
92 addEntryPoint(this,"ArcaneMasterLoopExit",
93 &ModuleMaster::_masterLoopExit,
94 IEntryPoint::WExit,
96 addEntryPoint(this,"ArcaneMasterLoopMeshChanged",
97 &ModuleMaster::_masterMeshChanged,
100 addEntryPoint(this,"ArcaneMasterLoopRestore",
101 &ModuleMaster::_masterRestore,
104}
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
114
115/*---------------------------------------------------------------------------*/
116/*---------------------------------------------------------------------------*/
117
120{
122 m_global_time = 0.0;
125 m_global_cpu_time = 0.0;
129
130 // Met a jour les options du jeu de données qui dépendent d'une table de marche.
131 ICaseMng* com = subDomain()->caseMng();
132 com->updateOptions(0.0,0.0,0);
133
134 _masterStartInit();
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
142{
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
150{
151 // En reprise, l'initialisation est considérée comme ayant lieu avant
152 // la prochaine itération, donc avec les anciennes valeurs du pas de temps
153 // et du temps de la simulation.
154
155 ICaseMng* com = subDomain()->caseMng();
156 Int32 opt_iteration = m_global_iteration() - 1;
157 info() << "Initialization to restore the functions of the input data: "
158 << " time=" << m_global_old_time()
159 << " dt=" << m_global_old_deltat()
160 << " iteration=" << opt_iteration;
162
163 _masterContinueInit();
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
180{
181 Integer precision = FloatInfo<Real>::maxDigit();
182 Integer digit = FloatInfo<Real>::maxDigit()+5;
183
184 info()<<" ";
185 info(0) << "***"
186 << " ITERATION " << Trace::Width(8) << m_global_iteration()
187 << " TIME " << Trace::Width(digit) << Trace::Precision(precision,m_global_time(),true)
188 << " LOOP " << Trace::Width(8) << m_nb_loop
189 << " DELTAT " << Trace::Width(digit) << Trace::Precision(precision,m_global_deltat(),true)
190 << " ***";
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
196
199{
200 // Première boucle, initialise le temps et affiche les infos
201 // sur la consommation
202 if (m_is_first_loop){
203 info() << "Information on consumption (unit:second): Con(R=...,I=...,C=...)";
204 info() << " R -> consumption in real time (clock) since the beginning of the computation";
205 info() << " I -> real time (clock) spent during the last iteration";
206 info() << " C -> consumption in CPU time since the beginning of the computation";
207 info() << "Information on memory consumption (unit: Mo): Mem=(X,m=X1:R1,M=X2:R2,avg=Z)";
208 info() << " X -> memory consumption of the process";
209 info() << " X1 -> memory consumption of the least memory hungry process and R1 is its rank";
210 info() << " X2 -> memory consumption of the most memory hungry process and R2 is its rank";
211 info() << " Z -> average memory consumption of all process";
212 }
213
214 ++m_nb_loop;
215
216 // Met a jour les options du jeu de données qui dépendent d'une table de marche.
217 ICaseMng* com = subDomain()->caseMng();
219
220 Real mem_used = platform::getMemoryUsed();
221
223
225
226 // Infos pour les courbes
227 m_thm_mem_used = mem_used;
228
229 // Ajoute le deltat au temps courant
230 //info() << "[ModuleMaster::timeLoopBegin] Add deltat to the current time";
232
233 m_thm_global_time = m_global_time();
234 //thm->addValue(m_global_time.name(),m_global_time());
235
236 //info() << "[ModuleMaster::timeLoopBegin] breakpoint_requested?";
238
239 // Il faut absolument que cette valeur soit la même pour tous les sous-domaines
240 Real cpu_time = (Real)platform::getCPUTime();
241 Real elapsed_time = platform::getRealTime();
242 {
243 Real values[3];
244 ArrayView<Real> vals(3,values);
245 values[0] = cpu_time;
246 values[1] = elapsed_time;
247 values[2] = (hyoda)?hyoda->loopbreak(subDomain()):0.0;
248 subDomain()->allReplicaParallelMng()->reduce(Parallel::ReduceMax,vals);
249 cpu_time = values[0];
250 elapsed_time = values[1];
251 if (hyoda && values[2]>0.0)
252 hyoda->hook(subDomain(),values[2]);
253 }
254 if (m_is_first_loop){
255 m_old_cpu_time = cpu_time;
256 m_old_elapsed_time = elapsed_time;
257 }
258 Real diff_cpu = (cpu_time - m_old_cpu_time) / CLOCKS_PER_SEC;
259 Real diff_elapsed = (elapsed_time - m_old_elapsed_time);
260 m_global_old_cpu_time = diff_cpu;
261 m_global_old_elapsed_time = diff_elapsed;
264
265 m_thm_diff_cpu = diff_cpu;
266 m_thm_global_cpu_time = m_global_cpu_time();
267 m_thm_diff_elapsed = diff_elapsed;
268 m_thm_global_elapsed_time = m_global_elapsed_time();
269
270 m_old_cpu_time = cpu_time;
271 m_old_elapsed_time = elapsed_time;
272
274
275 Real mem_sum = 0.0;
276 Real mem_min = 0.0;
277 Real mem_max = 0.0;
278 Int32 mem_min_rank = 0;
279 Int32 mem_max_rank = 0;
280 pm->computeMinMaxSum(mem_used,mem_min,mem_max,mem_sum,mem_min_rank,mem_max_rank);
281 // Tronque à la milli-seconde
282 Int64 i_elapsed = (Int64)(m_global_elapsed_time() * 1000.0);
283 Int64 i_diff_elapsed = (Int64)(diff_elapsed * 1000.0);
284 Int64 i_cpu = (Int64)(m_global_cpu_time() * 1000.0);
285 info(1) << "Date: " << platform::getCurrentDateTime()
286 << " Conso=(R=" << (((Real)i_elapsed) / 1000.0)
287 << ",I=" << (((Real)i_diff_elapsed) / 1000.0)
288 << ",C=" << ((Real)i_cpu / 1000.0)
289 << ") Mem=(" << (Int64)(mem_used/1e6)
290 << ",m=" << (Int64)(mem_min/1e6)
291 << ":" << mem_min_rank
292 << ",M=" << (Int64)(mem_max/1e6)
293 << ":" << mem_max_rank
294 << ",avg=" << (Int64)(mem_sum/1e6) / pm->commSize()
295 << ")";
296
297 _masterBeginLoop();
298 m_is_first_loop = false;
299 m_has_thm_dump_at_iteration = false;
300}
301
302/*---------------------------------------------------------------------------*/
303/*---------------------------------------------------------------------------*/
304
307{
308 _masterEndLoop();
309
310 // Effectue les sorties courbes
311 // Comme il est possible de désactiver les sorties courbes
312 // à une itération donnée, il faut faire les sorties en fin d'itération
313 // et non pas au début pour permettre aux autres modules d'activer ou non
314 // les sorties. Il est aussi possible pour un code utilisateur d'appeler
315 // explicitement cette méthode pour qu'il fasse les sorties quand il le
316 // souhaite au cours de l'itération.
318
319 // Incrémente le compteur d'itération
321
322 if (subDomain()->timeLoopMng()->finalTimeReached()){
323 info() <<"===============================================================";
324 info() <<"====== END OF COMPUTATION REACHED... =======================";
325 info() <<"===============================================================";
326 }
327}
328
329/*---------------------------------------------------------------------------*/
330/*---------------------------------------------------------------------------*/
331
334{
335 if (m_has_thm_dump_at_iteration)
336 return;
337
338 // Si cette méthode est appelée à la fin de l'itération, alors les
339 // temps cpu (m_thm_diff_cpu) et elapsed (m_thm_global_elapsed_time)
340 // ne sont pas bon car ils ont été calculés en début d'itération et donc
341 // ils ne sont pas bon. On les recalcule donc en prenant soin
342 // de ne pas mettre à jour les variables m_global* pour éviter toute
343 // incohérence car ces valeurs ne sont pas synchronisées entre tous
344 // les sous-domaines (et de plus cette méthode n'est pas toujours
345 // appelée)
346
347 Real cpu_time = (Real)platform::getCPUTime();
348 Real elapsed_time = platform::getRealTime();
349 Real diff_cpu = (cpu_time - m_old_cpu_time) / 1000000.0;
350 Real diff_elapsed = (elapsed_time - m_old_elapsed_time);
351 Real mem_used = platform::getMemoryUsed();
352 Real global_cpu_time = diff_cpu + m_global_cpu_time();
353 Real global_elapsed_time = diff_elapsed + m_global_elapsed_time();
354
356 thm->addValue("TotalMemory",mem_used);
357 thm->addValue("CpuTime",diff_cpu);
358 thm->addValue("GlobalCpuTime",global_cpu_time);
359 thm->addValue("ElapsedTime",diff_elapsed);
360 thm->addValue("GlobalElapsedTime",global_elapsed_time);
361 thm->addValue(m_global_time.name(),m_thm_global_time);
362 m_has_thm_dump_at_iteration = true;
363
364 Int64 i_elapsed = (Int64)(global_elapsed_time * 1000.0);
365 Int64 i_diff_elapsed = (Int64)(diff_elapsed * 1000.0);
366 Int64 i_cpu = (Int64)(global_cpu_time * 1000.0);
367
368 info(4) << "EndIter: Date: " << platform::getCurrentDateTime()
369 << " Conso=(R=" << (((Real)i_elapsed) / 1000.0)
370 << ",I=" << (((Real)i_diff_elapsed) / 1000.0)
371 << ",C=" << ((Real)i_cpu / 1000.0)
372 << ") Mem=(" << (Int64)(mem_used/1e6)
373 << ")";
374}
375
376/*---------------------------------------------------------------------------*/
377/*---------------------------------------------------------------------------*/
378
379/*---------------------------------------------------------------------------*/
380/*---------------------------------------------------------------------------*/
381
387
388/*---------------------------------------------------------------------------*/
389/*---------------------------------------------------------------------------*/
390
391void ModuleMaster::
392_masterBeginLoop()
393{
394 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
396 service->onTimeLoopBeginLoop();
397 }
398}
399
400/*---------------------------------------------------------------------------*/
401/*---------------------------------------------------------------------------*/
402
403void ModuleMaster::
404_masterEndLoop()
405{
406 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
407 ITimeLoopService* service = m_timeloop_services[i];
408 service->onTimeLoopEndLoop();
409 }
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
415void ModuleMaster::
416_masterStartInit()
417{
418 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
419 ITimeLoopService* service = m_timeloop_services[i];
420 service->onTimeLoopStartInit();
421 }
422}
423
424/*---------------------------------------------------------------------------*/
425/*---------------------------------------------------------------------------*/
426
427void ModuleMaster::
428_masterContinueInit()
429{
430 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
431 ITimeLoopService* service = m_timeloop_services[i];
432 service->onTimeLoopContinueInit();
433 }
434}
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
439void ModuleMaster::
440_masterLoopExit()
441{
442 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
443 ITimeLoopService* service = m_timeloop_services[i];
444 service->onTimeLoopExit();
445 }
446}
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
450
451void ModuleMaster::
452_masterMeshChanged()
453{
454 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
455 ITimeLoopService* service = m_timeloop_services[i];
456 service->onTimeLoopMeshChanged();
457 }
458}
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
463void ModuleMaster::
464_masterRestore()
465{
466 for( Integer i=0, is=m_timeloop_services.size(); i<is; ++i ){
467 ITimeLoopService* service = m_timeloop_services[i];
468 service->onTimeLoopRestore();
469 }
470}
471
472/*---------------------------------------------------------------------------*/
473/*---------------------------------------------------------------------------*/
474
475ARCANE_END_NAMESPACE
476
477/*---------------------------------------------------------------------------*/
478/*---------------------------------------------------------------------------*/
479
Classe représentant un module.
ISubDomain * subDomain() const override
Sous-domaine associé au module.
IParallelMng * parallelMng() const override
Gestionnaire du parallélisme par échange de message.
Variables communes d'un cas.
VariableScalarInt32 m_global_iteration
Itération courante.
VariableScalarReal m_global_elapsed_time
Temps horloge utilisé (en seconde)
VariableScalarReal m_global_cpu_time
Temps CPU utilisé (en seconde)
VariableScalarReal m_global_old_deltat
Delta T au temps précédent le temps global.
VariableScalarReal m_global_old_elapsed_time
Temps précédent horloge utilisé (en seconde)
VariableScalarReal m_global_time
Temps actuel.
VariableScalarReal m_global_old_cpu_time
Temps précédent CPU utilisé (en seconde)
VariableScalarReal m_global_old_time
Temps précédent le temps actuel.
VariableScalarReal m_global_deltat
Delta T global.
Informations sur le type flottant.
Definition Limits.h:48
Interface du gestionnaire de cas.
Definition ICaseMng.h:56
virtual void updateOptions(Real current_time, Real current_deltat, Integer current_iteration)=0
Met à jour les options basée sur une table de marche en temps.
@ PAutoLoadEnd
Chargé automatiquement à la fin. Cela signifie qu'un module possédant un point d'entrée avec cette pr...
Definition IEntryPoint.h:80
@ PAutoLoadBegin
Chargé automatiquement au début. Cela signifie qu'un module possédant un point d'entrée avec cette pr...
Definition IEntryPoint.h:73
static const char *const WComputeLoop
appelé pendant la boucle de calcul
Definition IEntryPoint.h:42
static const char *const WStartInit
appelé pendant l'initialisation d'un nouveau cas
Definition IEntryPoint.h:50
static const char *const WRestore
appelé pour restaurer les variables lors d'un retour arrière
Definition IEntryPoint.h:52
static const char *const WOnMeshChanged
appelé après un changement de maillage
Definition IEntryPoint.h:54
static const char *const WContinueInit
appelé pendant l'initialisation d'une reprise
Definition IEntryPoint.h:48
static const char *const WInit
appelé pendant l'initialisation
Definition IEntryPoint.h:46
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual void computeMinMaxSum(char val, char &min_val, char &max_val, char &sum_val, Int32 &min_rank, Int32 &max_rank)=0
Calcule en une opération la somme, le min, le max d'une valeur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual ITimeHistoryMng * timeHistoryMng()=0
Retourne le gestionnaire d'historique.
virtual ICaseMng * caseMng()=0
Retourne le gestionnaire du jeu de données.
virtual IParallelMng * allReplicaParallelMng() const =0
Retourne le gestionnaire de parallélisme pour tous les réplicats.
Classe gérant un historique de valeurs.
virtual void addValue(const String &name, Real value, bool end_time=true, bool is_local=false)=0
Ajoute la valeur value à l'historique name.
Interface d'un service opérant lors de la boucle en temps.
Informations pour construire un module.
ISubDomain * subDomain() const
Accès au sous-domaine associé
void masterInit()
Point d'entrée auto-chargé en début d'initialisation.
virtual ~ModuleMaster()
Destructeur.
void masterStartInit()
Point d'entrée auto-chargé en début d'initialisation d'un nouveau cas.
CaseOptionsMain * m_case_options_main
Instance des options du module.
bool m_is_first_loop
Indique si on est dans la première itération de l'exécution.
Real m_old_cpu_time
Valeur du temps CPU à la derniere itération.
Real m_old_elapsed_time
Valeur du temps horloge à la derniere itération.
virtual void timeStepInformation()
Affichage surchargeable des informations du pas de temps.
void timeLoopEnd()
Point d'entrée auto-chargé en fin d'itération de la boucle de calcul.
void timeLoopBegin()
Point d'entrée auto-chargé en début d'itération de la boucle de calcul.
virtual void addTimeLoopService(ITimeLoopService *tls)
Ajoute le service de boucle en temps.
virtual void dumpStandardCurves()
Sort les courbes classiques (CPUTime, ElapsedTime, ...)
UniqueArray< ITimeLoopService * > m_timeloop_services
Liste des serviecs de boucle en temps.
virtual void timeIncrementation()
Incrémentation du pas de temps surchargeable.
Integer m_nb_loop
Nombre de boucles de calcul effectuées.
void masterContinueInit()
Point d'entrée auto-chargé en début de reprise d'un nouveau cas.
String name() const
Nom de la variable.
Vue modifiable d'un tableau d'un type T.
TraceMessage info() const
Flot pour un message d'information.
Formattage des réels avec une précision donnée.
Formattage du flot en longueur.
IOnlineDebuggerService * getOnlineDebuggerService()
Service utilisé pour obtenir la mise en place d'une architecture en ligne de debug.
void addEntryPoint(ModuleType *module, const char *name, void(ModuleType::*func)(), const String &where=IEntryPoint::WComputeLoop, int property=IEntryPoint::PNone)
Routine template permettant de référencer un point d'entrée dans un module.
Definition EntryPoint.h:166