Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcaneCheckpointModule.cc
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/* ArcaneCheckpointModule.cc (C) 2000-2026 */
9/* */
10/* Module gérant les protections/reprises. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/Convert.h"
19
20#include "arcane/core/ISubDomain.h"
21#include "arcane/core/EntryPoint.h"
22#include "arcane/core/Timer.h"
23#include "arcane/core/ITimeHistoryMng.h"
24#include "arcane/core/ModuleFactory.h"
25#include "arcane/core/ServiceUtils.h"
26#include "arcane/core/ICheckpointWriter.h"
27#include "arcane/core/ICheckpointMng.h"
28#include "arcane/core/Directory.h"
29#include "arcane/core/IParallelMng.h"
30
31#include "arcane/core/OutputChecker.h"
32#include "arcane/std/ArcaneCheckpoint_axl.h"
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
46class ArcaneCheckpointModule
47: public ArcaneArcaneCheckpointObject
48{
49 public:
50
51 ArcaneCheckpointModule(const ModuleBuilder& cb);
52 ~ArcaneCheckpointModule();
53
54 public:
55
56 virtual VersionInfo versionInfo() const { return VersionInfo(0, 9, 1); }
57
58 public:
59
60 virtual void checkpointCheckAndWriteData();
61 virtual void checkpointStartInit();
62 virtual void checkpointInit();
63 virtual void checkpointExit();
64
65 private:
66
67 OutputChecker m_output_checker;
68 Timer* m_checkpoint_timer;
69 ICheckpointWriter* m_checkpoint_writer;
70 String m_checkpoint_dirname;
71
72 private:
73
74 void _doCheckpoint(bool save_history);
75 void _dumpStats();
76 void _getCheckpointService();
77 void _setDirectoryName();
78 bool _checkHasOutput();
79};
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84ARCANE_REGISTER_MODULE_ARCANECHECKPOINT(ArcaneCheckpointModule);
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89ArcaneCheckpointModule::
90ArcaneCheckpointModule(const ModuleBuildInfo& mb)
92, m_output_checker(mb.subDomain(), "CheckpointRestart")
93, m_checkpoint_timer(0)
94, m_checkpoint_writer(0)
95, m_checkpoint_dirname(".")
96{
97 m_checkpoint_timer = new Timer(mb.subDomain(), "Checkpoint", Timer::TimerReal);
98 m_output_checker.assignIteration(&m_next_iteration, &options()->period);
99 m_output_checker.assignGlobalTime(&m_next_global_time, &options()->frequency);
100 m_output_checker.assignCPUTime(&m_next_cpu_time, &options()->frequencyCpu);
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106ArcaneCheckpointModule::
107~ArcaneCheckpointModule()
108{
109 delete m_checkpoint_timer;
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115void ArcaneCheckpointModule::
116checkpointInit()
117{
118 // Contrairement aux autres types de sortie, il faut remettre le temps
119 // CPU de la prochaine sortie à zéro car le temps CPU utilisé est de
120 // l'exécution courante.
121 m_next_cpu_time = options()->frequencyCpu();
122 info() << " -------------------------------------------";
123 info() << "| PROTECTION-REPRISE |";
124 info() << " -------------------------------------------";
125 info() << " ";
126 //info() << " Utilise le service '" << options()->checkpointServiceName()
127 // << "' pour les protections";
128 info() << " ";
129 m_output_checker.initialize();
130 info() << " ";
131 // Si les protections sont actives, vérifie que le service spécifié
132 // existe bien
133 if (options()->doDumpAtEnd()) {
134 info() << "Protection requise à la fin des calculs";
135 _getCheckpointService();
136 }
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142bool ArcaneCheckpointModule::
143_checkHasOutput()
144{
145 Real old_time = m_global_old_time();
146 Real current_time = m_global_time();
147 Integer iteration = m_global_iteration();
149
150 bool do_output = m_output_checker.check(old_time, current_time, iteration, cpu_used);
151 return do_output;
152}
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
156
157void ArcaneCheckpointModule::
158checkpointStartInit()
159{
160 m_next_global_time = 0.;
162 m_next_cpu_time = 0;
163
164 // Initialise le vérificateur de sortie. Il faut le faire ici si on
165 // veut sauver des choses à l'itération 1.
166 _checkHasOutput();
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
178{
179 if (!options()->doDumpAtEnd())
180 return;
181
182 _doCheckpoint(false);
183 _dumpStats();
184
185 if (m_checkpoint_writer)
186 m_checkpoint_writer->close();
187 m_checkpoint_writer = 0;
188}
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
193void ArcaneCheckpointModule::
194_dumpStats()
195{
196 // Affiche statistiques d'exécutions
197 Real total_time = m_checkpoint_timer->totalTime();
198 info() << "Temps total passé dans la sortie de protection (secondes) : " << total_time;
199 Integer nb_time = m_checkpoint_timer->nbActivated();
200 if (nb_time != 0)
201 info() << "Temps moyen par sortie (secondes) : " << total_time / nb_time
202 << " (pour " << nb_time << " sorties";
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208void ArcaneCheckpointModule::
209_setDirectoryName()
210{
211 Directory export_dir = subDomain()->storageDirectory();
212 if (export_dir.path().null())
213 export_dir = subDomain()->exportDirectory();
214
215 Directory output_directory = Directory(export_dir, "protection");
216 IParallelMng* pm = parallelMng();
217 if (pm->isMasterIO())
218 output_directory.createDirectory();
219 pm->barrier();
220
221 m_checkpoint_dirname = output_directory.path();
222}
223
224/*---------------------------------------------------------------------------*/
225/*---------------------------------------------------------------------------*/
226
233_doCheckpoint(bool save_history)
234{
235 {
236 Timer::Sentry sentry(m_checkpoint_timer);
237 Timer::Phase tp(subDomain(), TP_InputOutput);
238 if (!m_checkpoint_writer)
239 _getCheckpointService();
240 if (m_checkpoint_writer) {
241 Integer nb_checkpoint = m_checkpoints_time.size();
242 m_checkpoints_time.resize(nb_checkpoint + 1);
243 Real checkpoint_time = m_global_time();
244 m_checkpoints_time[nb_checkpoint] = checkpoint_time;
245 m_checkpoint_writer->setCheckpointTimes(m_checkpoints_time);
246 m_checkpoint_writer->setBaseDirectoryName(m_checkpoint_dirname);
247 info() << "**** Protection active au temps " << checkpoint_time
248 << " répertoire=" << m_checkpoint_dirname
249 << " numéro " << nb_checkpoint << " ******";
250 subDomain()->checkpointMng()->writeDefaultCheckpoint(m_checkpoint_writer);
251 }
252 }
253 info() << "Temps d'écriture du point de contrôle (secondes) : "
254 << m_checkpoint_timer->lastActivationTime();
255
256 // Sauve les historiques
257 if (save_history)
259}
260
261/*---------------------------------------------------------------------------*/
262/*---------------------------------------------------------------------------*/
263
264void ArcaneCheckpointModule::
265_getCheckpointService()
266{
267 ICheckpointWriter* checkpoint = options()->checkpointService();
268 if (!checkpoint) {
269 StringUniqueArray valid_values;
270 options()->checkpointService.getAvailableNames(valid_values);
271 pfatal() << "Les protections sont requises mais le service de protection/restauration sélectionné ("
272 << options()->checkpointService.serviceName() << ") n'est pas disponible "
273 << "(valeurs valides : " << String::join(", ", valid_values) << ")";
274 }
275 m_checkpoint_writer = checkpoint;
276 _setDirectoryName();
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
288{
289 bool do_output = _checkHasOutput();
290 if (!do_output)
291 return;
292
293 info() << "Protection requise.";
294 // TEMPORAIRE:
295 // Contrairement a la protection en fin d'execution, celle-ci a lieu
296 // dans à la fin de la boucle en temps, mais avant que le numéro
297 // d'itération ne soit incrémenté. Si on reprend à ce temps,
298 // le numéro d'itération ne sera pas bon. Pour corriger ce problème,
299 // on incrémente ce nombre avant la protection et on le remet
300 // à sa bonne valeur après.
301 // SDC : ce probleme n'est pas constaté. Il me semble que c'est bien le numérod
302 // de l'itération courante qu'il faut sauver. Changé pour un problème de restart
303 // pour une application IFPEN (en interne Bugzilla 778.
304 // m_global_iteration = m_global_iteration() + 1;
305 _doCheckpoint(true);
306 // m_global_iteration = m_global_iteration() - 1;
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
312} // End namespace Arcane
313
314/*---------------------------------------------------------------------------*/
315/*---------------------------------------------------------------------------*/
Génération de la classe de base du Module.
CaseOptionsArcaneCheckpoint * options() const
Options du jeu de données du module.
Arcane::VariableScalarInteger m_next_iteration
Variables du module.
ISubDomain * subDomain() const override
Sous-domaine associé au module.
IParallelMng * parallelMng() const override
Gestionnaire du parallélisme par échange de message.
virtual void checkpointCheckAndWriteData()
Vérifie s'il faut faire une protection à cet instant et l'effectue si nécessaire.
virtual VersionInfo versionInfo() const
Version du module.
void _doCheckpoint(bool save_history)
Effectue une protection.
virtual void checkpointExit()
Opérations de fin de calcul.
VariableScalarInt32 m_global_iteration
Itération courante.
VariableScalarReal m_global_cpu_time
Temps CPU utilisé (en seconde).
VariableScalarReal m_global_time
Temps actuel.
VariableScalarReal m_global_old_time
Temps précédent le temps actuel.
virtual void writeDefaultCheckpoint(ICheckpointWriter *writer)=0
Écrit une protection avec l'écrivain writer.
Interface du service d'écriture d'une protection/reprise.
virtual const IDirectory & storageDirectory() const =0
Répertoire de base des exportations nécessitant un archivage.
virtual ICheckpointMng * checkpointMng() const =0
Gestionnaire de protections.
virtual ITimeHistoryMng * timeHistoryMng()=0
Retourne le gestionnaire d'historique.
virtual const IDirectory & exportDirectory() const =0
Répertoire de base des exportations.
virtual void dumpHistory(bool is_verbose)=0
Sauve l'historique.
Gère les sorties basées sur un temps physique, temps CPU ou un nombre d'itération.
Chaîne de caractères unicode.
Positionne la phase de l'action en cours d'exécution.
Definition Timer.h:128
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
Gestion d'un timer.
Definition Timer.h:62
Integer nbActivated() const
Retourne le nombre de fois que le timer a été activé
Definition Timer.h:222
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Real totalTime() const
Retourne le temps total (en secondes) passé dans le timer.
Definition Timer.h:216
TraceMessage pfatal() const
Flot pour un message d'erreur fatale en parallèle.
TraceMessage info() const
Flot pour un message d'information.
Informations sur une version.
Definition VersionInfo.h:46
Integer toInteger(Real r)
Convertit un Real en Integer.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type représentant un entier.
double Real
Type représentant un réel.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Definition UtilsTypes.h:357