Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TimeLoopMng.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/* TimeLoopMng.cc (C) 2000-2025 */
9/* */
10/* Time loop manager. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iterator.h"
15#include "arcane/utils/List.h"
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/StringBuilder.h"
19#include "arcane/utils/IMemoryInfo.h"
20#include "arcane/utils/ITraceMng.h"
21#include "arcane/utils/IProfilingService.h"
22#include "arcane/utils/IMessagePassingProfilingService.h"
23#include "arcane/utils/ValueConvert.h"
24#include "arcane/utils/TimeoutException.h"
25#include "arcane/utils/GoBackwardException.h"
26#include "arcane/utils/OStringStream.h"
27#include "arcane/utils/FloatingPointExceptionSentry.h"
28#include "arcane/utils/JSONWriter.h"
29
30#include "arcane/core/IApplication.h"
31#include "arcane/core/IServiceLoader.h"
32#include "arcane/core/ISubDomain.h"
33#include "arcane/core/CommonVariables.h"
34#include "arcane/core/IVariableMng.h"
35#include "arcane/core/IEntryPoint.h"
36#include "arcane/core/IEntryPointMng.h"
37#include "arcane/core/IMesh.h"
38#include "arcane/core/IMeshSubMeshTransition.h"
39#include "arcane/core/IModule.h"
40#include "arcane/core/Directory.h"
41#include "arcane/core/IModuleMng.h"
42#include "arcane/core/Timer.h"
43#include "arcane/core/ITimeLoop.h"
44#include "arcane/core/ITimeLoopMng.h"
45#include "arcane/core/TimeLoopEntryPointInfo.h"
46#include "arcane/core/TimeLoopSingletonServiceInfo.h"
47#include "arcane/core/IParallelMng.h"
48#include "arcane/core/IMainFactory.h"
49#include "arcane/core/ICaseMng.h"
50#include "arcane/core/ICaseFunction.h"
51#include "arcane/core/IServiceFactory.h"
52#include "arcane/core/IModuleFactory.h"
53#include "arcane/core/ServiceBuilder.h"
54#include "arcane/core/ServiceInfo.h"
55#include "arcane/core/ServiceUtils.h"
56#include "arcane/core/CaseOptions.h"
57#include "arcane/core/ICaseDocument.h"
58#include "arcane/core/IVerifierService.h"
59#include "arcane/core/IMeshPartitioner.h"
60#include "arcane/core/IVariableFilter.h"
61#include "arcane/core/ITimeStats.h"
62#include "arcane/core/XmlNodeIterator.h"
63#include "arcane/core/ServiceFinder2.h"
64#include "arcane/core/VariableCollection.h"
65#include "arcane/core/Observable.h"
66#include "arcane/core/IParallelReplication.h"
67#include "arcane/core/IItemFamily.h"
68#include "arcane/core/IConfiguration.h"
69#include "arcane/core/IMeshUtilities.h"
70#include "arcane/core/IVariableUtilities.h"
71#include "arcane/core/IItemEnumeratorTracer.h"
72#include "arcane/core/ObservablePool.h"
73#include "arcane/core/parallel/IStat.h"
74#include "arcane/core/IVariableSynchronizer.h"
75#include "arcane/core/IVariableSynchronizerMng.h"
76#include "arcane/core/VariableComparer.h"
77
78#include "arcane/accelerator/core/IAcceleratorMng.h"
79#include "arcane/accelerator/core/Runner.h"
80
81#include "arcane/impl/DefaultBackwardMng.h"
82
83#include <algorithm>
84#include <map>
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89namespace Arcane
90{
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
98class TimeLoopMng
99: public TraceAccessor
100, public ITimeLoopMng
101{
102 public:
103
104 struct ModuleState
105 {
106 ModuleState(bool is_optional, const String& alias)
107 : m_is_active(false)
108 , m_is_optional(is_optional)
109 , m_alias(alias)
110 {}
111
112 bool m_is_active;
113 bool m_is_optional;
114 String m_alias;
115 };
124
126 typedef std::map<String, ModuleState> ModuleStateMap;
128 typedef std::map<String, ITimeLoop*> TimeLoopMap;
130 typedef std::map<String, IModuleFactoryInfo*> ModuleFactoryMap;
131
132 public:
133
134 explicit TimeLoopMng(ISubDomain* sd);
135 ~TimeLoopMng() override;
136
137 public:
138
139 void build() override;
140
141 ISubDomain* subDomain() const override { return m_sub_domain; }
142
143 void execExitEntryPoints() override;
144 void execBuildEntryPoints() override;
145 void execInitEntryPoints(bool is_continue) override;
146 void stopComputeLoop(bool is_final_time, bool has_error) override;
147 bool finalTimeReached() const override { return m_final_time_reached; }
148 Real cpuTimeUsed() const override;
149
152
153 void registerTimeLoop(ITimeLoop* timeloop) override;
154 void setUsedTimeLoop(const String& name) override;
155
156 ITimeLoop* usedTimeLoop() const override { return m_used_time_loop; }
157
158 void doExecNextEntryPoint(bool& is_last) override;
159 IEntryPoint* nextEntryPoint() override;
160
162
163 int doOneIteration() override;
164
165 void setBackwardMng(IBackwardMng* backward_mng) override;
166 // Attention, may return NULL
167 IBackwardMng* getBackwardMng() const override { return m_backward_mng; }
168
169 void goBackward() override;
170 bool isDoingBackward() override;
172 {
173 if (!m_backward_mng)
174 _createOwnDefaultBackwardMng();
175 m_backward_mng->setSavePeriod(n);
176 }
177
178 void setVerificationActive(bool is_active) override { m_verification_active = is_active; }
179 void doVerification(const String& name) override;
180
181 void registerActionMeshPartition(IMeshPartitionerBase* mesh_partitioner) override;
182
183 void timeLoopsName(StringCollection& names) const override;
184 void timeLoops(TimeLoopCollection& time_loops) const override;
185 ITimeLoop* createTimeLoop(const String& name) override;
186
187 int doComputeLoop(Integer max_loop) override;
188 Integer nbLoop() const override { return m_nb_loop; }
189
190 void setStopReason(eTimeLoopStopReason reason) override;
191 eTimeLoopStopReason stopReason() const override { return m_stop_reason; }
192
193 public:
194
195 void execRestoreEntryPoints();
196 void execOnMeshChangedEntryPoints() override;
197 void execOnMeshRefinementEntryPoints() override;
198
199 ITraceMng* traceMng() { return m_sub_domain->traceMng(); }
200
201 IObservable* observable(eTimeLoopEventType type) override
202 {
203 return m_observables[type];
204 }
205
206 protected:
207
211 bool _createModule(const String& module_name);
213
214 void _processEntryPoints(EntryPointList& entry_points,
215 const TimeLoopEntryPointInfoCollection& entry_points_info,
216 const char* where);
221 void _fillModuleStateMap(ITimeLoop* time_loop);
222
227 static void _extractModuleAndEntryPointName(const String& timeloop_call_name,
228 String& module_name, String& entry_point_name);
229
230 private:
231
234
237
240
243
246
249
252
255
258
261
264
267
269
271
273
274 bool m_stop_time_loop;
275 bool m_stop_has_error;
276 bool m_final_time_reached;
277
279
281 bool m_verif_same_parallel;
283 bool m_verification_active;
286 bool m_verification_only_at_exit = false;
288
290 bool m_my_own_backward_mng;
291
292 ModuleStateMap m_module_state_list;
293
296
298 UniqueArray<IMeshPartitionerBase*> m_mesh_partitioner;
299 String m_message_class_name;
300 Integer m_alarm_timer_value;
301 Integer m_nb_loop;
302
304
305 eTimeLoopStopReason m_stop_reason;
306
307 // Message passing profiling service
308 Ref<IMessagePassingProfilingService> m_msg_pass_prof_srv;
309
312
313 private:
314
315 void _execOneEntryPoint(IEntryPoint* ic, Integer index_value = 0, bool do_verif = false);
316 void _dumpTimeInfos(JSONWriter& json_writer);
317 void _resetTimer() const;
318 void _checkVerif(const String& entry_point_name, Integer index, bool do_verif);
319 void _checkVerifSameOnAllReplica(const String& entry_point_name);
320 void _createOwnDefaultBackwardMng();
321 void _doMeshPartition();
323 void _createSingletonServices(IServiceLoader* service_loader);
324 void _callSpecificEntryPoint();
325};
326
327/*---------------------------------------------------------------------------*/
328/*---------------------------------------------------------------------------*/
329
330extern "C++" ITimeLoopMng*
331arcaneCreateTimeLoopMng(ISubDomain* mng)
332{
333 auto* tm = new TimeLoopMng(mng);
334 return tm;
335}
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
339
340TimeLoopMng::
341TimeLoopMng(ISubDomain* sd)
342: TraceAccessor(sd->traceMng())
343, m_sub_domain(sd)
344, m_entry_point_mng(m_sub_domain->entryPointMng())
345, m_default_time_loop(nullptr)
346, m_used_time_loop(nullptr)
347, m_current_entry_point_ptr(nullptr)
348, m_stop_time_loop(false)
349, m_stop_has_error(false)
350, m_final_time_reached(false)
351, m_current_entry_point(0)
352, m_verif_type(VerifNone)
353, m_verif_same_parallel(false)
354, m_verif_path(".")
355, m_verification_active(false)
356, m_verification_at_entry_point(false)
357, m_backward_mng(nullptr)
358, m_my_own_backward_mng(false)
359, m_message_class_name("TimeLoopMng")
360, m_alarm_timer_value(0)
361, m_nb_loop(0)
362, m_stop_reason(eTimeLoopStopReason::NoStop)
363{
364 {
365 String s = platform::getEnvironmentVariable("ARCANE_LISTENER_TIMEOUT");
366 if (!s.null()) {
367 Integer v = 0;
368 if (!builtInGetValue(v, s))
369 if (v > 0)
370 m_alarm_timer_value = v;
371 }
372 }
373 {
374 String s = platform::getEnvironmentVariable("ARCANE_VERIF_PARALLEL");
375 if (!s.null())
376 m_verif_same_parallel = true;
377 }
378
379 m_observables.add(eTimeLoopEventType::BeginEntryPoint);
380 m_observables.add(eTimeLoopEventType::EndEntryPoint);
381 m_observables.add(eTimeLoopEventType::BeginIteration);
382 m_observables.add(eTimeLoopEventType::EndIteration);
383}
384
385/*---------------------------------------------------------------------------*/
386/*---------------------------------------------------------------------------*/
387
388TimeLoopMng::
389~TimeLoopMng()
390{
391 for (ConstIterT<TimeLoopMap> i(m_time_loop_list); i(); ++i) {
392 ITimeLoop* tm = i->second;
393 delete tm;
394 }
395
396 if (m_my_own_backward_mng)
397 delete m_backward_mng;
398}
399
400/*---------------------------------------------------------------------------*/
401/*---------------------------------------------------------------------------*/
402
403void TimeLoopMng::
404build()
405{
406 // Creates and registers a default loop.
407 ITimeLoop* tm = createTimeLoop(String("ArcaneEmptyLoop"));
410
411 {
412 String verif_env = platform::getEnvironmentVariable("STDENV_VERIF");
413 if (verif_env == "READ") {
415 info() << "Checking in read mode";
416 }
417 if (verif_env == "WRITE") {
419 info() << "Checking in write mode";
420 }
421 if (verif_env == "CHECKSYNC") {
422 m_verif_type = VerifSync;
423 info() << "Checking synchronizations";
424 }
425 if (verif_env == "CHECKREPLICA") {
427 info() << "Checking variables values between replica";
428 }
429 if (m_verif_type != VerifNone)
430 m_verification_active = true;
431 }
432
433 {
434 String s = platform::getEnvironmentVariable("STDENV_VERIF_DIFF_METHOD");
435 if (!s.null()) {
436 if (s == "RELATIVE") {
438 info() << "Using 'Relative' method to compute difference of variable values";
439 }
440 if (s == "LOCALNORMMAX") {
442 info() << "Using 'LocalNormMax' method to compute difference of variable values";
443 }
444 }
445 }
446 {
447 String s = platform::getEnvironmentVariable("STDENV_VERIF_ENTRYPOINT");
448 if (!s.null()) {
450 info() << "Do verification at each entry point";
451 }
452 }
453 {
454 String s = platform::getEnvironmentVariable("STDENV_VERIF_ONLY_AT_EXIT");
455 if (s == "1" || s == "true" || s == "TRUE") {
456 m_verification_only_at_exit = true;
457 info() << "Do verification only at exit";
458 }
459 }
460 // Checks if only a single entry point is executed instead of the time loop.
461 // This is used only for tests
462 {
463 String s = platform::getEnvironmentVariable("ARCANE_CALL_SPECIFIC_ENTRY_POINT");
464 if (!s.null()) {
466 info() << "Use specific entry point: " << s;
467 }
468 }
469
470 //
471 if (m_verification_active) {
472 m_verif_path = platform::getEnvironmentVariable("STDENV_VERIF_PATH");
473 if (m_verif_path.null()) {
474 String user_name = subDomain()->application()->userName();
475 m_verif_path = "/tmp/" + user_name + "/verif";
476 //m_verif_path += user_name;
477 //m_verif_path += "/verif";
478 }
479 }
480 if (m_verif_type == VerifWrite) {
481 if (subDomain()->parallelMng()->isMasterIO()) {
482 info() << "Creating directory '" << m_verif_path << "' for checking";
484 }
485 }
486
487 // Creation of the "message passing profiling" service if necessary
488 {
489 String msg_pass_prof_str = platform::getEnvironmentVariable("ARCANE_MESSAGE_PASSING_PROFILING");
490 if (!msg_pass_prof_str.null()) {
491 String service_name;
492 // TODO: do not use if statements but use the name specified by the
493 // environment variable directly.
494 if (msg_pass_prof_str == "JSON") {
495 service_name = "JsonMessagePassingProfiling";
496 }
497 else if (msg_pass_prof_str == "OTF2") {
498 service_name = "Otf2MessagePassingProfiling";
499 }
500 ServiceBuilder<IMessagePassingProfilingService> srv(this->subDomain());
501 m_msg_pass_prof_srv = srv.createReference(service_name, SB_AllowNull);
502 }
503 }
504}
505
506/*---------------------------------------------------------------------------*/
507/*---------------------------------------------------------------------------*/
508
509void TimeLoopMng::
510_createOwnDefaultBackwardMng()
511{
512 m_backward_mng = new DefaultBackwardMng(traceMng(), subDomain());
513 m_backward_mng->init();
514 m_my_own_backward_mng = true;
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
520void TimeLoopMng::
521setBackwardMng(IBackwardMng* backward_mng)
522{
523 ARCANE_ASSERT((backward_mng), ("IBackwardMng pointer null"));
524
525 if (m_backward_mng) {
526 // Destroys the old manager if we created it.
527 if (m_my_own_backward_mng)
528 delete m_backward_mng;
529 ARCANE_FATAL("Backward manager already set");
530 }
531
532 m_backward_mng = backward_mng;
533 m_my_own_backward_mng = false;
534}
535
536/*---------------------------------------------------------------------------*/
537/*---------------------------------------------------------------------------*/
538
540execInitEntryPoints(bool is_continue)
541{
542 Timer::Action ts_action(m_sub_domain, "InitEntryPoints");
543 info() << "-- Executing init entry points";
544
546
548 IEntryPoint* ic = *i;
549 if (ic->where() == IEntryPoint::WInit || ic->where() == where)
550 _execOneEntryPoint(ic);
551 }
552}
553
554/*---------------------------------------------------------------------------*/
555/*---------------------------------------------------------------------------*/
556
559{
560 Timer::Action ts_action(m_sub_domain, "BuildtEntryPoints");
561 info() << "-- Executing build entry points";
562
564 IEntryPoint* ic = *i;
565 if (ic->where() == IEntryPoint::WBuild)
566 _execOneEntryPoint(ic);
567 }
568}
569
570/*---------------------------------------------------------------------------*/
571/*---------------------------------------------------------------------------*/
572
573void TimeLoopMng::
574execRestoreEntryPoints()
575{
576 Timer::Action ts_action(m_sub_domain, "RestoreEntryPoints");
577 info() << "-- Executing restore entry points";
578
580 IEntryPoint* ic = *i;
581 _execOneEntryPoint(ic);
582 }
583}
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
590{
591 Timer::Action ts_action(m_sub_domain, "OnMeshChangedEntryPoints");
592 info() << "-- Executing entry points after mesh change";
593
595 IEntryPoint* ic = *i;
596 info() << "Execute: " << ic->name();
597 _execOneEntryPoint(ic);
598 }
599}
600
601/*---------------------------------------------------------------------------*/
602/*---------------------------------------------------------------------------*/
603
606{
607 Timer::Action ts_action(m_sub_domain, "OnMeshRefinementEntryPoints");
608 info() << "-- Executing entry points after mesh refinement";
609
611 IEntryPoint* ic = *i;
612 info() << "Execute: " << ic->name();
613 _execOneEntryPoint(ic);
614 }
615}
616
617/*---------------------------------------------------------------------------*/
618/*---------------------------------------------------------------------------*/
619
622{
623 Timer::Action ts_action(m_sub_domain, "ExitEntryPoints");
624 info() << "-- Executing terminal entry points";
625
627 IEntryPoint* ic = *i;
628 _execOneEntryPoint(ic);
629 }
630
631 // Display execution statistics
632 {
633 JSONWriter json_writer(JSONWriter::FormatFlags::None);
634 json_writer.beginObject();
635 _dumpTimeInfos(json_writer);
636 json_writer.endObject();
637 traceMng()->plog() << "TimeStats:" << json_writer.getBuffer();
638 traceMng()->flush();
639 }
640
641 // Displays message passing profiling in a file for JSON traces
642 if (m_msg_pass_prof_srv.get() && m_msg_pass_prof_srv->implName() == "JsonMessagePassingProfiling") {
643 String fullname(subDomain()->listingDirectory().file("message_passing_logs.") + String(std::to_string(subDomain()->subDomainId())) + String(".json"));
644 std::ofstream file(fullname.localstr());
645 m_msg_pass_prof_srv->printInfos(file);
646 }
647}
648
649/*---------------------------------------------------------------------------*/
650/*---------------------------------------------------------------------------*/
651
652void TimeLoopMng::
653_execOneEntryPoint(IEntryPoint* ic, Integer index, bool do_verif)
654{
656 m_observables[eTimeLoopEventType::BeginEntryPoint]->notifyAllObservers();
657 ic->executeEntryPoint();
658 m_observables[eTimeLoopEventType::EndEntryPoint]->notifyAllObservers();
660 if (m_verification_at_entry_point && !m_verification_only_at_exit)
661 _checkVerif(ic->name(), index, do_verif);
662}
663
664/*---------------------------------------------------------------------------*/
665/*---------------------------------------------------------------------------*/
666
668doVerification(const String& name)
669{
670 _checkVerif(name, 0, true);
671}
672
673/*---------------------------------------------------------------------------*/
674/*---------------------------------------------------------------------------*/
675
676void TimeLoopMng::
677_checkVerif(const String& entry_point_name, Integer index, bool do_verif)
678{
680
681 ISubDomain* sd = subDomain();
682 IApplication* app = sd->application();
683 VariableComparer variable_comparer;
684 VariableComparerArgs sync_compare_args = variable_comparer.buildForCheckIfSync();
685 sync_compare_args.setMaxPrint(5);
686
688 String service_name1 = platform::getEnvironmentVariable("STDENV_VERIF_SERVICE");
689 if (service_name1.empty())
690 service_name1 = "ArcaneBasicVerifier2";
691
693 m_verifier_service = sf.createReference(service_name1);
694 if (!m_verifier_service.get()) {
695 warning() << "No verification service is available."
696 << " No verification will be performed";
698 }
699 if (m_verifier_service.get()) {
700 info() << "Use the service <" << service_name1
701 << "> for verification";
702 }
703 }
704
705 if (pm->isParallel()) {
706 if (m_verif_type == VerifSync) {
707 Integer nb_error = 0;
708 VariableCollection variables(subDomain()->variableMng()->usedVariables());
709 for (VariableCollection::Enumerator i(variables); ++i;) {
710 IVariable* var = *i;
711 if (var->property() & IVariable::PNoNeedSync)
712 continue;
713 if (var->isPartial())
714 continue;
715 VariableComparerResults r = variable_comparer.apply(var, sync_compare_args);
716 nb_error += r.nbDifference();
717 }
718 if (nb_error != 0)
719 info() << "Error in synchronization nb_error=" << nb_error
720 << " entry_point=" << entry_point_name;
721 }
722 }
723
725 _checkVerifSameOnAllReplica(entry_point_name);
726 }
727
728 if ((m_verif_type == VerifRead || m_verif_type == VerifWrite) && do_verif) {
729 Integer current_iter = subDomain()->commonVariables().globalIteration();
730 if (current_iter >= 0) {
731 {
732 StringBuilder path = Directory(m_verif_path).file("verif_file");
733 if (m_verif_same_parallel) {
734 path += "_";
735 path += pm->commRank();
736 }
737
738 StringBuilder sub_dir;
739 sub_dir += "iter";
740 sub_dir += current_iter;
741 sub_dir += "/";
742 sub_dir += entry_point_name;
743 sub_dir += index;
744
745 m_verifier_service->setFileName(path.toString());
746 m_verifier_service->setSubDir(sub_dir.toString());
747 m_verifier_service->setComputeDifferenceMethod(m_compute_diff_method);
748 }
749 bool parallel_sequential = pm->isParallel();
750 if (m_verif_same_parallel)
751 parallel_sequential = false;
752 if (m_verif_type == VerifRead) {
753
754 // Activate this part if we want to save the current values
755#if 0
756 {
757 ServiceFinder2T<IVerifierService,ISubDomain> sf(app,sd);
758 ScopedPtrT<IVerifierService> current_save(sf.find(service_name1));
759 if (current_save.get()){
760 current_save->setFileName(m_verifier_service->fileName()+"_current");
761 current_save->setSubDir(m_verifier_service->subDir());
762 current_save->writeReferenceFile();
763 }
764 }
765#endif
766
767 // In read mode, disable floating point exceptions to avoid
768 // errors when comparing uninitialized variables
769 {
770 FloatingPointExceptionSentry fpes(false);
771 m_verifier_service->doVerifFromReferenceFile(parallel_sequential,
772 platform::getEnvironmentVariable("STDENV_VERIF_SKIP_GHOSTS").null());
773 }
774 }
776 m_verifier_service->writeReferenceFile();
777 }
778 }
779}
780
781/*---------------------------------------------------------------------------*/
782/*---------------------------------------------------------------------------*/
783
784void TimeLoopMng::
785_checkVerifSameOnAllReplica(const String& entry_point_name)
786{
787 info() << "CHECK: comparing variables values on all replica"
788 << " entry_point_name=" << entry_point_name;
789 ISubDomain* sd = subDomain();
790 IParallelMng* replica_pm = sd->parallelMng()->replication()->replicaParallelMng();
791 IVariableMng* vm = sd->variableMng();
792 VariableCollection variables(vm->usedVariables());
793 VariableList vars_to_check;
794 for (VariableCollection::Enumerator i(variables); ++i;) {
795 IVariable* var = *i;
796 if (var->property() & IVariable::PNoReplicaSync)
797 continue;
798 if (var->isPartial())
799 continue;
800 // For now, we do not support comparison between replicas
801 // of 'String' type variables.
802 if (var->dataType() == DT_String)
803 continue;
804 vars_to_check.add(var);
805 }
806 VariableCollection common_vars = vm->utilities()->filterCommonVariables(replica_pm, vars_to_check, true);
807
808 Integer nb_error = 0;
809 VariableComparer variable_comparer;
810 {
811 VariableComparerArgs compare_args = variable_comparer.buildForCheckIfSameOnAllReplica();
812 compare_args.setMaxPrint(10);
813 FloatingPointExceptionSentry fpes(false);
814 for (VariableCollection::Enumerator ivar(common_vars); ++ivar;) {
815 IVariable* var = *ivar;
816 VariableComparerResults r = variable_comparer.apply(var, compare_args);
817 nb_error += r.nbDifference();
818 }
819 }
820
821 if (nb_error != 0)
822 info() << "Errors in comparing values between replica nb_error=" << nb_error
823 << " entry_point=" << entry_point_name;
824}
825
826/*---------------------------------------------------------------------------*/
827/*---------------------------------------------------------------------------*/
828
833doExecNextEntryPoint(bool& is_last)
834{
835 if (!m_used_time_loop)
836 ARCANE_FATAL("No time loop");
837
838 is_last = true;
839
841
842 if (cl.empty())
843 return;
844
845 if (m_current_entry_point >= cl.count())
847
848 _execOneEntryPoint(cl[m_current_entry_point]);
849
851
852 is_last = (m_current_entry_point >= cl.count());
853}
854
855/*---------------------------------------------------------------------------*/
856/*---------------------------------------------------------------------------*/
857
863{
864 //return m_loop_entry_points->EntryPointList()[m_current_entry_point];
866 if (m_current_entry_point >= cl.count())
867 return nullptr;
868 return cl[m_current_entry_point];
869}
870
871/*---------------------------------------------------------------------------*/
872/*---------------------------------------------------------------------------*/
873
876{
877 ITraceMng* msg = traceMng();
878 ISubDomain* sd = subDomain();
879 Trace::Setter mci(msg, m_message_class_name);
880
881 if (!m_used_time_loop)
882 ARCANE_FATAL("No time loop");
883
884 Integer current_iteration = sd->commonVariables().globalIteration();
885 // Iteration number 0 corresponds to initialization. The first
886 // iteration of the time loop is number 1.
887 if (current_iteration == 0) {
889 global_iteration = 1;
890 current_iteration = 1;
891 }
892
893 _resetTimer();
894
895 if (m_stop_time_loop) {
896 if (m_stop_has_error)
897 return (-1);
898 return (+1);
899 }
900
901 m_backward_mng->beginAction();
902
903 // Restoration action
904 if (m_backward_mng->checkAndApplyRestore()) {
905
906 execRestoreEntryPoints();
907
908 // Unnecessary partitioning if going backward
909 m_mesh_partitioner.clear();
910 }
911
912 // Requested partitioning
913 bool mesh_partition_done = false;
914 if (!m_mesh_partitioner.empty()) {
916 mesh_partition_done = true;
917 }
918
919 // Saving action
920 m_backward_mng->checkAndApplySave(mesh_partition_done);
921
922 m_backward_mng->endAction();
923
924 {
925 // Checks modules that are inactive over time
926 Real global_time = sd->commonVariables().globalTime();
927 CaseOptionsCollection blocks(sd->caseMng()->blocks());
928 for (CaseOptionsCollection::Enumerator i(blocks); ++i;) {
929 ICaseOptions* opt = *i;
930 IModule* mod = opt->caseModule();
932 if (mod && f) {
933 bool is_active = true;
934 f->value(global_time, is_active);
935 bool mod_disabled = mod->disabled();
936 bool mod_new_disabled = !is_active;
937 if (mod_new_disabled != mod_disabled) {
938 if (mod_new_disabled)
939 info() << "The module " << mod->name() << " is desactivated";
940 else
941 info() << "The module " << mod->name() << " is activated";
942 mod->setDisabled(mod_new_disabled);
943 }
944 }
945 }
946 }
947
948 m_observables[eTimeLoopEventType::BeginIteration]->notifyAllObservers();
949
950 // Executes each iteration entry point
951 {
952 Integer index = 0;
954 Timer::Action ts_action(sd, "LoopEntryPoints");
955 for (EntryPointList::Enumerator i(m_loop_entry_points); ++i; ++index) {
956 IEntryPoint* ep = *i;
957 IModule* mod = ep->module();
958 if (mod && mod->disabled()) {
959 continue;
960 //warning() << "MODULE " << mod->name() << " is disabled";
961 }
962 try {
963 _execOneEntryPoint(*i, index, true);
964 }
965 catch (const GoBackwardException&) {
966 m_backward_mng->goBackward();
967 }
968 catch (...) { // Catch any other exception
969 throw;
970 }
971 if (m_backward_mng->isBackwardEnabled()) {
972 break;
973 }
974 }
975 if (!m_verification_at_entry_point && !m_verification_only_at_exit)
976 _checkVerif("_EndLoop", 0, true);
977 }
978 m_observables[eTimeLoopEventType::EndIteration]->notifyAllObservers();
979
980 {
981 bool force_prepare_dump = false;
982 if (m_verification_active && m_verif_type == VerifWrite) {
983 if (!m_verif_same_parallel)
984 force_prepare_dump = true;
985 }
986 else {
987 String force_prepare_dump_str = platform::getEnvironmentVariable("ARCANE_FORCE_PREPARE_DUMP");
988 if (force_prepare_dump_str == "TRUE" || force_prepare_dump_str == "1" || force_prepare_dump_str == "true")
989 force_prepare_dump = true;
990 }
991 if (force_prepare_dump) {
992 info() << "TimeLoopMng::doOneIteration(): Force prepareDump()";
993 // TODO: check if necessary and if so, do it for all sub-domains.
995 }
996 }
997
998 if (m_stop_time_loop) {
999 if (m_stop_has_error)
1000 return (-1);
1001 return (+1);
1002 }
1003 return 0;
1004}
1005
1006/*---------------------------------------------------------------------------*/
1007/*---------------------------------------------------------------------------*/
1008
1014{
1015 ISubDomain* sd = subDomain();
1016
1017 // Destroys the backward manager to save memory.
1018 // It will be reconstructed after partitioning.
1019 m_backward_mng->clear();
1020
1021 Timer timer(sd, "TimeLoopMng::partitionMesh", Timer::TimerReal);
1022 Timer::Action ts_action(sd, "MeshesLoadBalance", true);
1023
1024 for (IMeshPartitionerBase* mesh_partitioner : m_mesh_partitioner) {
1025 IMesh* mesh = mesh_partitioner->primaryMesh();
1026 Timer::Action ts_action2(sd, mesh->name(), true);
1027 {
1028 Timer::Sentry sentry(&timer);
1029 mesh->utilities()->partitionAndExchangeMeshWithReplication(mesh_partitioner, false);
1030 }
1031 info() << "Time spent to repartition the mesh (unit: second): "
1032 << timer.lastActivationTime();
1033
1034 // Writes to logs in the infos about neighborhood distribution
1035 // TODO: ability to configure this and possibly add more information
1036 {
1037 IItemFamily* cell_family = mesh->cellFamily();
1038 IVariableSynchronizer* sync_info = cell_family->allItemsSynchronizer();
1039 auto communicating_ranks = sync_info->communicatingRanks();
1040 Int64 current_iteration = subDomain()->commonVariables().globalIteration();
1041 {
1042 JSONWriter json_writer(JSONWriter::FormatFlags::None);
1043 json_writer.beginObject();
1044 json_writer.write("Mesh", mesh->name());
1045 json_writer.write("Iteration", current_iteration);
1046 json_writer.write("CommunicatingRanks", communicating_ranks);
1047 json_writer.endObject();
1048 plog() << "MeshPartitionCommunicatingInfos:" << json_writer.getBuffer();
1049 }
1050 }
1051 }
1052
1053 {
1054 Timer::Action ts_action1(sd, "OnMeshChangeEntryPoints", true);
1056 }
1057
1058 m_mesh_partitioner.clear();
1059
1060 // Displays execution statistics
1061 sd->timeStats()->dumpCurrentStats("MeshesLoadBalance");
1062}
1063
1064/*---------------------------------------------------------------------------*/
1065/*---------------------------------------------------------------------------*/
1066
1067void TimeLoopMng::
1068_callSpecificEntryPoint()
1069{
1071 info() << "Calling specific entry point: " << m_specific_entry_point_name;
1072 if (!ep)
1073 ARCANE_FATAL("No entry point named '{0}' found", m_specific_entry_point_name);
1074 ep->executeEntryPoint();
1075}
1076
1077/*---------------------------------------------------------------------------*/
1078/*---------------------------------------------------------------------------*/
1079
1081registerTimeLoop(ITimeLoop* timeloop)
1082{
1083 ITraceMng* msg = traceMng();
1084 Trace::Setter mci(msg, m_message_class_name);
1085
1086 const String& name = timeloop->name();
1087
1088 log() << "Registering the time loop " << name;
1089
1090 auto tl = m_time_loop_list.find(name);
1091 if (tl != m_time_loop_list.end())
1092 ARCANE_FATAL("The time loop '{0}' is defined twice", name);
1093
1094 m_time_loop_list.insert(TimeLoopMap::value_type(name, timeloop));
1095}
1096
1097/*---------------------------------------------------------------------------*/
1098/*---------------------------------------------------------------------------*/
1099
1101setUsedTimeLoop(const String& name)
1102{
1103 ITraceMng* msg = traceMng();
1104 Trace::Setter mci(msg, m_message_class_name);
1105
1106 m_used_time_loop = nullptr;
1107 if (name.null())
1109 else {
1110 auto tl = m_time_loop_list.find(name);
1111 if (tl != m_time_loop_list.end())
1112 m_used_time_loop = tl->second;
1113 }
1114
1115 if (!m_used_time_loop) {
1116 info() << "Available time loops: ";
1117 for (const auto& tl : m_time_loop_list) {
1118 info() << "Time loop <" << tl.second->name() << ">";
1119 }
1120 ARCANE_FATAL("Unknown time loop '{0}'", name);
1121 }
1122
1123 logdate() << "Using time loop " << name;
1124
1126 // Merges the sub-domain configuration with that of the time loop.
1127 sd->configuration()->merge(m_used_time_loop->configuration());
1128
1130
1131 service_loader->loadModules(sd, false);
1132
1134
1135 // Loading modules of the time loop
1137
1138 for (const auto& it : m_module_state_list) {
1139 const ModuleState& module_state = it.second;
1140
1141 if (!module_state.m_is_optional || module_state.m_is_active) {
1142 // creation of the module
1143 if (!_createModule(module_state.m_alias))
1144 ARCANE_FATAL("The module \"{0}\" was not created.", module_state.m_alias);
1145 }
1146 else {
1147 info() << "The entry points of the module \""
1148 << module_state.m_alias << "\" won't be executed (inactive module).";
1149 }
1150 }
1151
1152 _createSingletonServices(service_loader.get());
1153
1155
1156 // Iterates over entry points explicitly referenced in the time loop
1157 // (m_used_time_loop) to search for those that correspond to entry points
1158 // registered in the modules
1159 // Entry points that are not auto-loaded and not referenced are therefore not supported.
1160 // Note: in the time loop entry points are referenced
1161 // by module_name.entry_point_name while in the data file
1162 // they are referenced by alias_module.entry_point_name
1163 EntryPointList timeloop_entry_points;
1164 _processEntryPoints(timeloop_entry_points,
1165 m_used_time_loop->entryPoints(ITimeLoop::WBuild),
1167 _processEntryPoints(timeloop_entry_points,
1170 _processEntryPoints(timeloop_entry_points,
1173 _processEntryPoints(timeloop_entry_points,
1176 _processEntryPoints(timeloop_entry_points,
1179 _processEntryPoints(timeloop_entry_points,
1180 m_used_time_loop->entryPoints(ITimeLoop::WInit),
1182 _processEntryPoints(timeloop_entry_points,
1183 m_used_time_loop->entryPoints(ITimeLoop::WExit),
1185
1186 // Adds autoloads at the beginning.
1187 EntryPointList entry_points(m_entry_point_mng->entryPoints());
1188 for (EntryPointCollection::Enumerator i(entry_points); ++i;) {
1189 IEntryPoint* ic = *i;
1192 }
1193
1194 // Adds compute loop entry points.
1195 for (EntryPointCollection::Enumerator i(timeloop_entry_points); ++i;)
1197
1198 { // Adds autoloads at the end in reverse order of declaration
1199 EntryPointList auto_load_ends;
1200 for (EntryPointCollection::Enumerator i(entry_points); ++i;) {
1201 IEntryPoint* ic = *i;
1202 if (ic->property() & IEntryPoint::PAutoLoadEnd) {
1203 auto_load_ends.add(ic);
1204 }
1205 }
1206 for (Integer i = 0, s = auto_load_ends.count(); i < s; ++i) {
1207 IEntryPoint* ic = auto_load_ends[s - 1 - i];
1209 }
1210 }
1211}
1212
1213/*---------------------------------------------------------------------------*/
1214/*---------------------------------------------------------------------------*/
1215
1216void TimeLoopMng::
1217_createSingletonServices(IServiceLoader* service_loader)
1218{
1221 const TimeLoopSingletonServiceInfo& ti = *i;
1222 String name = ti.name();
1223 bool is_found = service_loader->loadSingletonService(sd, name);
1224 if (!is_found) {
1225 if (ti.isRequired())
1226 ARCANE_FATAL("Unable to find a singleton service named '{0}'", name);
1227 info() << "The optional singleton service named '" << name << "' was not found";
1228 }
1229 info() << "Loading singleton service '" << name << "'";
1230 }
1231
1232 // Reading services specified in the data set.
1233 ICaseMng* cm = m_sub_domain->caseMng();
1234 ICaseDocument* doc = cm->caseDocument();
1235 if (doc) {
1236 XmlNode services_element = doc->servicesElement();
1237 String ustr_name("name");
1238 String ustr_active("active");
1239 XmlNodeList services = services_element.children("service");
1240 for (XmlNode x : services) {
1241 String name = x.attrValue(ustr_name);
1242 XmlNode active_node = x.attr(ustr_active);
1243 bool is_active = true;
1244 if (!active_node.null())
1245 is_active = active_node.valueAsBoolean(true);
1246 if (is_active)
1247 service_loader->loadSingletonService(sd, name);
1248 }
1249 }
1250}
1251
1252/*---------------------------------------------------------------------------*/
1253/*---------------------------------------------------------------------------*/
1254
1257 const TimeLoopEntryPointInfoCollection& entry_points_info,
1258 const char* where)
1259{
1260 //TODO: Verify that the module name specified in the list of modules to
1261 //activate actually exists.
1262 for (TimeLoopEntryPointInfoCollection::Enumerator i(entry_points_info); ++i;) {
1263 const TimeLoopEntryPointInfo& entry_point_info = *i;
1264 const String& timeloop_call_name = entry_point_info.name();
1265 String entry_point_name;
1266 String module_name;
1267 _extractModuleAndEntryPointName(timeloop_call_name, module_name, entry_point_name);
1268
1269 auto it = m_module_state_list.find(module_name);
1270 if (it == m_module_state_list.end())
1271 ARCANE_FATAL("No module named '{0}' is referenced", module_name);
1272
1273 const ModuleState& module_state = it->second;
1274 if (!module_state.m_is_optional || module_state.m_is_active) {
1275 if (!module_state.m_alias.null())
1276 module_name = module_state.m_alias;
1277 StringBuilder call_alias(module_name);
1278 call_alias += ".";
1279 call_alias += entry_point_name;
1280
1281 IEntryPoint* entry_point = m_entry_point_mng->findEntryPoint(module_name, entry_point_name);
1282 log() << "Looking for entry point '" << call_alias << "'";
1283 if (!entry_point)
1284 ARCANE_FATAL("No entry point named '{0}' is referenced", call_alias);
1285
1286 // it is necessary to verify that the "where" property of the entry point is
1287 // compatible with the "where" attribute given in the time loop
1288 String ep_where = entry_point->where();
1289 OStringStream msg;
1290 msg() << "The entry point '" << call_alias << "' declared \"" << ep_where
1291 << "\" can't be in the entry point list \""
1292 << where << "\" of the time loop";
1293
1294 if (ep_where == IEntryPoint::WComputeLoop && where != ITimeLoop::WComputeLoop)
1295 ARCANE_FATAL(msg.str());
1296 if (ep_where == IEntryPoint::WRestore && where != ITimeLoop::WRestore)
1297 ARCANE_FATAL(msg.str());
1298 if (ep_where == IEntryPoint::WExit && where != ITimeLoop::WExit)
1299 ARCANE_FATAL(msg.str());
1300 if ((ep_where == IEntryPoint::WInit ||
1301 ep_where == IEntryPoint::WContinueInit ||
1302 ep_where == IEntryPoint::WStartInit) &&
1303 where != ITimeLoop::WInit)
1304 ARCANE_FATAL(msg.str());
1305
1306 entry_points.add(entry_point);
1307 }
1308 }
1309}
1310
1311/*---------------------------------------------------------------------------*/
1312/*---------------------------------------------------------------------------*/
1313
1316{
1317 // Analyzes the time loop information
1318 // 1. list of required modules
1319 for (StringCollection::Enumerator i(time_loop->requiredModulesName()); ++i;) {
1320 const String& module_name = *i;
1321 ModuleState ms(false, module_name);
1322 m_module_state_list.insert(ModuleStateMap::value_type(module_name, ms));
1323 }
1324
1325 // 2. list of optional modules
1326 for (StringCollection::Enumerator i(time_loop->optionalModulesName()); ++i;) {
1327 const String& module_name = *i;
1328 ModuleState ms(true, module_name);
1329 m_module_state_list.insert(ModuleStateMap::value_type(module_name, ms));
1330 }
1331
1332 ICaseMng* cm = m_sub_domain->caseMng();
1333 // Filling the module state list from
1334 // the data file information if it exists
1335 // (There is no data set for example when generating internal infos
1336 // of the code via the option 'arcane_all_internal').
1337 ICaseDocument* doc = cm->caseDocument();
1338 if (!doc)
1339 return;
1340
1341 XmlNode modules_node = doc->modulesElement();
1342 String ustr_module("module");
1343 String ustr_false("false");
1344 String ustr_name("name");
1345 String ustr_alias("alias");
1346 String ustr_active("active");
1347 for (XmlNode::const_iter i(modules_node); i(); ++i) {
1348 if (i->name() != ustr_module)
1349 continue;
1350 XmlNode module_node = *i;
1351 String name = module_node.attrValue(ustr_name);
1352 String alias = module_node.attrValue(ustr_alias);
1353
1354 // Checks if the module is active.
1355 XmlNode active_node = module_node.attr(ustr_active);
1356 bool active = true;
1357 if (!active_node.null())
1358 active = active_node.valueAsBoolean(true);
1359
1360 // Completes the module state list information
1361
1362 // First checks if 'name' corresponds to a module name
1363 // in the language of the data file.
1364 auto ilang = m_lang_module_factory_map.find(name);
1365 if (ilang != m_lang_module_factory_map.end())
1366 name = ilang->second->moduleName();
1367
1368 auto it = m_module_state_list.find(name);
1369 if (it == m_module_state_list.end())
1370 // Raises an exception if the module name specified in the data file
1371 // does not correspond to any registered module.
1372 ARCANE_FATAL("Error in configuring active modules: no module named '{0}' is registered.",
1373 name);
1374
1375 ModuleState& ms = it->second;
1376 ms.m_is_active = active;
1377 if (!alias.null())
1378 ms.m_alias = alias;
1379
1380 if (!ms.m_is_optional && !ms.m_is_active) {
1381 pwarning() << "The module \"" << ms.m_alias
1382 << "\" can't be declared mandatory in the time loop"
1383 << " while being inactive in the input data."
1384 << " Its activity is therefore forced. ";
1385 ms.m_is_active = true;
1386 }
1387 }
1388}
1389
1390/*---------------------------------------------------------------------------*/
1391/*---------------------------------------------------------------------------*/
1392
1394_extractModuleAndEntryPointName(const String& timeloop_call_name,
1395 String& module_name,
1396 String& entry_point_name)
1397{
1398 std::string std_timeloop_call_name(timeloop_call_name.localstr());
1399 size_t index = std_timeloop_call_name.find_first_of('.');
1400 if (index == std::string::npos) {
1401 ARCANE_FATAL("The string '{0}' is not a valid reference to an entry point (has to be of type "
1402 "'module_name.entry_point_name)",
1403 timeloop_call_name);
1404 }
1405 std::string std_module_name = std_timeloop_call_name.substr(0, index);
1406 std::string std_entry_point_name = std_timeloop_call_name.substr(index + 1);
1407 module_name = std_module_name;
1408 entry_point_name = std_entry_point_name;
1409}
1410
1411/*---------------------------------------------------------------------------*/
1412/*---------------------------------------------------------------------------*/
1413
1419{
1420 String lang;
1421 ICaseDocumentFragment* doc = m_sub_domain->caseMng()->caseDocumentFragment();
1422 if (doc)
1423 lang = doc->language();
1424 ModuleFactoryInfoCollection module_factories(subDomain()->application()->moduleFactoryInfos());
1425 m_module_factory_map.clear();
1427 for (ModuleFactoryInfoCollection::Enumerator i(module_factories); ++i;) {
1428 IModuleFactoryInfo* mfi = *i;
1429
1430 const String& module_name = mfi->moduleName();
1431 if (m_module_factory_map.find(module_name) != m_module_factory_map.end())
1432 ARCANE_FATAL("Two modules with same name '{0}'", module_name);
1433 m_module_factory_map.insert(std::make_pair(module_name, mfi));
1434 info(5) << "Registering module in factory map name=" << module_name;
1435
1436 if (!lang.null()) {
1437 const IServiceInfo* si = mfi->serviceInfo();
1438 String translated_name = si->tagName(lang);
1439 if (m_lang_module_factory_map.find(module_name) != m_lang_module_factory_map.end()) {
1440 // Just sends a warning because it will not necessarily cause a problem.
1441 warning() << "Two modules with same translated name=" << translated_name
1442 << " ignoring name=" << module_name;
1443 }
1444 else {
1445 m_lang_module_factory_map.insert(std::make_pair(translated_name, mfi));
1446 info(5) << "Registering module in lang factory map name=" << translated_name;
1447 }
1448 }
1449 }
1450}
1451
1452/*---------------------------------------------------------------------------*/
1453/*---------------------------------------------------------------------------*/
1454
1456_createModule(const String& module_name)
1457{
1458 auto x = m_module_factory_map.find(module_name);
1459 if (x != m_module_factory_map.end()) {
1460 IModuleFactoryInfo* mfi = x->second;
1461 Ref<IModule> module = mfi->createModule(m_sub_domain, m_sub_domain->defaultMeshHandle());
1462 if (module.get()) {
1463 info() << "Loading module " << module->name()
1464 << " (Version " << module->versionInfo() << ")";
1465 return true;
1466 }
1467 }
1468 return false;
1469}
1470
1471/*---------------------------------------------------------------------------*/
1472/*---------------------------------------------------------------------------*/
1473
1479{
1480 log() << "Adding the entry point `" << entry_point->module()->name() << "::" << entry_point->name() << "' to the execution";
1481
1482 String where = entry_point->where();
1483 if (where == IEntryPoint::WInit || where == IEntryPoint::WContinueInit || where == IEntryPoint::WStartInit) {
1484 m_init_entry_points.add(entry_point);
1485 }
1486 else if (where == IEntryPoint::WBuild) {
1487 m_build_entry_points.add(entry_point);
1488 }
1489 else if (where == IEntryPoint::WExit) {
1490 m_exit_entry_points.add(entry_point);
1491 }
1492 else if (where == IEntryPoint::WRestore) {
1493 m_restore_entry_points.add(entry_point);
1494 }
1495 else if (where == IEntryPoint::WOnMeshChanged) {
1496 m_on_mesh_changed_entry_points.add(entry_point);
1497 }
1498 else if (where == IEntryPoint::WOnMeshRefinement) {
1499 m_on_mesh_refinement_entry_points.add(entry_point);
1500 }
1501 else if (IEntryPoint::WComputeLoop) {
1502 m_loop_entry_points.add(entry_point);
1504 }
1505 m_used_time_loop_entry_points.add(entry_point);
1506
1507 // Since the module has a used entry point, it is activated.
1508 IModule* c = entry_point->module();
1509 c->setUsed(true);
1510 {
1511 if (std::find(m_list_execute_module.begin(), m_list_execute_module.end(), c) == m_list_execute_module.end()) {
1512 debug() << "Adding the module `" << c->name() << "' to the execution";
1513 m_list_execute_module.add(c);
1514 }
1515 }
1516}
1517
1518/*---------------------------------------------------------------------------*/
1519/*---------------------------------------------------------------------------*/
1520
1521void TimeLoopMng::
1522_dumpTimeInfos(JSONWriter& json_writer)
1523{
1524 IModuleMng* module_mng = subDomain()->moduleMng();
1525
1527
1528 Real total_exec_time = cpuTimeUsed();
1529
1530 {
1531 Real total_real_time = 0.0;
1532 Real compute_real_time = 0.0;
1533 json_writer.writeKey("EntryPoints");
1534 json_writer.beginArray();
1535 for (EntryPointCollection::Enumerator i(entry_points); ++i;) {
1536 IEntryPoint* ep = *i;
1537 Real s2 = ep->totalElapsedTime();
1538 {
1539 JSONWriter::Object jo(json_writer);
1540 json_writer.write("Name", ep->name());
1541 json_writer.write("TotalCpuTime", s2);
1542 json_writer.write("TotalElapsedTime", s2);
1543 json_writer.write("NbCall", (Int64)ep->nbCall());
1544 json_writer.write("Where", ep->where());
1545 }
1546 info(5) << "CPU_TIME where=" << ep->where() << " name=" << ep->name() << " S=" << s2;
1547 total_real_time += s2;
1548 if (ep->where() == IEntryPoint::WComputeLoop) {
1549 compute_real_time += s2;
1550 }
1551 }
1552 json_writer.endArray();
1553 info(4) << "TOTAL_REAL_TIME COMPUTE=" << compute_real_time << " TOTAL=" << total_real_time;
1554 }
1555
1556 const CommonVariables& scv = subDomain()->commonVariables();
1557 info() << "Information on the execution time";
1558 {
1559 Accelerator::IAcceleratorMng* acc_mng = m_sub_domain->acceleratorMng();
1560 if (acc_mng->isInitialized()) {
1561 Accelerator::Runner* runner = acc_mng->defaultRunner();
1562 info() << " TotalRunner (" << runner->executionPolicy() << ") = "
1563 << runner->cumulativeCommandTime() << " seconds";
1564 }
1565 }
1566 info() << " TotalElapsed = " << total_exec_time << " seconds";
1567 info() << " CumulativeElapsed = " << scv.globalElapsedTime()
1568 << " seconds (" << platform::timeToHourMinuteSecond(scv.globalElapsedTime()) << ")";
1569 info() << " T = Total time spent in the function or in the module (s)";
1570 info() << " TC = Total time spend per call (ms)";
1571 info() << " TCC = Total time spent per call and per cell (ns)";
1572 info() << " N = Number of time the function was called";
1573
1574 info() << " Use the clock time (elapsed) for the statistics";
1575
1576 std::ostringstream o;
1577 std::ios_base::fmtflags f = o.flags(std::ios::right);
1578 Integer nb_cell = 0;
1579 IMesh* mesh = subDomain()->defaultMesh();
1580 if (mesh)
1581 nb_cell = mesh->nbCell();
1582 if (nb_cell == 0)
1583 nb_cell = 1;
1584
1585 o << "\n Name T TC TCC % N\n";
1586
1587 for (ModuleCollection::Enumerator j(module_mng->modules()); ++j;) {
1588 IModule* module = *j;
1589 Real total_time_module = 0.;
1590 Real total_time_module_entry_point = 0.;
1591 for (EntryPointCollection::Enumerator i(entry_points); ++i;) {
1592 IEntryPoint* ic = *i;
1593 if (ic->module() != module)
1594 continue;
1595 Integer nb_call = ic->nbCall();
1596 if (nb_call == 0)
1597 continue;
1598 Real total_time = ic->totalElapsedTime();
1599 //if (math::isZero(total_time))
1600 //continue;
1601 const String& ep_name = ic->name();
1602 {
1603 Int64 l = ep_name.length();
1604 if (l > 36) {
1605 o.write(ep_name.localstr(), 34);
1606 o << "...";
1607 }
1608 else {
1609 o.width(37);
1610 o << ep_name;
1611 }
1612 }
1613 o.width(10);
1614 Int64 z = Convert::toInt64(total_time);
1615 o << z;
1616 Real r = (1e3 * total_time) / nb_call;
1617 if (ic->where() == IEntryPoint::WComputeLoop) {
1618 total_time_module += r;
1619 total_time_module_entry_point += total_time;
1620 }
1621 z = Convert::toInt64(r);
1622 o.width(10);
1623 o << z;
1624 r = (r * 1e6) / nb_cell;
1625 z = Convert::toInt64(r);
1626 o.width(10);
1627 o << z;
1628 //Problem on certain machines: total_exec_time = 0
1629 if (total_exec_time > 0)
1630 z = Convert::toInt64((100.0 * total_time) / total_exec_time);
1631 else
1632 z = Convert::toInt64((100.0 * total_time));
1633 o.width(5);
1634 o << z;
1635 o.width(12);
1636 o << nb_call;
1637 o << '\n';
1638 }
1639 o << "--";
1640 o.width(33);
1641 o << module->name();
1642 o << "--";
1643 o.width(10);
1644 Int64 z = Convert::toInt64(total_time_module_entry_point * 1e-3);
1645 o << z;
1646 o.width(10);
1647 z = Convert::toInt64(total_time_module);
1648 o << z;
1649 Real r = (total_time_module * 1e6) / nb_cell;
1650 z = Convert::toInt64(r);
1651 o.width(10);
1652 o << z;
1653 o << '\n';
1654 }
1655 o.flags(f);
1656
1657 info() << o.str();
1658
1659 {
1660 IParallelMng* pm = m_sub_domain->parallelMng();
1661 if (pm->isParallel()) {
1662 JSONWriter::Object jo(json_writer, "MessagePassingStats");
1663 Parallel::IStat* s = pm->stat();
1664 if (s) {
1665 s->printCollective(pm);
1666 s->dumpJSON(json_writer);
1667 }
1668 }
1669 }
1670 {
1671 JSONWriter::Object jo(json_writer, "VariablesStats");
1672 m_sub_domain->variableMng()->dumpStatsJSON(json_writer);
1673 }
1674 {
1675 JSONWriter::Object jo(json_writer, "TimeStats");
1676 m_sub_domain->timeStats()->dumpStatsJSON(json_writer);
1677 }
1678 {
1679 IProfilingService* ps = platform::getProfilingService();
1680 if (ps) {
1681 JSONWriter::Object jo(json_writer, "Profiling");
1682 ps->dumpJSON(json_writer);
1683 }
1684 }
1685
1686 Item::dumpStats(traceMng());
1687}
1688
1689/*---------------------------------------------------------------------------*/
1690/*---------------------------------------------------------------------------*/
1691
1693cpuTimeUsed() const
1694{
1695 EntryPointCollection entry_points = m_entry_point_mng->entryPoints();
1696 Real total_elapsed_time = 0.0;
1697 for (EntryPointCollection::Enumerator i(entry_points); ++i;) {
1698 Real s1 = (*i)->totalElapsedTime();
1699 total_elapsed_time += s1;
1700 }
1701 return total_elapsed_time;
1702}
1703
1704/*---------------------------------------------------------------------------*/
1705/*---------------------------------------------------------------------------*/
1706
1709{
1710 if (!m_backward_mng)
1711 _createOwnDefaultBackwardMng();
1712 return m_backward_mng->isLocked();
1713}
1714
1715/*---------------------------------------------------------------------------*/
1716/*---------------------------------------------------------------------------*/
1717
1719goBackward()
1720{
1721 ITraceMng* msg = traceMng();
1722 Trace::Setter mci(msg, m_message_class_name);
1723
1724 if (!m_backward_mng)
1725 _createOwnDefaultBackwardMng();
1726
1727 m_backward_mng->goBackward();
1728}
1729
1730/*---------------------------------------------------------------------------*/
1731/*---------------------------------------------------------------------------*/
1732
1734timeLoopsName(StringCollection& names) const
1735{
1736 for (ConstIterT<TimeLoopMap> i(m_time_loop_list); i(); ++i)
1737 names.add(i->first);
1738}
1739
1740/*---------------------------------------------------------------------------*/
1741/*---------------------------------------------------------------------------*/
1742
1744timeLoops(TimeLoopCollection& time_loops) const
1745{
1746 for (ConstIterT<TimeLoopMap> i(m_time_loop_list); i(); ++i)
1747 time_loops.add(i->second);
1748}
1749
1750/*---------------------------------------------------------------------------*/
1751/*---------------------------------------------------------------------------*/
1752
1754createTimeLoop(const String& name)
1755{
1756 IApplication* sm = m_sub_domain->application();
1757 return sm->mainFactory()->createTimeLoop(sm, name);
1758}
1759
1760/*---------------------------------------------------------------------------*/
1761/*---------------------------------------------------------------------------*/
1762
1765{
1766 m_stop_reason = reason;
1767}
1768
1769/*---------------------------------------------------------------------------*/
1770/*---------------------------------------------------------------------------*/
1771
1773stopComputeLoop(bool is_final_time, bool has_error)
1774{
1775 m_stop_time_loop = true;
1776 m_stop_has_error = has_error;
1777 if (is_final_time)
1778 m_final_time_reached = true;
1779 if (has_error)
1780 m_stop_reason = eTimeLoopStopReason::Error;
1781 else if (is_final_time)
1783 // If m_stop_reason has not yet been specified, indicate that there is no
1784 // special reason
1785 if (m_stop_reason == eTimeLoopStopReason::NoStop)
1786 m_stop_reason = eTimeLoopStopReason::NoReason;
1787}
1788
1789/*---------------------------------------------------------------------------*/
1790/*---------------------------------------------------------------------------*/
1791
1794{
1795 if (!m_backward_mng)
1796 _createOwnDefaultBackwardMng();
1797
1798 if (m_backward_mng->isLocked() || m_backward_mng->isBackwardEnabled()) {
1799 info() << "Repartioning required but inactive due to a backward process active";
1800 return;
1801 }
1802 m_mesh_partitioner.add(mesh_partitioner);
1803}
1804
1805/*---------------------------------------------------------------------------*/
1806/*---------------------------------------------------------------------------*/
1807
1809doComputeLoop(Integer max_loop)
1810{
1811 m_nb_loop = 0;
1812 bool is_end = false;
1813 bool is_end_by_max_loop = false;
1814 int ret_val = 0;
1815 //m_alarm_timer_value = 0;
1816 //pwarning() << "Force the alarm_timer_value to zero";
1817 if (m_alarm_timer_value > 0) {
1818 info() << "Set the timeout before alarm at " << m_alarm_timer_value << " seconds";
1819 }
1820
1821 // Allocation of a default backward manager
1822 if (!m_backward_mng)
1823 _createOwnDefaultBackwardMng();
1824
1826 bool want_specific_profiling = false;
1827 // Checks if specific profiling is requested. In this case,
1828 // modules and services manage the profiling themselves, and therefore
1829 // profiling is not automatically started at the beginning of the
1830 // computation loop
1831 if (!platform::getEnvironmentVariable("ARCANE_SPECIFIC_PROFILING").null()) {
1832 info() << "Specific profiling activated";
1833 want_specific_profiling = true;
1834 }
1835
1836 {
1837 // NOTE: arcaneGlobalMemoryInfo() can change during computation,
1838 // so it must be retrieved every time it is needed.
1839 IMemoryInfo* mem_info = arcaneGlobalMemoryInfo();
1840 String s = platform::getEnvironmentVariable("ARCANE_CHECK_MEMORY_BLOCK_SIZE_ITERATION");
1841 if (!s.null()) {
1842 Int64 block_size = 0;
1843 bool is_bad = builtInGetValue(block_size, s);
1844 if (!is_bad && block_size > 2) {
1845 info() << "Set Memory StackTraceMinAllocSize to " << block_size;
1846 mem_info->setStackTraceMinAllocSize(block_size);
1847 }
1848 }
1849 }
1850
1851 // Start message passing profiling if applicable
1852 if (m_msg_pass_prof_srv.get())
1853 m_msg_pass_prof_srv->startProfiling();
1854
1855 try {
1856 if (ps) {
1857 if (!ps->isInitialized())
1858 ps->initialize();
1859 ps->reset();
1860 }
1861 Item::resetStats();
1862 // Deactivate profiling if specific request
1863 if (want_specific_profiling)
1864 ps = nullptr;
1865 ProfilingSentryWithInitialize ps_sentry(ps);
1866 if (!m_specific_entry_point_name.null()) {
1867 _callSpecificEntryPoint();
1868 is_end = true;
1869 }
1870 while (!is_end) {
1871 if (max_loop != 0 && m_nb_loop >= max_loop) {
1872 info() << "===================================================";
1873 info() << "====== MAXIMUM NUMBER OF ITERATION REACHED =======";
1874 info() << "===================================================";
1875 is_end_by_max_loop = true;
1877 stopComputeLoop(false, false);
1878 break;
1879 }
1880 // Indicate that we will stop by maximum number of iterations
1881 if (max_loop != 0 && (1 + m_nb_loop) >= max_loop) {
1883 }
1884 ret_val = doOneIteration();
1885 IMemoryInfo* mem_info = arcaneGlobalMemoryInfo();
1886 if (mem_info && mem_info->isCollecting()) {
1887 mem_info->endCollect();
1889 mem_info->setIteration(iteration);
1890
1891 std::ostringstream ostr;
1892 if (iteration > 0)
1893 mem_info->printAllocatedMemory(ostr, iteration - 1);
1894 if (iteration > 1)
1895 mem_info->printAllocatedMemory(ostr, iteration - 2);
1896 if (iteration > 4)
1897 mem_info->printAllocatedMemory(ostr, iteration - 5);
1898 info() << "ITERATION_MemoryInfo: " << ostr.str();
1899 mem_info->beginCollect();
1900 }
1902 if (ret_val != 0)
1903 is_end = true;
1904 ++m_nb_loop;
1905 }
1906 }
1907 catch (const TimeoutException& ex) {
1908 if (m_msg_pass_prof_srv.get())
1909 m_msg_pass_prof_srv->stopProfiling();
1911 pinfo() << "TIMEOUT " << Trace::Width(8) << pm->commRank() << "_RANK Infos:" << ex.additionalInfo();
1912 traceMng()->flush();
1913 // Wait for all processors to send the signal and display the
1914 // previous message
1915 platform::sleep(40);
1916 throw;
1917 }
1918 if (m_verification_only_at_exit) {
1919 info() << "Doing verification at exit";
1920 doVerification("AtExit");
1921 }
1922 {
1924 if (ps2)
1925 ps2->printInfos(true);
1926 }
1927 if (m_msg_pass_prof_srv.get())
1928 m_msg_pass_prof_srv->stopProfiling();
1929 if (IItemEnumeratorTracer::singleton())
1930 IItemEnumeratorTracer::singleton()->dumpStats();
1931 info() << "End of compute loop: reason=" << (int)m_stop_reason;
1932 if (is_end_by_max_loop)
1933 return 2;
1934 if (m_final_time_reached)
1935 return 1;
1936 if (ret_val < 0) {
1937 return ret_val;
1938 }
1939 return 0;
1940}
1941
1942/*---------------------------------------------------------------------------*/
1943/*---------------------------------------------------------------------------*/
1944
1945void TimeLoopMng::
1946_resetTimer() const
1947{
1948 if (m_alarm_timer_value > 0)
1949 platform::resetAlarmTimer(m_alarm_timer_value);
1950}
1951
1952/*---------------------------------------------------------------------------*/
1953/*---------------------------------------------------------------------------*/
1954
1955} // End namespace Arcane
1956
1957/*---------------------------------------------------------------------------*/
1958/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer count() const
Number of elements in the collection.
bool empty() const
True if the collection is empty.
VariableScalarInt32 m_global_iteration
Current iteration.
Real globalTime() const
Current time.
Int32 globalIteration() const
Current iteration number.
const String & additionalInfo() const
Returns the additional information.
Exception to request a backward step in the time loop.
Application interface.
virtual IMainFactory * mainFactory() const =0
Main factory.
virtual String userName() const =0
User name.
Interface managing backward strategies.
virtual ITraceMng * traceMng() const =0
Trace manager.
Interface of a part of a dataset.
virtual String language() const =0
Language used in the dataset.
Interface of a class managing an XML document of the dataset.
virtual XmlNode modulesElement()=0
Returns the element containing the module descriptions.
Interface of a dataset function.
virtual void value(Real param, Real &v) const =0
Value v of the option for parameter param.
Case manager interface.
Definition ICaseMng.h:57
virtual CaseOptionsCollection blocks() const =0
Collection of option blocks.
virtual ICaseDocument * caseDocument()=0
XML document of the dataset (can be null if no dataset).
Interface for a list of data set options.
virtual ICaseFunction * activateFunction()=0
Function indicating the activation status of the option.
virtual IModule * caseModule() const =0
Returns the associated module or nullptr if none exists.
virtual void merge(const IConfiguration *c)=0
Merges this configuration with configuration c.
Interface for the entry point manager.
virtual IEntryPoint * findEntryPoint(const String &s)=0
Entry point by name s.
virtual EntryPointCollection entryPoints()=0
List of entry points.
Interface of a module entry point.
Definition IEntryPoint.h:35
virtual void executeEntryPoint()=0
Calls the entry point.
virtual Real totalElapsedTime() const =0
Elapsed execution time (clock time) in this entry point (in milliseconds).
static const char *const WComputeLoop
called during the calculation loop
Definition IEntryPoint.h:43
static const char *const WBuild
called for module construction
Definition IEntryPoint.h:45
static const char *const WStartInit
called during new case initialization
Definition IEntryPoint.h:51
static const char *const WRestore
called to restore variables during a rollback
Definition IEntryPoint.h:53
virtual Integer nbCall() const =0
Returns the number of times the entry point has been executed.
static const char *const WOnMeshRefinement
called after mesh refinement
Definition IEntryPoint.h:57
@ PAutoLoadEnd
Automatically loaded at the end. This means that a module possessing an entry point with this propert...
Definition IEntryPoint.h:81
@ PAutoLoadBegin
Automatically loaded at the beginning. This means that a module possessing an entry point with this p...
Definition IEntryPoint.h:74
virtual int property() const =0
Returns the properties of the entry point.
static const char *const WOnMeshChanged
called after a mesh change
Definition IEntryPoint.h:55
static const char *const WContinueInit
called during continuation initialization
Definition IEntryPoint.h:49
virtual String where() const =0
Returns where the entry point is called.
static const char *const WInit
called during initialization
Definition IEntryPoint.h:47
virtual IModule * module() const =0
Returns the module associated with the entry point.
virtual String name() const =0
Returns the name of the entry point.
Interface of an entity family.
Definition IItemFamily.h:83
virtual IVariableSynchronizer * allItemsSynchronizer()=0
Synchronizer on all entities of the family.
virtual IServiceLoader * createServiceLoader()=0
Creates an instance of the service loader.
virtual ITimeLoop * createTimeLoop(IApplication *sm, const String &name)=0
Creates a time loop named name.
Interface for a memory usage information collector.
Definition IMemoryInfo.h:79
virtual void setIteration(Integer iteration)=0
Sets the current iteration number.
virtual void setStackTraceMinAllocSize(Int64 alloc_size)=0
Sets the minimum size of allocations whose call stack is traced.
virtual Integer nbCell()=0
Number of mesh cells.
Interface of a mesh partitioner.
virtual void prepareForDump()=0
Prepares the instance for dumping.
Information about a module factory.
virtual String moduleName() const =0
Name of the module created by this factory.
virtual Ref< IModule > createModule(ISubDomain *parent, const MeshHandle &mesh_handle)=0
Creates a module.
virtual const IServiceInfo * serviceInfo() const =0
Information about the module that can be created by this factory.
Module manager interface.
Definition IModuleMng.h:39
virtual ModuleCollection modules() const =0
List of modules.
Interface of a module.
Definition IModule.h:40
virtual void setUsed(bool v)=0
Indicates whether a module is used or not (internal).
virtual String name() const =0
Module name.
virtual bool disabled() const =0
true if the module is disabled
virtual void setDisabled(bool v)=0
Temporarily activates or deactivates the module (internal).
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual IParallelReplication * replication() const =0
Replication information.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
virtual bool hasReplication() const =0
Indicates if replication is active.
Interface of a profiling service.
virtual bool isInitialized() const
Indicates if initialize() has already been called.
virtual void initialize()=0
Initializes the profiling service.
virtual void reset()=0
Resets the counters.
virtual void printInfos(bool dump_file=false)=0
Displays profiling information.
Interface for service or module information.
virtual String tagName(const String &lang) const =0
Name of the service XML element for the language lang. If lang is null, returns the default name.
Service loading interface.
virtual bool loadSingletonService(ISubDomain *sd, const String &name)=0
Loads the subdomain singleton service with name name.
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual IModuleMng * moduleMng()=0
Returns the module manager.
virtual const CommonVariables & commonVariables() const =0
Information on standard variables.
virtual IMesh * defaultMesh()=0
Default mesh.
virtual ITimeStats * timeStats() const =0
Execution time statistics.
virtual IApplication * application()=0
Application.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual const IConfiguration * configuration() const =0
Associated configuration.
virtual IVariableMng * variableMng()=0
Returns the variable manager.
virtual IMainFactory * mainFactory()=0
Main factory.
virtual ICaseMng * caseMng()=0
Returns the dataset manager.
Interface for the time loop manager.
Interface of a time loop.
Definition ITimeLoop.h:33
static const char * WRestore
called to restore variables during a rollback
Definition ITimeLoop.h:47
virtual StringCollection optionalModulesName() const =0
List of names of optional modules.
static const char * WOnMeshChanged
called after a mesh change
Definition ITimeLoop.h:49
static const char * WExit
called upon termination of the code.
Definition ITimeLoop.h:53
virtual StringCollection requiredModulesName() const =0
List of names of required modules.
virtual TimeLoopSingletonServiceInfoCollection singletonServices() const =0
List of singleton services.
static const char * WOnMeshRefinement
called after mesh refinement
Definition ITimeLoop.h:51
static const char * WBuild
called when reading the dataset
Definition ITimeLoop.h:43
static const char * WComputeLoop
called during the calculation loop
Definition ITimeLoop.h:41
static const char * WInit
called during initialization, initialization of a restart, or a new case
Definition ITimeLoop.h:45
virtual String name() const =0
Name of the time loop.
virtual void dumpCurrentStats(const String &name)=0
Displays statistics for an action.
virtual void notifyNewIterationLoop()=0
Notifies that a new iteration of the calculation loop begins.
virtual void flush()=0
Flushes all streams.
virtual TraceMessage plog()=0
Stream for a parallel log message.
virtual IVariableSynchronizerMng * synchronizerMng() const =0
Interface of the variable synchronization manager.
virtual void flushPendingStats()=0
Processes pending statistics.
Interface of a variable synchronization service.
virtual Int32ConstArrayView communicatingRanks()=0
Ranks of subdomains with which communication occurs.
@ PNoReplicaSync
Indicates that the variable does not necessarily have the same value across replicas.
Definition IVariable.h:147
@ PNoNeedSync
Indicates that the variable is not necessarily synchronized.
Definition IVariable.h:70
Output stream linked to a String.
List of observables.
Class allowing automatic start and stop of a service.
T * get() const
Returns the object referenced by the instance.
Definition Ptr.h:122
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
Utility class to find one or more services implementing the InterfaceType interface.
Unicode character string constructor.
bool null() const
Returns true if the string is null.
Definition String.cc:306
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
bool empty() const
True if the string is empty (null or "").
Definition String.cc:317
Info about a time loop entry point.
Time loop manager.
bool finalTimeReached() const override
Returns true if the final time has been reached.
IObservable * observable(eTimeLoopEventType type) override
Observable on the instance.
ModuleFactoryMap m_module_factory_map
State of all referenced modules.
TimeLoopMap m_time_loop_list
List of time loops.
void registerActionMeshPartition(IMeshPartitionerBase *mesh_partitioner) override
Schedules a mesh partitioning using the partition tool mesh_partitioner.
EntryPointCollection usedTimeLoopEntryPoints() override
List of all entry points for the current time loop.
void _processEntryPoints(EntryPointList &entry_points, const TimeLoopEntryPointInfoCollection &entry_points_info, const char *where)
Adds the entry points proposed in entry_points_info to the list entry_points.
@ VerifSameReplica
Checks that variables are synchronized.
@ VerifWrite
Indicates that values are generated for checking.
@ VerifNone
Indicates that no checks are performed.
@ VerifRead
Indicates that values are reread and checked.
ITimeLoop * createTimeLoop(const String &name) override
Creates a time loop named name.
std::map< String, ITimeLoop * > TimeLoopMap
List of time loops.
EntryPointList m_exit_entry_points
List of entry points to execute upon termination.
EntryPointCollection loopEntryPoints() override
Returns the list of 'ComputeLoop' type entry points in the time loop.
ITimeLoop * usedTimeLoop() const override
Returns the time loop used.
EntryPointList m_on_mesh_changed_entry_points
List of entry points to execute after a mesh change.
ITimeLoop * m_default_time_loop
Default time loop.
void doVerification(const String &name) override
Performs a verification.
void stopComputeLoop(bool is_final_time, bool has_error) override
Indicates that the compute loop must stop.
void execInitEntryPoints(bool is_continue) override
Executes the initialization entry points.
std::map< String, ModuleState > ModuleStateMap
List of module states.
IEntryPoint * nextEntryPoint() override
Returns the next function to call.
bool _createModule(const String &module_name)
Creates a module from its name.
eTimeLoopStopReason stopReason() const override
Reason for stopping the code.
void doExecNextEntryPoint(bool &is_last) override
void execExitEntryPoints() override
Executes the exit entry points.
static void _extractModuleAndEntryPointName(const String &timeloop_call_name, String &module_name, String &entry_point_name)
EntryPointList m_build_entry_points
List of entry points to execute during build.
EntryPointList m_used_time_loop_entry_points
List of all entry points of the used time loop.
Integer m_current_entry_point
Next entry point to execute.
int doOneIteration() override
Starts the execution of a compute loop iteration.
void execOnMeshRefinementEntryPoints() override
Executes the entry points after refinement.
ISubDomain * subDomain() const override
< Returns the sub-domain manager
std::map< String, IModuleFactoryInfo * > ModuleFactoryMap
List of module factories indexed by their name.
bool m_verification_at_entry_point
If true, performs checks at every entry point, otherwise only at the end of the iteration.
void timeLoops(TimeLoopCollection &time_loops) const override
Returns in time_loops the list of time loops.
EntryPointList m_restore_entry_points
List of entry points to execute during a backward step.
EntryPointList m_on_mesh_refinement_entry_points
List of entry points to execute after a refinement.
ISubDomain * m_sub_domain
Sub-domain manager.
ModuleFactoryMap m_lang_module_factory_map
List of module factories.
Integer nbLoop() const override
Number of compute loops performed.
bool isDoingBackward() override
True if currently in a backward step.
int doComputeLoop(Integer max_loop) override
Executes the compute loop.
void timeLoopsName(StringCollection &names) const override
Returns in names the list of time loop names.
void goBackward() override
Performs a backward step.
void setStopReason(eTimeLoopStopReason reason) override
Positions the reason for stopping the code.
EntryPointList m_loop_entry_points
List of entry points to execute.
IEntryPointMng * m_entry_point_mng
Entry point manager.
EntryPointList m_init_entry_points
List of entry points to execute during initialization.
String m_specific_entry_point_name
For testing, specific entry point to call.
ModuleList m_list_execute_module
List of modules to execute.
Real cpuTimeUsed() const override
Returns the CPU time used in seconds.
void execBuildEntryPoints() override
Executes the build entry points.
void setBackwardSavePeriod(Integer n) override
Positions the period between two saves for backward step. If this value is null, backward step is dis...
IEntryPoint * m_current_entry_point_ptr
Currently executing entry point.
IBackwardMng * m_backward_mng
Backward manager;.
ITimeLoop * m_used_time_loop
Used time loop.
void setUsedTimeLoop(const String &name) override
Positions the time loop to be executed. Selects the time loop named name as the one to be executed....
eVerifType m_verif_type
Verification type.
void _fillModuleStateMap(ITimeLoop *time_loop)
void _doMeshPartition()
Performs a mesh partitioning.
void execOnMeshChangedEntryPoints() override
Executes the entry points after load balancing.
void _addExecuteEntryPoint(IEntryPoint *)
Adds an entry point to execute.
IEntryPoint * currentEntryPoint() override
Returns the entry point currently being executed or 0 if there is none.
void _fillModuleFactoryMap()
Fills m_module_factory_map with the list of available factories.
void registerTimeLoop(ITimeLoop *timeloop) override
Registration and selection of the time loop.
Ref< IVerifierService > m_verifier_service
List of module factories in the data file language.
String m_verif_path
Save/read directory for verifications.
void setVerificationActive(bool is_active) override
Positions the state of the verification mode.
Info of a time loop singleton service.
Positions the name of the currently executing action.
Definition Timer.h:119
Sentinel for the timer. The sentinel associated with a timer allows it to be triggered upon its const...
Definition Timer.h:90
Management of a timer.
Definition Timer.h:63
@ TimerReal
Timer using real time.
Definition Timer.h:77
Real lastActivationTime() const
Returns the time (in seconds) spent during the last activation of the timer.
Definition Timer.h:243
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage pinfo() const
Flow for a parallel information message.
TraceMessage logdate() const
Flow for a log message preceded by the date.
TraceMessage log() const
Flow for a log message.
TraceMessage info() const
Flow for an information message.
TraceMessage warning() const
Flow for a warning message.
TraceMessage plog() const
Flow for a log message.
ITraceMng * traceMng() const
Trace manager.
TraceMessage pwarning() const
Formatting the stream by length.
1D data vector with value semantics (STL style).
Arguments for VariableComparer methods.
void setMaxPrint(Int32 v)
Sets the number of errors to display in the listing.
Class to perform comparisons between variables.
VariableComparerResults apply(IVariable *var, const VariableComparerArgs &compare_args)
Applies the comparison compare_args to the variable var.
VariableComparerArgs buildForCheckIfSync()
Creates a comparison to verify that a variable is synchronized.
Node of a DOM tree.
Definition XmlNode.h:51
XmlNode attr(const String &name, bool throw_exception=false) const
Returns the attribute of name name.
Definition XmlNode.cc:257
String attrValue(const String &name, bool throw_exception=false) const
Value of attribute name.
Definition XmlNode.cc:234
bool null() const
True if the node is null.
Definition XmlNode.h:303
ConstIterT< XmlNode > const_iter
Type of a constant iterator over the entire array.
Definition XmlNode.h:76
bool valueAsBoolean(bool throw_exception=false) const
Node value converted to boolean.
Definition XmlNode.cc:421
VariableRefScalarT< Integer > VariableScalarInteger
Scalar variable of integer type.
Int64 toInt64(Real r)
Converts a Real to Int64.
String timeToHourMinuteSecond(Real t)
Returns time in hours, minutes, and seconds format.
IProfilingService * getProfilingService()
Service used to obtain profiling information.
void resetAlarmTimer(Integer nb_second)
Resets the alarm timer to nb_second.
bool recursiveCreateDirectory(const String &dir_name)
Create a directory.
void sleep(Integer nb_second)
Puts the process to sleep for nb_second seconds.
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
@ SB_AllowNull
Allows the service to be absent.
eTimeLoopStopReason
Reason for stopping the code.
@ MaxIterationReached
Stop because maximum number of iterations specified was reached.
@ NoStop
Indicates that the code is not yet in stop mode.
@ FinalTimeReached
Stop because final time was reached.
@ NoReason
No specific reason.
@ Error
Stop due to an error.
std::int64_t Int64
Signed integer type of 64 bits.
eVariableComparerComputeDifferenceMethod
Method used to calculate the difference between two values v1 and v2.
Int32 Integer
Type representing an integer.
Collection< String > StringCollection
Collection of strings.
Definition UtilsTypes.h:506
List< IModule * > ModuleList
Array of modules.
List< IEntryPoint * > EntryPointList
Array of entry points.
Collection< ICaseOptions * > CaseOptionsCollection
Collection of dataset options.
Collection< ITimeLoop * > TimeLoopCollection
Collection of time loops.
Collection< IModuleFactoryInfo * > ModuleFactoryInfoCollection
Collection of module factory information.
double Real
Type representing a real number.
Collection< IEntryPoint * > EntryPointCollection
Collection of entry points.
@ DT_String
UTF-8 character string data type.
Definition DataTypes.h:47