Arcane  v3.16.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TimeLoopMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* Gestionnaire de la boucle en temps. */
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/*---------------------------------------------------------------------------*/
97class TimeLoopMng
98: public TraceAccessor
99, public ITimeLoopMng
100{
101 public:
102
103 struct ModuleState
104 {
105 ModuleState(bool is_optional, const String & alias)
106 : m_is_active(false), m_is_optional(is_optional), m_alias(alias) { }
107
108 bool m_is_active;
109 bool m_is_optional;
110 String m_alias;
111 };
120
122 typedef std::map<String,ModuleState> ModuleStateMap;
124 typedef std::map<String,ITimeLoop*> TimeLoopMap;
126 typedef std::map<String,IModuleFactoryInfo*> ModuleFactoryMap;
127
128 public:
129
130 explicit TimeLoopMng(ISubDomain* sd);
131 ~TimeLoopMng() override;
132
133 public:
134
135 void build() override;
136
137 ISubDomain* subDomain() const override { return m_sub_domain; }
138
139 void execExitEntryPoints() override;
140 void execBuildEntryPoints() override;
141 void execInitEntryPoints(bool is_continue) override;
142 void stopComputeLoop(bool is_final_time,bool has_error) override;
143 bool finalTimeReached() const override { return m_final_time_reached; }
144 Real cpuTimeUsed() const override;
145
148
149 void registerTimeLoop(ITimeLoop* timeloop) override;
150 void setUsedTimeLoop(const String& name) override;
151
152 ITimeLoop* usedTimeLoop() const override { return m_used_time_loop; }
153
154 void doExecNextEntryPoint(bool & is_last) override;
155 IEntryPoint* nextEntryPoint() override;
156
158
159 int doOneIteration() override;
160
161 void setBackwardMng(IBackwardMng* backward_mng) override;
162 // Attention, peut renvoyer NULL
163 IBackwardMng* getBackwardMng() const override { return m_backward_mng;}
164
165 void goBackward() override;
166 bool isDoingBackward() override;
168 {
169 if (!m_backward_mng)
170 _createOwnDefaultBackwardMng();
171 m_backward_mng->setSavePeriod(n);
172 }
173
174 void setVerificationActive(bool is_active) override { m_verification_active = is_active; }
175 void doVerification(const String& name) override;
176
177 void registerActionMeshPartition(IMeshPartitionerBase* mesh_partitioner) override;
178
179 void timeLoopsName(StringCollection & names) const override;
180 void timeLoops(TimeLoopCollection & time_loops) const override;
181 ITimeLoop * createTimeLoop(const String & name) override;
182
183 int doComputeLoop(Integer max_loop) override;
184 Integer nbLoop() const override { return m_nb_loop; }
185
186 void setStopReason(eTimeLoopStopReason reason) override;
187 eTimeLoopStopReason stopReason() const override { return m_stop_reason; }
188
189 public:
190
191 void execRestoreEntryPoints();
192 void execOnMeshChangedEntryPoints() override;
193 void execOnMeshRefinementEntryPoints() override;
194
195 ITraceMng* traceMng() { return m_sub_domain->traceMng(); }
196
197 IObservable* observable(eTimeLoopEventType type) override
198 {
199 return m_observables[type];
200 }
201
202 protected:
203
207 bool _createModule(const String & module_name);
209
210 void _processEntryPoints(EntryPointList& entry_points,
211 const TimeLoopEntryPointInfoCollection& entry_points_info,
212 const char* where);
217 void _fillModuleStateMap(ITimeLoop* time_loop);
218
223 static void _extractModuleAndEntryPointName(const String & timeloop_call_name,
224 String& module_name,String& entry_point_name);
225
226 private:
227
230
233
236
239
242
245
248
251
254
257
260
263
265
267
269
270 bool m_stop_time_loop;
271 bool m_stop_has_error;
272 bool m_final_time_reached;
273
275
277 bool m_verif_same_parallel;
279 bool m_verification_active;
282 bool m_verification_only_at_exit = false;
284
286 bool m_my_own_backward_mng;
287
288 ModuleStateMap m_module_state_list;
289
292
294 UniqueArray<IMeshPartitionerBase*> m_mesh_partitioner;
295 String m_message_class_name;
296 Integer m_alarm_timer_value;
297 Integer m_nb_loop;
298
300
301 eTimeLoopStopReason m_stop_reason;
302
303 // Service de message passing profiling
304 Ref<IMessagePassingProfilingService> m_msg_pass_prof_srv;
305
308
309 private:
310
311 void _execOneEntryPoint(IEntryPoint* ic, Integer index_value = 0, bool do_verif = false);
312 void _dumpTimeInfos(JSONWriter& json_writer);
313 void _resetTimer() const;
314 void _checkVerif(const String& entry_point_name,Integer index,bool do_verif);
315 void _checkVerifSameOnAllReplica(const String& entry_point_name);
316 void _createOwnDefaultBackwardMng();
317 void _doMeshPartition();
319 void _createSingletonServices(IServiceLoader* service_loader);
320 void _callSpecificEntryPoint();
321};
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
326extern "C++" ITimeLoopMng*
327arcaneCreateTimeLoopMng(ISubDomain * mng)
328{
329 auto* tm = new TimeLoopMng(mng);
330 return tm;
331}
332
333/*---------------------------------------------------------------------------*/
334/*---------------------------------------------------------------------------*/
335
336TimeLoopMng::
337TimeLoopMng(ISubDomain* sd)
338: TraceAccessor(sd->traceMng())
339, m_sub_domain(sd)
340, m_entry_point_mng(m_sub_domain->entryPointMng())
341, m_default_time_loop(nullptr)
342, m_used_time_loop(nullptr)
343, m_current_entry_point_ptr(nullptr)
344, m_stop_time_loop(false)
345, m_stop_has_error(false)
346, m_final_time_reached(false)
347, m_current_entry_point(0)
348, m_verif_type(VerifNone)
349, m_verif_same_parallel(false)
350, m_verif_path(".")
351, m_verification_active(false)
352, m_verification_at_entry_point(false)
353, m_backward_mng(nullptr)
354, m_my_own_backward_mng(false)
355, m_message_class_name("TimeLoopMng")
356, m_alarm_timer_value(0)
357, m_nb_loop(0)
358, m_stop_reason(eTimeLoopStopReason::NoStop)
359{
360 {
361 String s = platform::getEnvironmentVariable("ARCANE_LISTENER_TIMEOUT");
362 if (!s.null()){
363 Integer v = 0;
364 if (!builtInGetValue(v,s))
365 if (v>0)
366 m_alarm_timer_value = v;
367 }
368 }
369 {
370 String s = platform::getEnvironmentVariable("ARCANE_VERIF_PARALLEL");
371 if (!s.null())
372 m_verif_same_parallel = true;
373 }
374
375 m_observables.add(eTimeLoopEventType::BeginEntryPoint);
376 m_observables.add(eTimeLoopEventType::EndEntryPoint);
377 m_observables.add(eTimeLoopEventType::BeginIteration);
378 m_observables.add(eTimeLoopEventType::EndIteration);
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384TimeLoopMng::
385~TimeLoopMng()
386{
387 for( ConstIterT<TimeLoopMap> i(m_time_loop_list); i(); ++i){
388 ITimeLoop * tm = i->second;
389 delete tm;
390 }
391
392 if (m_my_own_backward_mng)
393 delete m_backward_mng;
394}
395
396/*---------------------------------------------------------------------------*/
397/*---------------------------------------------------------------------------*/
398
399void TimeLoopMng::
400build()
401{
402 // Créé en enregistre une boucle par défaut.
403 ITimeLoop * tm = createTimeLoop(String("ArcaneEmptyLoop"));
406
407 {
408 String verif_env = platform::getEnvironmentVariable("STDENV_VERIF");
409 if (verif_env=="READ"){
411 info() << "Checking in read mode";
412 }
413 if (verif_env=="WRITE"){
415 info() << "Checking in write mode";
416 }
417 if (verif_env=="CHECKSYNC"){
418 m_verif_type = VerifSync;
419 info() << "Checking synchronizations";
420 }
421 if (verif_env=="CHECKREPLICA"){
423 info() << "Checking variables values between replica";
424 }
426 m_verification_active = true;
427 }
428
429 {
430 String s = platform::getEnvironmentVariable("STDENV_VERIF_DIFF_METHOD");
431 if (!s.null()){
432 if (s=="RELATIVE"){
434 info() << "Using 'Relative' method to compute difference of variable values";
435 }
436 if (s=="LOCALNORMMAX"){
438 info() << "Using 'LocalNormMax' method to compute difference of variable values";
439 }
440 }
441 }
442 {
443 String s = platform::getEnvironmentVariable("STDENV_VERIF_ENTRYPOINT");
444 if (!s.null()){
446 info() << "Do verification at each entry point";
447 }
448 }
449 {
450 String s = platform::getEnvironmentVariable("STDENV_VERIF_ONLY_AT_EXIT");
451 if (s=="1" || s=="true" || s=="TRUE"){
452 m_verification_only_at_exit = true;
453 info() << "Do verification only at exit";
454 }
455 }
456 // Regarde si on n'exécute qu'un seul point d'entrée au lieu de la boucle
457 // en temps. Cela est utilisé uniquement pour des tests
458 {
459 String s = platform::getEnvironmentVariable("ARCANE_CALL_SPECIFIC_ENTRY_POINT");
460 if (!s.null()){
462 info() << "Use specific entry point: " << s;
463 }
464 }
465
466 //
467 if (m_verification_active){
468 m_verif_path = platform::getEnvironmentVariable("STDENV_VERIF_PATH");
469 if (m_verif_path.null()){
470 String user_name = subDomain()->application()->userName();
471 m_verif_path = "/tmp/" + user_name + "/verif";
472 //m_verif_path += user_name;
473 //m_verif_path += "/verif";
474 }
475 }
477 if (subDomain()->parallelMng()->isMasterIO()){
478 info() << "Creating directory '"<< m_verif_path << "' for checking";
480 }
481 }
482
483 // Creation du service de "message passing profiling" le cas echeant
484 {
485 String msg_pass_prof_str = platform::getEnvironmentVariable("ARCANE_MESSAGE_PASSING_PROFILING");
486 if (!msg_pass_prof_str.null()) {
487 String service_name;
488 // TODO: ne pas faire de if mais utiliser directement le nom spécifié par la
489 // variable d'environnement.
490 if (msg_pass_prof_str == "JSON") {
491 service_name = "JsonMessagePassingProfiling";
492 } else if (msg_pass_prof_str == "OTF2") {
493 service_name = "Otf2MessagePassingProfiling";
494 }
495 ServiceBuilder<IMessagePassingProfilingService> srv(this->subDomain());
496 m_msg_pass_prof_srv = srv.createReference(service_name ,SB_AllowNull);
497 }
498 }
499}
500
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504void TimeLoopMng::
505_createOwnDefaultBackwardMng()
506{
507 m_backward_mng = new DefaultBackwardMng(traceMng(),subDomain());
508 m_backward_mng->init();
509 m_my_own_backward_mng = true;
510}
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
515void TimeLoopMng::
516setBackwardMng(IBackwardMng* backward_mng)
517{
518 ARCANE_ASSERT((backward_mng),("IBackwardMng pointer null"));
519
520 if (m_backward_mng){
521 // Détruit l'ancien gestionnaire si c'est nous qui l'avons créé.
522 if (m_my_own_backward_mng)
523 delete m_backward_mng;
524 ARCANE_FATAL("Backward manager already set");
525 }
526
527 m_backward_mng = backward_mng;
528 m_my_own_backward_mng = false;
529}
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
533
535execInitEntryPoints(bool is_continue)
536{
537 Timer::Action ts_action(m_sub_domain,"InitEntryPoints");
538 info() << "-- Executing init entry points";
539
541
543 IEntryPoint * ic = * i;
544 if (ic->where() == IEntryPoint::WInit || ic->where() == where)
545 _execOneEntryPoint(ic);
546 }
547}
548
549/*---------------------------------------------------------------------------*/
550/*---------------------------------------------------------------------------*/
551
554{
555 Timer::Action ts_action(m_sub_domain,"BuildtEntryPoints");
556 info() << "-- Executing build entry points";
557
559 IEntryPoint* ic = *i;
560 if (ic->where()==IEntryPoint::WBuild)
561 _execOneEntryPoint(ic);
562 }
563}
564
565/*---------------------------------------------------------------------------*/
566/*---------------------------------------------------------------------------*/
567
568void TimeLoopMng::
569execRestoreEntryPoints()
570{
571 Timer::Action ts_action(m_sub_domain,"RestoreEntryPoints");
572 info() << "-- Executing restore entry points";
573
575 IEntryPoint * ic = * i;
576 _execOneEntryPoint(ic);
577 }
578}
579
580/*---------------------------------------------------------------------------*/
581/*---------------------------------------------------------------------------*/
582
585{
586 Timer::Action ts_action(m_sub_domain,"OnMeshChangedEntryPoints");
587 info() << "-- Executing entry points after mesh change";
588
590 IEntryPoint * ic = * i;
591 info() << "Execute: " << ic->name();
592 _execOneEntryPoint(ic);
593 }
594}
595
596/*---------------------------------------------------------------------------*/
597/*---------------------------------------------------------------------------*/
598
601{
602 Timer::Action ts_action(m_sub_domain,"OnMeshRefinementEntryPoints");
603 info() << "-- Executing entry points after mesh refinement";
604
606 IEntryPoint * ic = * i;
607 info() << "Execute: " << ic->name();
608 _execOneEntryPoint(ic);
609 }
610}
611
612/*---------------------------------------------------------------------------*/
613/*---------------------------------------------------------------------------*/
614
617{
618 Timer::Action ts_action(m_sub_domain,"ExitEntryPoints");
619 info() << "-- Executing terminal entry points";
620
622 IEntryPoint * ic = * i;
623 _execOneEntryPoint(ic);
624 }
625
626 // Affiche les statistiques d'exécution
627 {
628 JSONWriter json_writer(JSONWriter::FormatFlags::None);
629 json_writer.beginObject();
630 _dumpTimeInfos(json_writer);
631 json_writer.endObject();
632 traceMng()->plog() << "TimeStats:" << json_writer.getBuffer();
633 traceMng()->flush();
634 }
635
636 // Affiche le profiling de message passing dans un fichier pour les traces JSON
637 if (m_msg_pass_prof_srv.get() && m_msg_pass_prof_srv->implName() == "JsonMessagePassingProfiling") {
638 String fullname(subDomain()->listingDirectory().file("message_passing_logs.")
639 + String(std::to_string(subDomain()->subDomainId()))
640 + String(".json"));
641 std::ofstream file(fullname.localstr());
642 m_msg_pass_prof_srv->printInfos(file);
643 }
644}
645
646/*---------------------------------------------------------------------------*/
647/*---------------------------------------------------------------------------*/
648
649void TimeLoopMng::
650_execOneEntryPoint(IEntryPoint * ic, Integer index, bool do_verif)
651{
653 m_observables[eTimeLoopEventType::BeginEntryPoint]->notifyAllObservers();
654 ic->executeEntryPoint();
655 m_observables[eTimeLoopEventType::EndEntryPoint]->notifyAllObservers();
657 if (m_verification_at_entry_point && !m_verification_only_at_exit)
658 _checkVerif(ic->name(),index,do_verif);
659}
660
661/*---------------------------------------------------------------------------*/
662/*---------------------------------------------------------------------------*/
663
665doVerification(const String& name)
666{
667 _checkVerif(name,0,true);
668}
669
670/*---------------------------------------------------------------------------*/
671/*---------------------------------------------------------------------------*/
672
673void TimeLoopMng::
674_checkVerif(const String& entry_point_name,Integer index,bool do_verif)
675{
677
678 ISubDomain* sd = subDomain();
679 IApplication* app = sd->application();
680 VariableComparer variable_comparer;
681 VariableComparerArgs sync_compare_args = variable_comparer.buildForCheckIfSync();
682 sync_compare_args.setMaxPrint(5);
683
685 String service_name1 = platform::getEnvironmentVariable("STDENV_VERIF_SERVICE");
686 if (service_name1.empty())
687 service_name1 = "ArcaneBasicVerifier2";
688
690 m_verifier_service = sf.createReference(service_name1);
691 if (!m_verifier_service.get()){
692 warning() << "No verification service is available."
693 << " No verification will be performed";
695 }
696 if (m_verifier_service.get()){
697 info() << "Use the service <" << service_name1
698 << "> for verification";
699 }
700 }
701
702 if (pm->isParallel()){
703 if (m_verif_type == VerifSync){
704 Integer nb_error = 0;
705 VariableCollection variables(subDomain()->variableMng()->usedVariables());
706 for( VariableCollection::Enumerator i(variables); ++i; ){
707 IVariable* var = *i;
708 if (var->property() & IVariable::PNoNeedSync)
709 continue;
710 if (var->isPartial())
711 continue;
712 VariableComparerResults r = variable_comparer.apply(var, sync_compare_args);
713 nb_error += r.nbDifference();
714 }
715 if (nb_error!=0)
716 info() << "Error in synchronization nb_error=" << nb_error
717 << " entry_point=" << entry_point_name;
718 }
719 }
720
722 _checkVerifSameOnAllReplica(entry_point_name);
723 }
724
725 if ((m_verif_type == VerifRead || m_verif_type == VerifWrite) && do_verif){
726 Integer current_iter = subDomain()->commonVariables().globalIteration();
727 if (current_iter>=0){
728 {
729 StringBuilder path = Directory(m_verif_path).file("verif_file");
730 if (m_verif_same_parallel){
731 path += "_";
732 path += pm->commRank();
733 }
734
735 StringBuilder sub_dir;
736 sub_dir += "iter";
737 sub_dir += current_iter;
738 sub_dir += "/";
739 sub_dir += entry_point_name;
740 sub_dir += index;
741
742 m_verifier_service->setFileName(path.toString());
743 m_verifier_service->setSubDir(sub_dir.toString());
744 m_verifier_service->setComputeDifferenceMethod(m_compute_diff_method);
745 }
746 bool parallel_sequential = pm->isParallel();
747 if (m_verif_same_parallel)
748 parallel_sequential = false;
750
751 // Activer cette partie si on souhaite sauver les valeurs actuelles
752#if 0
753 {
754 ServiceFinder2T<IVerifierService,ISubDomain> sf(app,sd);
755 ScopedPtrT<IVerifierService> current_save(sf.find(service_name1));
756 if (current_save.get()){
757 current_save->setFileName(m_verifier_service->fileName()+"_current");
758 current_save->setSubDir(m_verifier_service->subDir());
759 current_save->writeReferenceFile();
760 }
761 }
762#endif
763
764 // En lecture, désactive les exceptions flottantes pour éviter
765 // des erreurs lorsqu'on compare des variables non initialisées
766 {
767 FloatingPointExceptionSentry fpes(false);
768 m_verifier_service->doVerifFromReferenceFile(parallel_sequential,
769 platform::getEnvironmentVariable("STDENV_VERIF_SKIP_GHOSTS").null());
770 }
771 }
773 m_verifier_service->writeReferenceFile();
774 }
775 }
776}
777
778/*---------------------------------------------------------------------------*/
779/*---------------------------------------------------------------------------*/
780
781void TimeLoopMng::
782_checkVerifSameOnAllReplica(const String& entry_point_name)
783{
784 info() << "CHECK: comparing variables values on all replica"
785 << " entry_point_name=" << entry_point_name;
786 ISubDomain* sd = subDomain();
787 IParallelMng* replica_pm = sd->parallelMng()->replication()->replicaParallelMng();
788 IVariableMng* vm = sd->variableMng();
789 VariableCollection variables(vm->usedVariables());
790 VariableList vars_to_check;
791 for( VariableCollection::Enumerator i(variables); ++i; ){
792 IVariable* var = *i;
793 if (var->property() & IVariable::PNoReplicaSync)
794 continue;
795 if (var->isPartial())
796 continue;
797 // Pour l'instant on ne supporte pas la comparaison entre réplica
798 // des variables de type 'String'.
799 if (var->dataType()==DT_String)
800 continue;
801 vars_to_check.add(var);
802 }
803 VariableCollection common_vars = vm->utilities()->filterCommonVariables(replica_pm,vars_to_check,true);
804
805 Integer nb_error = 0;
806 VariableComparer variable_comparer;
807 {
808 VariableComparerArgs compare_args = variable_comparer.buildForCheckIfSameOnAllReplica();
809 compare_args.setMaxPrint(10);
810 FloatingPointExceptionSentry fpes(false);
811 for( VariableCollection::Enumerator ivar(common_vars); ++ivar; ){
812 IVariable* var = *ivar;
813 VariableComparerResults r = variable_comparer.apply(var, compare_args);
814 nb_error += r.nbDifference();
815 }
816 }
817
818 if (nb_error!=0)
819 info() << "Errors in comparing values between replica nb_error=" << nb_error
820 << " entry_point=" << entry_point_name;
821}
822
823/*---------------------------------------------------------------------------*/
824/*---------------------------------------------------------------------------*/
829doExecNextEntryPoint(bool & is_last)
830{
831 if (!m_used_time_loop)
832 ARCANE_FATAL("No time loop");
833
834 is_last = true;
835
837
838 if (cl.empty())
839 return;
840
841 if (m_current_entry_point >= cl.count())
843
844 _execOneEntryPoint(cl[m_current_entry_point]);
845
847
848 is_last = (m_current_entry_point >= cl.count());
849}
850
851/*---------------------------------------------------------------------------*/
852/*---------------------------------------------------------------------------*/
858{
859 //return m_loop_entry_points->EntryPointList()[m_current_entry_point];
861 if (m_current_entry_point >= cl.count())
862 return nullptr;
863 return cl[m_current_entry_point];
864}
865
866/*---------------------------------------------------------------------------*/
867/*---------------------------------------------------------------------------*/
868
871{
872 ITraceMng * msg = traceMng();
873 ISubDomain* sd = subDomain();
874 Trace::Setter mci(msg,m_message_class_name);
875
876 if (!m_used_time_loop)
877 ARCANE_FATAL("No time loop");
878
879 Integer current_iteration = sd->commonVariables().globalIteration();
880 // Le numéro d'itération 0 correspond à l'initialisation. La première
881 // itération de la boucle en temps porte le numéro 1.
882 if (current_iteration==0){
884 global_iteration = 1;
885 current_iteration = 1;
886 }
887
888 _resetTimer();
889
890 if (m_stop_time_loop){
891 if (m_stop_has_error)
892 return (-1);
893 return (+1);
894 }
895
896 m_backward_mng->beginAction();
897
898 // Action de restauration
899 if (m_backward_mng->checkAndApplyRestore()) {
900
901 execRestoreEntryPoints();
902
903 // Repartitionnement inutile si retour-arrière
904 m_mesh_partitioner.clear();
905 }
906
907 // Repartionnement demandé
908 bool mesh_partition_done = false;
909 if (!m_mesh_partitioner.empty()) {
911 mesh_partition_done = true;
912 }
913
914 // Action de sauvegarde
915 m_backward_mng->checkAndApplySave(mesh_partition_done);
916
917 m_backward_mng->endAction();
918
919 {
920 // Regarde les modules inactifs au cours du temps
921 Real global_time = sd->commonVariables().globalTime();
922 CaseOptionsCollection blocks(sd->caseMng()->blocks());
923 for( CaseOptionsCollection::Enumerator i(blocks); ++i; ){
924 ICaseOptions * opt = * i;
925 IModule * mod = opt->caseModule();
926 ICaseFunction * f = opt->activateFunction();
927 if (mod && f){
928 bool is_active = true;
929 f->value(global_time, is_active);
930 bool mod_disabled = mod->disabled();
931 bool mod_new_disabled = !is_active;
932 if (mod_new_disabled != mod_disabled){
933 if (mod_new_disabled)
934 info() << "The module " << mod->name() << " is desactivated";
935 else
936 info() << "The module " << mod->name() << " is activated";
937 mod->setDisabled(mod_new_disabled);
938 }
939 }
940 }
941 }
942
943 m_observables[eTimeLoopEventType::BeginIteration]->notifyAllObservers();
944
945 // Exécute chaque point d'entrée de l'itération
946 {
947 Integer index =0;
949 Timer::Action ts_action(sd,"LoopEntryPoints");
950 for( EntryPointList::Enumerator i(m_loop_entry_points); ++i; ++index ){
951 IEntryPoint* ep = *i;
952 IModule* mod = ep->module();
953 if (mod && mod->disabled()){
954 continue;
955 //warning() << "MODULE " << mod->name() << " is disabled";
956 }
957 try{
958 _execOneEntryPoint(*i, index, true);
959 } catch(const GoBackwardException&){
960 m_backward_mng->goBackward();
961 } catch(...){ // On remonte toute autre exception
962 throw;
963 }
964 if (m_backward_mng->isBackwardEnabled()){
965 break;
966 }
967 }
968 if (!m_verification_at_entry_point && !m_verification_only_at_exit)
969 _checkVerif("_EndLoop",0,true);
970 }
971 m_observables[eTimeLoopEventType::EndIteration]->notifyAllObservers();
972
973 {
974 bool force_prepare_dump = false;
975 if (m_verification_active && m_verif_type==VerifWrite){
976 if (!m_verif_same_parallel)
977 force_prepare_dump = true;
978 }
979 else{
980 String force_prepare_dump_str = platform::getEnvironmentVariable("ARCANE_FORCE_PREPARE_DUMP");
981 if (force_prepare_dump_str=="TRUE" || force_prepare_dump_str=="1" || force_prepare_dump_str=="true")
982 force_prepare_dump = true;
983 }
984 if (force_prepare_dump){
985 info() << "TimeLoopMng::doOneIteration(): Force prepareDump()";
986 // TODO: vérifier si nécessaire et si oui le faire pour tous les sous-domaines.
988 }
989 }
990
991 if (m_stop_time_loop){
992 if (m_stop_has_error)
993 return (-1);
994 return (+1);
995 }
996 return 0;
997}
998
999/*---------------------------------------------------------------------------*/
1000/*---------------------------------------------------------------------------*/
1006{
1007 ISubDomain* sd = subDomain();
1008
1009 // Détruit le gestionnaire de retour-arrière pour économiser de la mémoire.
1010 // Il sera reconstruit après le partitionnement.
1011 m_backward_mng->clear();
1012
1013 Timer timer(sd,"TimeLoopMng::partitionMesh",Timer::TimerReal);
1014 Timer::Action ts_action(sd, "MeshesLoadBalance", true);
1015
1016 for (IMeshPartitionerBase* mesh_partitioner : m_mesh_partitioner) {
1017 IMesh* mesh = mesh_partitioner->primaryMesh();
1018 Timer::Action ts_action2(sd, mesh->name(), true);
1019 {
1020 Timer::Sentry sentry(&timer);
1021 mesh->utilities()->partitionAndExchangeMeshWithReplication(mesh_partitioner, false);
1022 }
1023 info() << "Time spent to repartition the mesh (unit: second): "
1024 << timer.lastActivationTime();
1025
1026 // Écrit dans les logs dans les infos sur la distribution du voisinage
1027 // TODO: pouvoir configurer cela et éventuellement ajouter des informations
1028 {
1029 IItemFamily* cell_family = mesh->cellFamily();
1030 IVariableSynchronizer* sync_info = cell_family->allItemsSynchronizer();
1031 auto communicating_ranks = sync_info->communicatingRanks();
1032 Int64 current_iteration = subDomain()->commonVariables().globalIteration();
1033 {
1034 JSONWriter json_writer(JSONWriter::FormatFlags::None);
1035 json_writer.beginObject();
1036 json_writer.write("Mesh", mesh->name());
1037 json_writer.write("Iteration", current_iteration);
1038 json_writer.write("CommunicatingRanks", communicating_ranks);
1039 json_writer.endObject();
1040 plog() << "MeshPartitionCommunicatingInfos:" << json_writer.getBuffer();
1041 }
1042 }
1043 }
1044
1045 {
1046 Timer::Action ts_action1(sd, "OnMeshChangeEntryPoints", true);
1048 }
1049
1050 m_mesh_partitioner.clear();
1051
1052 // Affiche les statistiques d'exécution
1053 sd->timeStats()->dumpCurrentStats("MeshesLoadBalance");
1054}
1055
1056/*---------------------------------------------------------------------------*/
1057/*---------------------------------------------------------------------------*/
1058
1059void TimeLoopMng::
1060_callSpecificEntryPoint()
1061{
1063 info() << "Calling specific entry point: " << m_specific_entry_point_name;
1064 if (!ep)
1065 ARCANE_FATAL("No entry point named '{0}' found",m_specific_entry_point_name);
1066 ep->executeEntryPoint();
1067}
1068
1069/*---------------------------------------------------------------------------*/
1070/*---------------------------------------------------------------------------*/
1071
1073registerTimeLoop(ITimeLoop * timeloop)
1074{
1075 ITraceMng* msg = traceMng();
1076 Trace::Setter mci(msg,m_message_class_name);
1077
1078 const String& name = timeloop->name();
1079
1080 log() << "Registering the time loop " << name;
1081
1082 auto tl = m_time_loop_list.find(name);
1083 if (tl != m_time_loop_list.end())
1084 ARCANE_FATAL("The time loop '{0}' is defined twice",name);
1085
1086 m_time_loop_list.insert(TimeLoopMap::value_type(name, timeloop));
1087}
1088
1089/*---------------------------------------------------------------------------*/
1090/*---------------------------------------------------------------------------*/
1091
1093setUsedTimeLoop(const String& name)
1094{
1095 ITraceMng * msg = traceMng();
1096 Trace::Setter mci(msg,m_message_class_name);
1097
1098 m_used_time_loop = nullptr;
1099 if (name.null())
1101 else{
1102 auto tl = m_time_loop_list.find(name);
1103 if (tl != m_time_loop_list.end())
1104 m_used_time_loop = tl->second;
1105 }
1106
1107 if (!m_used_time_loop){
1108 info() << "Available time loops: ";
1109 for( const auto& tl : m_time_loop_list ){
1110 info() << "Time loop <" << tl.second->name() << ">";
1111 }
1112 ARCANE_FATAL("Unknown time loop '{0}'",name);
1113 }
1114
1115 logdate() << "Using time loop " << name;
1116
1118 // Fusionne la configuration du sous-domaine avec celle de la boucle en temps.
1119 sd->configuration()->merge(m_used_time_loop->configuration());
1120
1122
1123 service_loader->loadModules(sd,false);
1124
1126
1127 // Chargement des modules de la boucle en temps
1129
1130 for( const auto& it : m_module_state_list ){
1131 const ModuleState & module_state = it.second;
1132
1133 if (!module_state.m_is_optional || module_state.m_is_active){
1134 // creation du module
1135 if (!_createModule(module_state.m_alias))
1136 ARCANE_FATAL("The module \"{0}\" was not created.",module_state.m_alias);
1137 }
1138 else{
1139 info() << "The entry points of the module \""
1140 << module_state.m_alias << "\" won't be executed (inactive module).";
1141 }
1142 }
1143
1144 _createSingletonServices(service_loader.get());
1145
1147
1148 // Parcours des points d'entrée explicitement référencés dans la boucle en temps
1149 // (m_used_time_loop) pour rechercher ceux qui correspondent aux points d'entrée
1150 // enregistrés dans les modules
1151 // Les points d'entrée non auto-load non référencés ne sont donc pas pris en charge.
1152 // Attention: dans la boucle en temps les points d'entrée sont référencés
1153 // par nom_module.nom_point_entrée alors que dans le fichier de données
1154 // ils sont référencés par alias_module.nom_point_entrée
1155 EntryPointList timeloop_entry_points;
1156 _processEntryPoints(timeloop_entry_points,
1157 m_used_time_loop->entryPoints(ITimeLoop::WBuild),
1159 _processEntryPoints(timeloop_entry_points,
1162 _processEntryPoints(timeloop_entry_points,
1165 _processEntryPoints(timeloop_entry_points,
1168 _processEntryPoints(timeloop_entry_points,
1171 _processEntryPoints(timeloop_entry_points,
1172 m_used_time_loop->entryPoints(ITimeLoop::WInit),
1174 _processEntryPoints(timeloop_entry_points,
1175 m_used_time_loop->entryPoints(ITimeLoop::WExit),
1177
1178 // Ajoute les autoload au début.
1179 EntryPointList entry_points(m_entry_point_mng->entryPoints());
1180 for( EntryPointCollection::Enumerator i(entry_points); ++i; ){
1181 IEntryPoint* ic = * i;
1184 }
1185
1186 // Ajoute les points d'entrées de la boucle de calcul.
1187 for (EntryPointCollection::Enumerator i(timeloop_entry_points); ++i; )
1189
1190 { // Ajoute les autoload à la fin dans le sens inverse de leur déclaration
1191 EntryPointList auto_load_ends;
1192 for( EntryPointCollection::Enumerator i(entry_points); ++i; ){
1193 IEntryPoint* ic = *i;
1195 auto_load_ends.add(ic);
1196 }
1197 }
1198 for( Integer i=0, s=auto_load_ends.count(); i<s; ++i){
1199 IEntryPoint * ic = auto_load_ends[s - 1 - i];
1201 }
1202 }
1203}
1204
1205/*---------------------------------------------------------------------------*/
1206/*---------------------------------------------------------------------------*/
1207
1208void TimeLoopMng::
1209_createSingletonServices(IServiceLoader* service_loader)
1210{
1213 const TimeLoopSingletonServiceInfo& ti = *i;
1214 String name = ti.name();
1215 bool is_found = service_loader->loadSingletonService(sd,name);
1216 if (!is_found){
1217 if (ti.isRequired())
1218 ARCANE_FATAL("Unable to find a singleton service named '{0}'",name);
1219 info() << "The optional singleton service named '" << name << "' was not found";
1220 }
1221 info() << "Loading singleton service '" << name << "'";
1222 }
1223
1224 // Lecture des services spécifiés dans le jeu de données.
1225 ICaseMng* cm = m_sub_domain->caseMng();
1226 ICaseDocument* doc = cm->caseDocument();
1227 if (doc){
1228 XmlNode services_element = doc->servicesElement();
1229 String ustr_name("name");
1230 String ustr_active("active");
1231 XmlNodeList services = services_element.children("service");
1232 for( XmlNode x : services ) {
1233 String name = x.attrValue(ustr_name);
1234 XmlNode active_node = x.attr(ustr_active);
1235 bool is_active = true;
1236 if (!active_node.null())
1237 is_active = active_node.valueAsBoolean(true);
1238 if (is_active)
1239 service_loader->loadSingletonService(sd,name);
1240 }
1241 }
1242}
1243
1244/*---------------------------------------------------------------------------*/
1245/*---------------------------------------------------------------------------*/
1246
1249 const TimeLoopEntryPointInfoCollection& entry_points_info,
1250 const char* where)
1251{
1252 //TODO: Verifier que le nom du module spécifié dans la liste des modules à activer existe bien.
1253 for( TimeLoopEntryPointInfoCollection::Enumerator i(entry_points_info); ++i; ){
1254 const TimeLoopEntryPointInfo& entry_point_info = *i;
1255 const String& timeloop_call_name = entry_point_info.name();
1256 String entry_point_name;
1257 String module_name;
1258 _extractModuleAndEntryPointName(timeloop_call_name,module_name,entry_point_name);
1259
1260 auto it = m_module_state_list.find(module_name);
1261 if (it == m_module_state_list.end())
1262 ARCANE_FATAL("No module named '{0}' is referenced",module_name);
1263
1264 const ModuleState & module_state = it->second;
1265 if (!module_state.m_is_optional || module_state.m_is_active){
1266 if (!module_state.m_alias.null())
1267 module_name = module_state.m_alias;
1268 StringBuilder call_alias(module_name);
1269 call_alias += ".";
1270 call_alias += entry_point_name;
1271
1272 IEntryPoint* entry_point = m_entry_point_mng->findEntryPoint(module_name,entry_point_name);
1273 log() << "Looking for entry point '" << call_alias << "'";
1274 if (!entry_point)
1275 ARCANE_FATAL("No entry point named '{0}' is referenced",call_alias);
1276
1277 // il faut verifier que la propriete "where" du point d'entree est
1278 // compatible avec l'attribut "where" donne dans la boucle en temps
1279 String ep_where = entry_point->where();
1280 OStringStream msg;
1281 msg() << "The entry point '" << call_alias << "' declared \"" << ep_where
1282 << "\" can't be in the entry point list \""
1283 << where << "\" of the time loop";
1284
1285 if (ep_where==IEntryPoint::WComputeLoop && where!=ITimeLoop::WComputeLoop)
1286 ARCANE_FATAL(msg.str());
1287 if (ep_where==IEntryPoint::WRestore && where!=ITimeLoop::WRestore)
1288 ARCANE_FATAL(msg.str());
1289 if (ep_where==IEntryPoint::WExit && where!=ITimeLoop::WExit)
1290 ARCANE_FATAL(msg.str());
1291 if ((ep_where==IEntryPoint::WInit ||
1292 ep_where==IEntryPoint::WContinueInit ||
1293 ep_where==IEntryPoint::WStartInit)
1294 && where != ITimeLoop::WInit)
1295 ARCANE_FATAL(msg.str());
1296
1297 entry_points.add(entry_point);
1298 }
1299 }
1300}
1301
1302/*---------------------------------------------------------------------------*/
1303/*---------------------------------------------------------------------------*/
1304
1307{
1308 // Analyse des infos de la boucle en temps
1309 // 1. liste des modules obligatoires
1310 for( StringCollection::Enumerator i(time_loop->requiredModulesName()); ++i; ){
1311 const String& module_name = *i;
1312 ModuleState ms(false, module_name);
1313 m_module_state_list.insert(ModuleStateMap::value_type(module_name, ms));
1314 }
1315
1316 // 2. liste des modules optionnels
1317 for( StringCollection::Enumerator i(time_loop->optionalModulesName()); ++i; ){
1318 const String& module_name = *i;
1319 ModuleState ms(true, module_name);
1320 m_module_state_list.insert(ModuleStateMap::value_type(module_name,ms));
1321 }
1322
1323 ICaseMng* cm = m_sub_domain->caseMng();
1324 // Remplissage de la liste d'état des modules à partir
1325 // des infos du fichier de données s'il existe
1326 // (Il n'y a pas de jeu de données par exemple lorsqu'on génére les infos
1327 // internes du code via l'option 'arcane_all_internal').
1328 ICaseDocument* doc = cm->caseDocument();
1329 if (!doc)
1330 return;
1331
1332 XmlNode modules_node = doc->modulesElement();
1333 String ustr_module("module");
1334 String ustr_false("false");
1335 String ustr_name("name");
1336 String ustr_alias("alias");
1337 String ustr_active("active");
1338 for (XmlNode::const_iter i(modules_node); i(); ++i){
1339 if (i->name() != ustr_module)
1340 continue;
1341 XmlNode module_node = *i;
1342 String name = module_node.attrValue(ustr_name);
1343 String alias = module_node.attrValue(ustr_alias);
1344
1345 // Regarde si le module est actif.
1346 XmlNode active_node = module_node.attr(ustr_active);
1347 bool active = true;
1348 if (!active_node.null())
1349 active = active_node.valueAsBoolean(true);
1350
1351 // Complète les infos de la liste d'état
1352
1353 // Regarde d'abord si 'name' correspond à un nom de module
1354 // dans la langue du JDD.
1355 auto ilang = m_lang_module_factory_map.find(name);
1356 if (ilang!=m_lang_module_factory_map.end())
1357 name = ilang->second->moduleName();
1358
1359 auto it = m_module_state_list.find(name);
1360 if (it == m_module_state_list.end())
1361 // Lève une exception si le nom du module spécifié dans le JDD
1362 // ne correspond à aucun module enregistré.
1363 ARCANE_FATAL("Error in configuring active modules: no module named '{0}' is registered.",
1364 name);
1365
1366 ModuleState& ms = it->second;
1367 ms.m_is_active = active;
1368 if (!alias.null())
1369 ms.m_alias = alias;
1370
1371 if (!ms.m_is_optional && !ms.m_is_active) {
1372 pwarning() << "The module \"" << ms.m_alias
1373 << "\" can't be declared mandatory in the time loop"
1374 << " while being inactive in the input data."
1375 << " It's activity is therefore forced. ";
1376 ms.m_is_active = true;
1377 }
1378 }
1379}
1380
1381/*---------------------------------------------------------------------------*/
1382/*---------------------------------------------------------------------------*/
1383
1385_extractModuleAndEntryPointName(const String& timeloop_call_name,
1386 String& module_name,
1387 String& entry_point_name)
1388{
1389 std::string std_timeloop_call_name(timeloop_call_name.localstr());
1390 size_t index = std_timeloop_call_name.find_first_of('.');
1391 if (index==std::string::npos){
1392 ARCANE_FATAL("The string '{0}' is not a valid reference to an entry point (has to be of type "
1393 "'module_name.entry_point_name)",timeloop_call_name);
1394 }
1395 std::string std_module_name = std_timeloop_call_name.substr(0, index);
1396 std::string std_entry_point_name = std_timeloop_call_name.substr(index+1);
1397 module_name = std_module_name;
1398 entry_point_name = std_entry_point_name;
1399}
1400
1401/*---------------------------------------------------------------------------*/
1402/*---------------------------------------------------------------------------*/
1408{
1409 String lang;
1410 ICaseDocumentFragment* doc = m_sub_domain->caseMng()->caseDocumentFragment();
1411 if (doc)
1412 lang = doc->language();
1413 ModuleFactoryInfoCollection module_factories(subDomain()->application()->moduleFactoryInfos());
1414 m_module_factory_map.clear();
1416 for( ModuleFactoryInfoCollection::Enumerator i(module_factories); ++i; ){
1417 IModuleFactoryInfo* mfi = *i;
1418
1419 const String& module_name = mfi->moduleName();
1420 if (m_module_factory_map.find(module_name)!=m_module_factory_map.end())
1421 ARCANE_FATAL("Two modules with same name '{0}'",module_name);
1422 m_module_factory_map.insert(std::make_pair(module_name,mfi));
1423 info(5) << "Registering module in factory map name=" << module_name;
1424
1425 if (!lang.null()){
1426 const IServiceInfo* si = mfi->serviceInfo();
1427 String translated_name = si->tagName(lang);
1428 if (m_lang_module_factory_map.find(module_name)!=m_lang_module_factory_map.end()){
1429 // Envoie juste un avertissement car cela ne posera pas forcément problème.
1430 warning() << "Two modules with same translated name=" << translated_name
1431 << " ignoring name=" << module_name;
1432 }
1433 else{
1434 m_lang_module_factory_map.insert(std::make_pair(translated_name,mfi));
1435 info(5) << "Registering module in lang factory map name=" << translated_name;
1436 }
1437 }
1438 }
1439}
1440
1441/*---------------------------------------------------------------------------*/
1442/*---------------------------------------------------------------------------*/
1443
1445_createModule(const String& module_name)
1446{
1447 auto x = m_module_factory_map.find(module_name);
1448 if (x!=m_module_factory_map.end()){
1449 IModuleFactoryInfo* mfi = x->second;
1450 Ref<IModule> module = mfi->createModule(m_sub_domain,m_sub_domain->defaultMeshHandle());
1451 if (module.get()){
1452 info() << "Loading module " << module->name()
1453 << " (Version " << module->versionInfo() << ")";
1454 return true;
1455 }
1456 }
1457 return false;
1458}
1459
1460/*---------------------------------------------------------------------------*/
1461/*---------------------------------------------------------------------------*/
1467{
1468 log() << "Adding the entry point `" << entry_point->module()->name() << "::" << entry_point->name() << "' to the execution";
1469
1470 String where = entry_point->where();
1472 m_init_entry_points.add(entry_point);
1473 }
1474 else if (where==IEntryPoint::WBuild){
1475 m_build_entry_points.add(entry_point);
1476 }
1477 else if (where==IEntryPoint::WExit){
1478 m_exit_entry_points.add(entry_point);
1479 }
1480 else if (where == IEntryPoint::WRestore){
1481 m_restore_entry_points.add(entry_point);
1482 }
1483 else if (where == IEntryPoint::WOnMeshChanged){
1484 m_on_mesh_changed_entry_points.add(entry_point);
1485 }
1486 else if (where == IEntryPoint::WOnMeshRefinement){
1487 m_on_mesh_refinement_entry_points.add(entry_point);
1488 }
1489 else if (IEntryPoint::WComputeLoop){
1490 m_loop_entry_points.add(entry_point);
1492 }
1493 m_used_time_loop_entry_points.add(entry_point);
1494
1495 // Puisque le module a un point d'entrée utilisé, il est activé.
1496 IModule* c = entry_point->module();
1497 c->setUsed(true);
1498 {
1499 if (std::find(m_list_execute_module.begin(),m_list_execute_module.end(),c)==m_list_execute_module.end()){
1500 debug() << "Adding the module `" << c->name() << "' to the execution";
1501 m_list_execute_module.add(c);
1502 }
1503 }
1504}
1505
1506/*---------------------------------------------------------------------------*/
1507/*---------------------------------------------------------------------------*/
1508
1509void TimeLoopMng::
1510_dumpTimeInfos(JSONWriter& json_writer)
1511{
1512 IModuleMng * module_mng = subDomain()->moduleMng();
1513
1515
1516 Real total_exec_time = cpuTimeUsed();
1517
1518 {
1519 Real total_real_time = 0.0;
1520 Real compute_real_time = 0.0;
1521 json_writer.writeKey("EntryPoints");
1522 json_writer.beginArray();
1523 for( EntryPointCollection::Enumerator i(entry_points); ++i; ){
1524 IEntryPoint* ep = *i;
1525 Real s2 = ep->totalElapsedTime();
1526 {
1527 JSONWriter::Object jo(json_writer);
1528 json_writer.write("Name",ep->name());
1529 json_writer.write("TotalCpuTime",s2);
1530 json_writer.write("TotalElapsedTime",s2);
1531 json_writer.write("NbCall",(Int64)ep->nbCall());
1532 json_writer.write("Where",ep->where());
1533 }
1534 info(5) << "CPU_TIME where=" << ep->where() << " name=" << ep->name() << " S=" << s2;
1535 total_real_time += s2;
1536 if (ep->where()==IEntryPoint::WComputeLoop){
1537 compute_real_time += s2;
1538 }
1539 }
1540 json_writer.endArray();
1541 info(4) << "TOTAL_REAL_TIME COMPUTE=" << compute_real_time << " TOTAL=" << total_real_time;
1542 }
1543
1544
1545 const CommonVariables& scv = subDomain()->commonVariables();
1546 info() << "Information on the execution time";
1547 {
1548 Accelerator::IAcceleratorMng* acc_mng = m_sub_domain->acceleratorMng();
1549 if (acc_mng->isInitialized()){
1550 Accelerator::Runner* runner = acc_mng->defaultRunner();
1551 info() << " TotalRunner (" << runner->executionPolicy() << ") = "
1552 << runner->cumulativeCommandTime() << " seconds";
1553 }
1554 }
1555 info() << " TotalElapsed = " << total_exec_time << " seconds";
1556 info() << " CumulativeElapsed = " << scv.globalElapsedTime()
1557 << " seconds (" << platform::timeToHourMinuteSecond(scv.globalElapsedTime()) << ")";
1558 info() << " T = Total time spent in the function or in the module (s)";
1559 info() << " TC = Total time spend per call (ms)";
1560 info() << " TCC = Total time spent per call and per cell (ns)";
1561 info() << " N = Number of time the function was called";
1562
1563 info() << " Use the clock time (elapsed) for the statistics";
1564
1565 std::ostringstream o;
1566 std::ios_base::fmtflags f = o.flags(std::ios::right);
1567 Integer nb_cell = 0;
1568 IMesh * mesh = subDomain()->defaultMesh();
1569 if (mesh)
1570 nb_cell = mesh->nbCell();
1571 if (nb_cell == 0)
1572 nb_cell = 1;
1573
1574 o << "\n Name T TC TCC % N\n";
1575
1576 for (ModuleCollection::Enumerator j(module_mng->modules()); ++j; ){
1577 IModule * module = * j;
1578 Real total_time_module = 0.;
1579 Real total_time_module_entry_point = 0.;
1580 for (EntryPointCollection::Enumerator i(entry_points); ++i; ){
1581 IEntryPoint * ic = * i;
1582 if (ic->module()!=module)
1583 continue;
1584 Integer nb_call = ic->nbCall();
1585 if (nb_call==0)
1586 continue;
1587 Real total_time = ic->totalElapsedTime();
1588 //if (math::isZero(total_time))
1589 //continue;
1590 const String& ep_name = ic->name();
1591 {
1592 Int64 l = ep_name.length();
1593 if (l > 36){
1594 o.write(ep_name.localstr(), 34);
1595 o << "...";
1596 }
1597 else{
1598 o.width(37);
1599 o << ep_name;
1600 }
1601 }
1602 o.width(10);
1603 Int64 z = Convert::toInt64(total_time);
1604 o << z;
1605 Real r = (1e3 * total_time) / nb_call;
1606 if (ic->where() == IEntryPoint::WComputeLoop){
1607 total_time_module += r;
1608 total_time_module_entry_point += total_time;
1609 }
1610 z = Convert::toInt64(r);
1611 o.width(10);
1612 o << z;
1613 r = (r * 1e6) / nb_cell;
1614 z = Convert::toInt64(r);
1615 o.width(10);
1616 o << z;
1617 //Probleme sur certaine machine : total_exec_time = 0
1618 if (total_exec_time>0)
1619 z = Convert::toInt64((100.0 * total_time) / total_exec_time);
1620 else
1621 z = Convert::toInt64((100.0 * total_time)) ;
1622 o.width(5);
1623 o << z;
1624 o.width(12);
1625 o << nb_call;
1626 o << '\n';
1627 }
1628 o << "--";
1629 o.width(33);
1630 o << module->name();
1631 o << "--";
1632 o.width(10);
1633 Int64 z = Convert::toInt64(total_time_module_entry_point * 1e-3);
1634 o << z;
1635 o.width(10);
1636 z = Convert::toInt64(total_time_module);
1637 o << z;
1638 Real r = (total_time_module * 1e6) / nb_cell;
1639 z = Convert::toInt64(r);
1640 o.width(10);
1641 o << z;
1642 o << '\n';
1643 }
1644 o.flags(f);
1645
1646 info() << o.str();
1647
1648 {
1649 IParallelMng* pm = m_sub_domain->parallelMng();
1650 if (pm->isParallel()){
1651 JSONWriter::Object jo(json_writer,"MessagePassingStats");
1652 Parallel::IStat* s = pm->stat();
1653 if (s){
1654 s->printCollective(pm);
1655 s->dumpJSON(json_writer);
1656 }
1657 }
1658 }
1659 {
1660 JSONWriter::Object jo(json_writer,"VariablesStats");
1661 m_sub_domain->variableMng()->dumpStatsJSON(json_writer);
1662 }
1663 {
1664 JSONWriter::Object jo(json_writer,"TimeStats");
1665 m_sub_domain->timeStats()->dumpStatsJSON(json_writer);
1666 }
1667 {
1668 IProfilingService* ps = platform::getProfilingService();
1669 if (ps){
1670 JSONWriter::Object jo(json_writer,"Profiling");
1671 ps->dumpJSON(json_writer);
1672 }
1673 }
1674
1675 Item::dumpStats(traceMng());
1676}
1677
1678/*---------------------------------------------------------------------------*/
1679/*---------------------------------------------------------------------------*/
1680
1682cpuTimeUsed() const
1683{
1684 EntryPointCollection entry_points = m_entry_point_mng->entryPoints();
1685 Real total_elapsed_time = 0.0;
1686 for( EntryPointCollection::Enumerator i(entry_points); ++i; ){
1687 Real s1 = (*i)->totalElapsedTime();
1688 total_elapsed_time += s1;
1689 }
1690 return total_elapsed_time;
1691}
1692
1693/*---------------------------------------------------------------------------*/
1694/*---------------------------------------------------------------------------*/
1695
1698{
1699 if (!m_backward_mng)
1700 _createOwnDefaultBackwardMng();
1701 return m_backward_mng->isLocked();
1702}
1703
1704/*---------------------------------------------------------------------------*/
1705/*---------------------------------------------------------------------------*/
1706
1708goBackward()
1709{
1710 ITraceMng * msg = traceMng();
1711 Trace::Setter mci(msg,m_message_class_name);
1712
1713 if (!m_backward_mng)
1714 _createOwnDefaultBackwardMng();
1715
1716 m_backward_mng->goBackward();
1717}
1718
1719/*---------------------------------------------------------------------------*/
1720/*---------------------------------------------------------------------------*/
1721
1723timeLoopsName(StringCollection& names) const
1724{
1725 for( ConstIterT<TimeLoopMap> i(m_time_loop_list); i(); ++i)
1726 names.add(i->first);
1727}
1728
1729/*---------------------------------------------------------------------------*/
1730/*---------------------------------------------------------------------------*/
1731
1733timeLoops(TimeLoopCollection& time_loops) const
1734{
1735 for( ConstIterT<TimeLoopMap> i(m_time_loop_list); i(); ++i)
1736 time_loops.add(i->second);
1737}
1738
1739/*---------------------------------------------------------------------------*/
1740/*---------------------------------------------------------------------------*/
1741
1743createTimeLoop(const String& name)
1744{
1745 IApplication * sm = m_sub_domain->application();
1746 return sm->mainFactory()->createTimeLoop(sm, name);
1747}
1748
1749/*---------------------------------------------------------------------------*/
1750/*---------------------------------------------------------------------------*/
1751
1754{
1755 m_stop_reason = reason;
1756}
1757
1758/*---------------------------------------------------------------------------*/
1759/*---------------------------------------------------------------------------*/
1760
1762stopComputeLoop(bool is_final_time,bool has_error)
1763{
1764 m_stop_time_loop = true;
1765 m_stop_has_error = has_error;
1766 if (is_final_time)
1767 m_final_time_reached = true;
1768 if (has_error)
1769 m_stop_reason = eTimeLoopStopReason::Error;
1770 else if (is_final_time)
1772 // Si \a m_stop_reason n'est pas encore spécifié, indique qu'il n'y a pas
1773 // de raison spéciale
1774 if (m_stop_reason==eTimeLoopStopReason::NoStop)
1775 m_stop_reason = eTimeLoopStopReason::NoReason;
1776}
1777
1778/*---------------------------------------------------------------------------*/
1779/*---------------------------------------------------------------------------*/
1780
1783{
1784 if (!m_backward_mng)
1785 _createOwnDefaultBackwardMng();
1786
1787 if (m_backward_mng->isLocked() || m_backward_mng->isBackwardEnabled()){
1788 info() << "Repartioning required but inactive due to a backward process active";
1789 return;
1790 }
1791 m_mesh_partitioner.add(mesh_partitioner);
1792}
1793
1794/*---------------------------------------------------------------------------*/
1795/*---------------------------------------------------------------------------*/
1796
1798doComputeLoop(Integer max_loop)
1799{
1800 m_nb_loop = 0;
1801 bool is_end = false;
1802 bool is_end_by_max_loop = false;
1803 int ret_val = 0;
1804 //m_alarm_timer_value = 0;
1805 //pwarning() << "Force le alarm_timer_value a zéro";
1806 if (m_alarm_timer_value>0){
1807 info() << "Set the timeout before alarm at " << m_alarm_timer_value << " seconds";
1808 }
1809
1810 // Allocation d'un gestionnaire de retour-arrière par défaut
1811 if (!m_backward_mng)
1812 _createOwnDefaultBackwardMng();
1813
1815 bool want_specific_profiling = false;
1816 // Regarde si on demande un profiling spécifique. Dans ce cas,
1817 // les modules et services gèrent eux même le profiling et donc
1818 // on ne démarre pas automatiquement le profiling au début de la
1819 // boucle de calcul
1820 if (!platform::getEnvironmentVariable("ARCANE_SPECIFIC_PROFILING").null()){
1821 info() << "Specific profiling activated";
1822 want_specific_profiling = true;
1823 }
1824
1825 {
1826 // NOTE: arcaneGlobalMemoryInfo() peut changer au cours du calcul
1827 // donc il faut le récupérer à chaque fois qu'on en a besoin.
1828 IMemoryInfo* mem_info = arcaneGlobalMemoryInfo();
1829 String s = platform::getEnvironmentVariable("ARCANE_CHECK_MEMORY_BLOCK_SIZE_ITERATION");
1830 if (!s.null()){
1831 Int64 block_size = 0;
1832 bool is_bad = builtInGetValue(block_size,s);
1833 if (!is_bad && block_size>2){
1834 info() << "Set Memory StackTraceMinAllocSize to " << block_size;
1835 mem_info->setStackTraceMinAllocSize(block_size);
1836 }
1837 }
1838 }
1839
1840 // Demarrage du profiling de message passing le cas echeant
1841 if (m_msg_pass_prof_srv.get())
1842 m_msg_pass_prof_srv->startProfiling();
1843
1844 try{
1845 if (ps){
1846 if (!ps->isInitialized())
1847 ps->initialize();
1848 ps->reset();
1849 }
1850 Item::resetStats();
1851 // Désactive le profiling si demande spécifique
1852 if (want_specific_profiling)
1853 ps = nullptr;
1854 ProfilingSentryWithInitialize ps_sentry(ps);
1855 if (!m_specific_entry_point_name.null()){
1856 _callSpecificEntryPoint();
1857 is_end = true;
1858 }
1859 while (!is_end){
1860 if (max_loop!=0 && m_nb_loop>=max_loop){
1861 info()<<"===================================================";
1862 info()<<"====== MAXIMUM NUMBER OF ITERATION REACHED =======";
1863 info()<<"===================================================";
1864 is_end_by_max_loop = true;
1866 stopComputeLoop(false,false);
1867 break;
1868 }
1869 // Indique qu'on va s'arrêter par nombre max d'itération
1870 if (max_loop!=0 && (1+m_nb_loop)>=max_loop){
1872 }
1873 ret_val = doOneIteration();
1874 IMemoryInfo* mem_info = arcaneGlobalMemoryInfo();
1875 if (mem_info && mem_info->isCollecting()){
1876 mem_info->endCollect();
1878 mem_info->setIteration(iteration);
1879
1880 std::ostringstream ostr;
1881 if (iteration>0)
1882 mem_info->printAllocatedMemory(ostr,iteration-1);
1883 if (iteration>1)
1884 mem_info->printAllocatedMemory(ostr,iteration-2);
1885 if (iteration>4)
1886 mem_info->printAllocatedMemory(ostr,iteration-5);
1887 info() << "ITERATION_MemoryInfo: " << ostr.str();
1888 mem_info->beginCollect();
1889 }
1891 if (ret_val!=0)
1892 is_end = true;
1893 ++m_nb_loop;
1894 }
1895 }
1896 catch (const TimeoutException& ex){
1897 if (m_msg_pass_prof_srv.get())
1898 m_msg_pass_prof_srv->stopProfiling();
1900 pinfo() << "TIMEOUT " << Trace::Width(8) << pm->commRank() << "_RANK Infos:"<<ex.additionalInfo();
1901 traceMng()->flush();
1902 // Attend que tous les processeurs envoient le signal et affichent le
1903 // message précédent
1904 platform::sleep(40);
1905 throw;
1906 }
1907 if (m_verification_only_at_exit){
1908 info() << "Doing verification at exit";
1909 doVerification("AtExit");
1910 }
1911 {
1913 if (ps2)
1914 ps2->printInfos(true);
1915 }
1916 if (m_msg_pass_prof_srv.get())
1917 m_msg_pass_prof_srv->stopProfiling();
1918 if (IItemEnumeratorTracer::singleton())
1919 IItemEnumeratorTracer::singleton()->dumpStats();
1920 info() << "End of compute loop: reason=" << (int)m_stop_reason;
1921 if (is_end_by_max_loop)
1922 return 2;
1923 if (m_final_time_reached)
1924 return 1;
1925 if (ret_val<0){
1926 return ret_val;
1927 }
1928 return 0;
1929}
1930
1931/*---------------------------------------------------------------------------*/
1932/*---------------------------------------------------------------------------*/
1933
1934void TimeLoopMng::
1935_resetTimer() const
1936{
1937 if (m_alarm_timer_value>0)
1938 platform::resetAlarmTimer(m_alarm_timer_value);
1939}
1940
1941/*---------------------------------------------------------------------------*/
1942/*---------------------------------------------------------------------------*/
1943
1944} // End namespace Arcane
1945
1946/*---------------------------------------------------------------------------*/
1947/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer count() const
Nombre d'éléments de la collection.
Definition Collection.h:70
bool empty() const
True si la collection est vide.
Definition Collection.h:72
EnumeratorT< ICaseOptions * > Enumerator
Definition Collection.h:129
VariableScalarInt32 m_global_iteration
Itération courante.
Real globalTime() const
Temps courant.
Int32 globalIteration() const
Numéro de l'itération courante.
interval d'itérateurs constant
const String & additionalInfo() const
Retourne les infos supplémentaires.
Exception pour demander un retour-arrière de la boucle en temps.
Interface de l'application.
virtual IMainFactory * mainFactory() const =0
Manufacture principale.
virtual String userName() const =0
Nom de l'utilisateur.
Interface gérant les stratégies de retour-arrière.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
Interface d'une partie d'un jeu de données.
virtual String language() const =0
Langage utilisé dans le jeu de données.
Interface d'une classe gérant un document XML du jeu de données.
virtual XmlNode modulesElement()=0
Retourne l'élément contenant la description des modules.
Interface d'une fonction du jeu de données.
virtual void value(Real param, Real &v) const =0
Valeur v de l'option pour le paramètre param.
Interface du gestionnaire de cas.
Definition ICaseMng.h:56
virtual CaseOptionsCollection blocks() const =0
Collection des blocs d'options.
virtual ICaseDocument * caseDocument()=0
Document XML du jeu de données (peut être nul si pas de jeu de donneés)
Interface d'une liste d'options du jeu de données.
virtual ICaseFunction * activateFunction()=0
Fonction indiquant l'état d'activation de l'option.
virtual IModule * caseModule() const =0
Retourne le module associé ou nullptr s'il n'y en a pas.
virtual void merge(const IConfiguration *c)=0
Fusionne cette configuration avec la configuration c.
Interface du gestionnaire de point d'entrée.
virtual IEntryPoint * findEntryPoint(const String &s)=0
Point d'entrée de nom s.
virtual EntryPointCollection entryPoints()=0
Liste des points d'entrées.
Interface d'un point d'entrée d'un module.
Definition IEntryPoint.h:34
virtual void executeEntryPoint()=0
Appelle le point d'entrée.
virtual Real totalElapsedTime() const =0
Temps d'exécution passé (temps horloge) dans ce point d'entrée en (en milli-s)
static const char *const WComputeLoop
appelé pendant la boucle de calcul
Definition IEntryPoint.h:42
static const char *const WBuild
appelé pour la construction du module
Definition IEntryPoint.h:44
static const char *const WStartInit
appelé pendant l'initialisation d'un nouveau cas
Definition IEntryPoint.h:50
static const char *const WRestore
appelé pour restaurer les variables lors d'un retour arrière
Definition IEntryPoint.h:52
virtual Integer nbCall() const =0
Retourne le nombre de fois que le point d'entrée a été exécuté
static const char *const WOnMeshRefinement
appelé après un raffinement de maillage
Definition IEntryPoint.h:56
@ PAutoLoadEnd
Chargé automatiquement à la fin. Cela signifie qu'un module possédant un point d'entrée avec cette pr...
Definition IEntryPoint.h:80
@ PAutoLoadBegin
Chargé automatiquement au début. Cela signifie qu'un module possédant un point d'entrée avec cette pr...
Definition IEntryPoint.h:73
virtual int property() const =0
Retourne les propriétés du point d'entrée.
static const char *const WOnMeshChanged
appelé après un changement de maillage
Definition IEntryPoint.h:54
static const char *const WContinueInit
appelé pendant l'initialisation d'une reprise
Definition IEntryPoint.h:48
virtual String where() const =0
Retourne l'endroit ou est appelé le point d'entrée.
static const char *const WInit
appelé pendant l'initialisation
Definition IEntryPoint.h:46
virtual IModule * module() const =0
Retourne le module associé au point d'entrée.
virtual String name() const =0
Retourne le nom du point d'entrée.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual IVariableSynchronizer * allItemsSynchronizer()=0
Synchroniseur sur toutes les entités de la famille.
virtual IServiceLoader * createServiceLoader()=0
Crée une instance du chargeur de services.
virtual ITimeLoop * createTimeLoop(IApplication *sm, const String &name)=0
Crée une boucle en temps de nom name.
Interface d'un collecteur d'informations sur l'usage mémoire.
Definition IMemoryInfo.h:60
virtual void setIteration(Integer iteration)=0
Positionne le numéro de l'itération courante.
virtual void setStackTraceMinAllocSize(Int64 alloc_size)=0
Positionne la taille minimale des allocations dont on trace la pile d'appel.
virtual Integer nbCell()=0
Nombre de mailles du maillage.
Interface d'un partitionneur de maillage.
virtual void prepareForDump()=0
Prépare l'instance en vue d'une protection.
Informations sur la fabrique d'un module.
virtual String moduleName() const =0
Nom du module créé par cette fabrique.
virtual Ref< IModule > createModule(ISubDomain *parent, const MeshHandle &mesh_handle)=0
Créé un module.
virtual const IServiceInfo * serviceInfo() const =0
Informations sur le module pouvant être créé par cette fabrique.
Interface du gestionnaire de modules.
Definition IModuleMng.h:39
virtual ModuleCollection modules() const =0
Liste des modules.
Interface d'un module.
Definition IModule.h:39
virtual void setUsed(bool v)=0
Indique si un module est utilisé ou non (interne).
virtual String name() const =0
Nom du module.
virtual bool disabled() const =0
true si le module est désactivé
virtual void setDisabled(bool v)=0
Active ou désactive temporairement le module (interne).
Interface d'un observable.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual IParallelReplication * replication() const =0
Informations sur la réplication.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
virtual bool hasReplication() const =0
Indique si la réplication est active.
Interface d'un service de profiling.
virtual bool isInitialized() const
Indique si initialize() a déjà été appelé
virtual void initialize()=0
Initialise le service de profiling.
virtual void reset()=0
Remet à zéro les compteurs.
virtual void printInfos(bool dump_file=false)=0
Affiche les infos de profiling.
Interface des informations d'un service ou d'un module.
virtual String tagName(const String &lang) const =0
Nom de l'élément XML du service pour le langage lang. Si lang est nul, retourne le nom par défaut.
Interface de chargement des services.
virtual bool loadSingletonService(ISubDomain *sd, const String &name)=0
Charge le service singleton de sous-domaine de nom name.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
virtual IModuleMng * moduleMng()=0
Retourne le gestionnaire de modules.
virtual const CommonVariables & commonVariables() const =0
Informations sur les variables standards.
virtual IMesh * defaultMesh()=0
Maillage par défaut.
virtual ITimeStats * timeStats() const =0
Statistiques des temps d'exécution.
virtual IApplication * application()=0
Application.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual const IConfiguration * configuration() const =0
Configuration associée.
virtual IVariableMng * variableMng()=0
Retourne le gestionnaire de variables.
virtual IMainFactory * mainFactory()=0
Manufacture principale.
virtual ICaseMng * caseMng()=0
Retourne le gestionnaire du jeu de données.
Interface du gestionnaire de la boucle en temps.
Interface d'une boucle en temps.
Definition ITimeLoop.h:41
static const char * WRestore
appelé pour restaurer les variables lors d'un retour arrière
Definition ITimeLoop.h:54
virtual StringCollection optionalModulesName() const =0
Liste des noms des modules facultatifs.
static const char * WOnMeshChanged
appelé après un changement de maillage
Definition ITimeLoop.h:56
static const char * WExit
appelé lors de la terminaison du code.
Definition ITimeLoop.h:60
virtual StringCollection requiredModulesName() const =0
Liste des noms des modules obligatoires.
virtual TimeLoopSingletonServiceInfoCollection singletonServices() const =0
Liste services singletons.
static const char * WOnMeshRefinement
appelé après un raffinement de maillage
Definition ITimeLoop.h:58
static const char * WBuild
appelé lors de la lecture du jeu de données
Definition ITimeLoop.h:50
static const char * WComputeLoop
appelé pendant la boucle de calcul
Definition ITimeLoop.h:48
static const char * WInit
appelé pendant l'initialisation, l'initialisation d'une reprise ou d'un nouveau cas
Definition ITimeLoop.h:52
virtual String name() const =0
Nom de la boucle en temps.
virtual void dumpCurrentStats(const String &name)=0
Affiche les statistiques d'une action.
virtual void notifyNewIterationLoop()=0
Notifie qu'on commence une nouvelle itération de la boucle de calcul.
Interface du gestionnaire de traces.
virtual IVariableSynchronizerMng * synchronizerMng() const =0
Interface du gestionnaire de synchronisation des variables.
virtual void flushPendingStats()=0
Traite les statistiques en cours.
Interface d'un service de synchronisation de variable.
virtual Int32ConstArrayView communicatingRanks()=0
Rangs des sous-domaines avec lesquels on communique.
@ PNoReplicaSync
Indique que la variable n'a pas forcément la même valeur entre les réplicas.
Definition IVariable.h:161
@ PNoNeedSync
Indique que la variable n'est pas nécessairement synchronisée.
Definition IVariable.h:82
Ecrivain au format JSON.
Definition JSONWriter.h:33
ListEnumeratorT< IEntryPoint * > Enumerator
Definition List.h:243
Flot de sortie lié à une String.
Liste d'observables.
Classe permettant de démarrer et arrêter automatiquement un service.
T * get() const
Retourne l'objet référé par l'instance.
Definition Ptr.h:121
Référence à une instance.
InstanceType * get() const
Instance associée ou nullptr si aucune.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Classe utilitaire pour retrouver un ou plusieurs services implémentant l'interface InterfaceType.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:227
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:315
Infos d'un point d'entrée d'une boucle en temps.
Gestionnaire de la boucle en temps.
bool finalTimeReached() const override
Retourne true si le temps final est atteint.
IObservable * observable(eTimeLoopEventType type) override
Observable sur l'instance.
ModuleFactoryMap m_module_factory_map
Etat de tous les modules référencés.
std::map< String, ITimeLoop * > TimeLoopMap
Liste de boucles en temps.
TimeLoopMap m_time_loop_list
Liste des boucles en temps.
void registerActionMeshPartition(IMeshPartitionerBase *mesh_partitioner) override
Programme un repartitionnement du maillage avec l'outil de partition mesh_partitioner.
EntryPointCollection usedTimeLoopEntryPoints() override
Liste de tous les points d'entrée pour la boucle en temps actuelle.
void _processEntryPoints(EntryPointList &entry_points, const TimeLoopEntryPointInfoCollection &entry_points_info, const char *where)
Ajoute à la liste entry_points les points d'entrée proposés dans entry_points_info.
@ VerifSameReplica
Vérifie que les variables sont synchronisées.
@ VerifWrite
Indique qu'on génère des valeurs pour vérifier.
@ VerifNone
Indique qu'on ne fait pas de vérifications.
@ VerifRead
Indique qu'on relit et vérifie des valeurs.
ITimeLoop * createTimeLoop(const String &name) override
Crée une boucle en temps de nom name.
EntryPointList m_exit_entry_points
Liste des points d'entrée à exécuter à la terminaison.
EntryPointCollection loopEntryPoints() override
Retourne la liste des points d'entrée de type 'ComputeLoop' de la boucle en temps.
ITimeLoop * usedTimeLoop() const override
Retourne la boucle en temps utilisée.
EntryPointList m_on_mesh_changed_entry_points
Liste des points d'entrée à exécuter après un changement de maillage.
std::map< String, ModuleState > ModuleStateMap
Liste des états des modules.
ITimeLoop * m_default_time_loop
Boucle en temps par défaut.
void doVerification(const String &name) override
Effectue une vérification.
void stopComputeLoop(bool is_final_time, bool has_error) override
Indique que la boucle de calcul doit s'interrompre.
void execInitEntryPoints(bool is_continue) override
Exécute les points d'entrée d'initialisation.
IEntryPoint * nextEntryPoint() override
Retourne la fonction suivante à appeler.
bool _createModule(const String &module_name)
Crée un module à partir de son nom.
eTimeLoopStopReason stopReason() const override
Raison pour laquelle on arrête le code.
void doExecNextEntryPoint(bool &is_last) override
void execExitEntryPoints() override
Exécute les points d'entrée de terminaison.
static void _extractModuleAndEntryPointName(const String &timeloop_call_name, String &module_name, String &entry_point_name)
EntryPointList m_build_entry_points
Liste des points d'entrée à exécuter lors de la construction.
EntryPointList m_used_time_loop_entry_points
Liste de tous les points d'entrée de la boucle en temps utilisée.
Integer m_current_entry_point
Prochain point d'entrée à exécuter.
int doOneIteration() override
Lance l'exécution d'une itération de la boucle de calcul.
void execOnMeshRefinementEntryPoints() override
Exécute les points d'entrée après raffinement.
ISubDomain * subDomain() const override
< Retourne le gestionnaire du sous-domaine
bool m_verification_at_entry_point
Si vrai, effectue vérifications à chaque point d'entrée, sinon uniquement en fin d'itération.
void timeLoops(TimeLoopCollection &time_loops) const override
Retourne dans time_loops la liste des boucles en temps.
EntryPointList m_restore_entry_points
Liste des points d'entrée à exécuter lors d'un retour arrière.
EntryPointList m_on_mesh_refinement_entry_points
Liste des points d'entrée à exécuter après un raffinement.
ISubDomain * m_sub_domain
Gestionnaire du sous-domaine.
ModuleFactoryMap m_lang_module_factory_map
Liste des fabriques des modules.
Integer nbLoop() const override
Nombre de boucles de calcul (ComputeLoop) effectuées.
bool isDoingBackward() override
Vrai si on est actuellement dans un retour-arrière.
int doComputeLoop(Integer max_loop) override
Exécute la boucle de calcul.
void timeLoopsName(StringCollection &names) const override
Retourne dans names la liste des noms des boucles en temps.
void goBackward() override
Effectue un retour arrière.
void setStopReason(eTimeLoopStopReason reason) override
Positionne la raison pour laquelle on arrête le code.
EntryPointList m_loop_entry_points
Liste des points d'entrée à exécuter.
IEntryPointMng * m_entry_point_mng
Gestionnaire de points d'entrée.
EntryPointList m_init_entry_points
Liste des points d'entrée à exécuter à l'initialisation.
String m_specific_entry_point_name
Pour test, point d'entrée spécifique à appeler.
ModuleList m_list_execute_module
Liste des modules à éxécuter.
Real cpuTimeUsed() const override
Retourne le temps CPU utilisé en secondes.
void execBuildEntryPoints() override
Exécute les points d'entrée de construction.
void setBackwardSavePeriod(Integer n) override
Positionne la période entre deux sauvegarde pour le retour arrière. Si cette valeur est nulle,...
IEntryPoint * m_current_entry_point_ptr
Point d'entrée en cours d'exécution.
IBackwardMng * m_backward_mng
Gestionnaire du retour-arrière;.
ITimeLoop * m_used_time_loop
Boucle en temps utilisée.
void setUsedTimeLoop(const String &name) override
Positionne la boucle en temps à exécuter. Sélectionne la boucle en temps de nom name comme celle qui ...
eVerifType m_verif_type
Type de vérifications.
void _fillModuleStateMap(ITimeLoop *time_loop)
void _doMeshPartition()
Effectue un repartitionnement des maillages.
std::map< String, IModuleFactoryInfo * > ModuleFactoryMap
Liste des fabriques des modules indéxés par leur nom.
void execOnMeshChangedEntryPoints() override
Exécute les points d'entrée après rééquilibrage.
void _addExecuteEntryPoint(IEntryPoint *)
Ajoute un point d'entrée à exécuter.
IEntryPoint * currentEntryPoint() override
Retourne le point d'entrée en cours d'exécution ou 0 s'il n'y en a pas.
void _fillModuleFactoryMap()
Remplit m_module_factory_map avec la liste des fabriques disponibles.
void registerTimeLoop(ITimeLoop *timeloop) override
Enregistrement et choix de la boucle en temps.
Ref< IVerifierService > m_verifier_service
Liste des fabriques des modules dans la langue du JDD.
String m_verif_path
Répertoire de sauvegarde/lecture des verifs.
void setVerificationActive(bool is_active) override
Positionne l'état du mode de vérification.
Infos d'un service singleton d'une boucle en temps.
Postionne le nom de l'action en cours d'exécution.
Definition Timer.h:110
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
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Real lastActivationTime() const
Retourne le temps (en secondes) passé lors de la dernière activation du timer.
Definition Timer.h:219
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
TraceMessage logdate() const
Flot pour un message de log précédé de la date.
TraceMessage log() const
Flot pour un message de log.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
TraceMessage plog() const
Flot pour un message de log.
TraceMessage pwarning() const
Positionne une classe de message.
Formattage du flot en longueur.
Vecteur 1D de données avec sémantique par valeur (style STL).
Arguments des méthodes de VariableComparer.
void setMaxPrint(Int32 v)
Positionne le nombre d'erreurs à afficher dans le listing.
Classe pour effectuer des comparaisons entre les variables.
VariableComparerResults apply(IVariable *var, const VariableComparerArgs &compare_args)
Applique la comparaison compare_args à la variable var.
VariableComparerArgs buildForCheckIfSync()
Créé une comparaison pour vérifie qu'une variable est bien synchronisée.
Noeud d'un arbre DOM.
Definition XmlNode.h:51
XmlNode attr(const String &name, bool throw_exception=false) const
Retourne l'attribut de nom name.
Definition XmlNode.cc:248
String attrValue(const String &name, bool throw_exception=false) const
Valeur de l'attribut name.
Definition XmlNode.cc:225
bool null() const
Vrai si le noeud est nul.
Definition XmlNode.h:294
ConstIterT< XmlNode > const_iter
Type d'un itérateur constant sur tout le tableau.
Definition XmlNode.h:76
bool valueAsBoolean(bool throw_exception=false) const
Valeur du noeud convertie en booléan.
Definition XmlNode.cc:412
VariableRefScalarT< Integer > VariableScalarInteger
Variable scalaire de type entier.
Int64 toInt64(Real r)
Converti un Real en Int64.
Definition Convert.h:54
ARCCORE_BASE_EXPORT String timeToHourMinuteSecond(Real t)
Retourne un temps sous forme des heures, minutes et secondes.
IProfilingService * getProfilingService()
Service utilisé pour obtenir pour obtenir des informations de profiling.
void resetAlarmTimer(Integer nb_second)
Remet à timer d'alarme à nb_second.
ARCCORE_BASE_EXPORT bool recursiveCreateDirectory(const String &dir_name)
Créé un répertoire.
ARCCORE_BASE_EXPORT String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
ARCCORE_BASE_EXPORT void sleep(Integer nb_second)
Met le process en sommeil pendant nb_second secondes.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ SB_AllowNull
Autorise l'absence du service.
eTimeLoopStopReason
Raison pour laquelle on arrête le code.
@ MaxIterationReached
Arrêt car nombre d'itération maximal spécifié atteint.
@ NoStop
Indique qu'on n'est pas encore en mode d'arrête du code.
@ FinalTimeReached
Arrêt car temps final atteint.
@ NoReason
Pas de raison spécifique.
@ Error
Arrêt sur une erreur.
std::int64_t Int64
Type entier signé sur 64 bits.
eVariableComparerComputeDifferenceMethod
Méthode utilisée pour calculer la différence entre deux valeurs v1 et v2.
@ LocalNormMax
Utilise (v1-v2) / local_norm_max.
Int32 Integer
Type représentant un entier.
Collection< String > StringCollection
Collection de chaînes de caractères.
Definition UtilsTypes.h:593
List< IModule * > ModuleList
Tableau de modules.
List< IEntryPoint * > EntryPointList
Tableau de points d'entrées.
Collection< ICaseOptions * > CaseOptionsCollection
Collection d'options du jeu de données.
Collection< ITimeLoop * > TimeLoopCollection
Collection de boucles en temps.
Collection< IModuleFactoryInfo * > ModuleFactoryInfoCollection
Collection d'informations sur les fabriques de module.
double Real
Type représentant un réel.
Collection< IEntryPoint * > EntryPointCollection
Collection de points d'entrées.
@ DT_String
Donnée de type chaîne de caractère UTF-8.
Definition DataTypes.h:45