Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcaneMain.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* ArcaneMain.cc (C) 2000-2024 */
9/* */
10/* Classe gérant l'exécution. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/ArcaneMain.h"
15
16#include "arcane/utils/Iostream.h"
17#include "arcane/utils/StdHeader.h"
18#include "arcane/utils/List.h"
19#include "arcane/utils/Iterator.h"
20#include "arcane/utils/ScopedPtr.h"
21#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/FatalErrorException.h"
23#include "arcane/utils/ParallelFatalErrorException.h"
24#include "arcane/utils/OStringStream.h"
25#include "arcane/utils/ApplicationInfo.h"
26#include "arcane/utils/ValueConvert.h"
27#include "arcane/utils/ITraceMng.h"
28#include "arcane/utils/SignalException.h"
29#include "arcane/utils/TimeoutException.h"
30#include "arcane/utils/NotImplementedException.h"
31#include "arcane/utils/ArithmeticException.h"
32#include "arcane/utils/StringBuilder.h"
33#include "arcane/utils/IDynamicLibraryLoader.h"
34#include "arcane/utils/CheckedConvert.h"
35#include "arcane/utils/CommandLineArguments.h"
36#include "arcane/utils/ApplicationInfo.h"
37#include "arcane/utils/TestLogger.h"
38
39#include "arcane/core/ArcaneException.h"
40#include "arcane/core/IMainFactory.h"
41#include "arcane/core/IApplication.h"
42#include "arcane/core/IServiceLoader.h"
43#include "arcane/core/IParallelMng.h"
44#include "arcane/core/IParallelSuperMng.h"
45#include "arcane/core/IIOMng.h"
46#include "arcane/core/ISession.h"
47#include "arcane/core/ISubDomain.h"
48#include "arcane/core/IRessourceMng.h"
49#include "arcane/core/IModuleMng.h"
50#include "arcane/core/IModule.h"
51#include "arcane/core/IVariableMng.h"
52#include "arcane/core/VariableRef.h"
53#include "arcane/core/ITimeLoopMng.h"
54#include "arcane/core/ITimeLoop.h"
55#include "arcane/core/Directory.h"
56#include "arcane/core/XmlNodeList.h"
57#include "arcane/core/IXmlDocumentHolder.h"
58#include "arcane/core/ItemTypeMng.h"
59#include "arcane/core/ServiceUtils.h"
60#include "arcane/core/ICodeService.h"
61#include "arcane/core/CaseOptions.h"
62#include "arcane/core/VariableCollection.h"
63#include "arcane/core/ItemGroupImpl.h"
64#include "arcane/core/SubDomainBuildInfo.h"
65#include "arcane/core/ICaseMng.h"
66#include "arcane/core/DotNetRuntimeInitialisationInfo.h"
67#include "arcane/core/AcceleratorRuntimeInitialisationInfo.h"
68#include "arcane/core/ApplicationBuildInfo.h"
69
70#include "arcane/core/IServiceFactory.h"
71#include "arcane/core/IModuleFactory.h"
72
73#include "arcane/impl/TimeLoopReader.h"
74#include "arcane/impl/MainFactory.h"
75#include "arcane/impl/InternalInfosDumper.h"
76#include "arcane/impl/internal/ArcaneMainExecInfo.h"
77#include "arcane/impl/internal/ThreadBindingMng.h"
78
79#include "arcane/accelerator/core/internal/RegisterRuntimeInfo.h"
80
81#include <signal.h>
82#include <exception>
83#ifndef ARCANE_OS_WIN32
84#include <unistd.h>
85#include <sys/stat.h>
86#include <fcntl.h>
87#endif
88
89#include <set>
90#include <map>
91#include <chrono>
92
93#ifdef ARCANE_FLEXLM
94#include "arcane/impl/FlexLMTools.h"
95#endif
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99namespace Arcane
100{
102{
103 public:
104
105 List<IServiceFactoryInfo*> m_service_factory_infos;
106 List<IModuleFactoryInfo*> m_module_factory_infos;
107 List<IApplicationBuildInfoVisitor*> m_application_build_info_visitors;
108 ApplicationBuildInfo m_app_build_info;
109 DotNetRuntimeInitialisationInfo m_dotnet_init_info;
110 AcceleratorRuntimeInitialisationInfo m_accelerator_init_info;
111 bool m_has_dotnet_wrapper = false;
112 String m_dotnet_assembly;
113 String m_arcane_lib_path;
114 IDirectSubDomainExecuteFunctor* m_direct_exec_functor = nullptr;
116 std::atomic<Int32> m_nb_autodetect = 0;
121};
122} // namespace Arcane
123
124namespace
125{
126Arcane::ArcaneMainStaticInfo* global_static_info = nullptr;
127Arcane::ArcaneMainStaticInfo* _staticInfo()
128{
129 // TODO: voir s'il faut protéger en multi-threading.
130 if (!global_static_info)
131 global_static_info = new Arcane::ArcaneMainStaticInfo();
132 return global_static_info;
133}
134void _deleteStaticInfo()
135{
136 delete global_static_info;
137 global_static_info = nullptr;
138}
139} // namespace
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
144extern "C" void arcaneEndProgram()
145{
146 // Juste la pour faire un point d'entrée à third.
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
152extern "C" {
153typedef void (*fSignalFunc)(int);
154void arcaneSignalHandler(int);
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
160namespace Arcane
161{
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
166extern "C++" ARCANE_UTILS_EXPORT void
167arcaneRedirectSignals(fSignalFunc sig_func);
168
169extern "C++" ARCANE_UTILS_EXPORT void
170arcaneCallDefaultSignal(int val);
171
172extern "C++" ARCANE_UTILS_EXPORT void
173initializeStringConverter();
174
175extern "C++" ARCANE_IMPL_EXPORT IArcaneMain*
176createArcaneMainBatch(const ApplicationInfo& exe_info, IMainFactory*);
177
178extern "C++" ARCANE_IMPL_EXPORT IDynamicLibraryLoader*
179createGlibDynamicLibraryLoader();
180
181extern "C++" ARCANE_IMPL_EXPORT ICodeService*
182createArcaneCodeService(IApplication* app);
183
184extern "C++" ARCANE_UTILS_EXPORT void
185arcanePrintSpecificMemoryStats();
186
187std::atomic<Int32> ArcaneMain::m_nb_arcane_init(0);
188std::atomic<Int32> ArcaneMain::m_is_init_done(0);
189bool ArcaneMain::m_has_garbage_collector = false;
190bool ArcaneMain::m_is_master_io = true;
191bool ArcaneMain::m_is_use_test_logger = false;
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
197: public MainFactory
198{
199 public:
200
202 {
203 return createArcaneMainBatch(app_info, this);
204 }
205};
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
211{
212 public:
213
214 Impl(const ApplicationInfo& infos)
215 : m_app_info(infos)
216 , m_application_build_info(ArcaneMain::defaultApplicationBuildInfo())
219 {}
223 : m_app_info(infos)
224 , m_application_build_info(build_infos)
225 , m_dotnet_info(dotnet_info)
226 , m_accelerator_info(accelerator_info)
227 {}
228
229 public:
230
231 ApplicationInfo m_app_info;
232 ApplicationBuildInfo m_application_build_info;
234 AcceleratorRuntimeInitialisationInfo m_accelerator_info;
235 ThreadBindingMng m_thread_binding_mng;
236};
237
238/*---------------------------------------------------------------------------*/
239/*---------------------------------------------------------------------------*/
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
244void ArcaneMain::
245redirectSignals()
246{
247 bool redirect_signals = true;
248 String rv = platform::getEnvironmentVariable("ARCANE_REDIRECT_SIGNALS");
249 (void)builtInGetValue(redirect_signals, rv);
250 if (redirect_signals) {
251 arcaneRedirectSignals(arcaneSignalHandler);
252 }
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258void ArcaneMain::
259setUseTestLogger(bool v)
260{
261 m_is_use_test_logger = v;
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
269{
270 m_default_main_factory = mf;
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
277: public IFunctor
278{
279 public:
280
282 : m_app_info(app_info)
283 , m_exec_main(exec_main)
284 {
285 }
286
287 public:
288
289 void executeFunctor() override
290 {
291 StringList args;
292 m_app_info.args(args);
293 if (!m_exec_main->parseArgs(args))
294 m_exec_main->execute();
295 }
296
297 private:
298
299 const ApplicationInfo& m_app_info;
300 IArcaneMain* m_exec_main;
301};
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
312{
313 public:
314
315 Int32 check()
316 {
317 auto* x = _staticInfo();
318 if (x->m_nb_autodetect > 0)
319 return x->m_autodetect_return_value;
320
321 ArcaneMain::_setArcaneLibraryPath();
322
323 std::chrono::high_resolution_clock clock;
324
325 // TODO: rendre thread-safe
326 {
327 ArcaneMain::_checkAutoDetectMPI();
328
329 bool has_accelerator = false;
330 // Mesure le temps de l'initialisation.
331 // Comme ici on n'a pas encore initialié Arcane il ne faut
332 // pas utiliser de méthode du namespace 'platform'.
333 auto start_time = clock.now();
334 x->m_autodetect_return_value = ArcaneMain::_checkAutoDetectAccelerator(has_accelerator);
335 auto end_time = clock.now();
336 // Ne récupère le temps que si on a utilise un accélérateur
337 if (has_accelerator)
338 x->m_init_time_accelerator = _getTime(end_time,start_time);
339 ++x->m_nb_autodetect;
340 }
341 return x->m_autodetect_return_value;
342 }
343
344 template<typename TimeType>
345 Real _getTime(TimeType end_time,TimeType start_time)
346 {
347 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
348 Real x = static_cast<Real>(duration.count());
349 return x / 1.0e9;
350 }
351};
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
366{
367 if (m_exec_main)
368 return 0;
369
370 m_ret_val = 0;
371 m_clean_abort = false;
372
373 ArcaneMain::redirectSignals();
374
375 // Création de la classe d'exécution
376 try {
377 if (m_has_build_info) {
378 ArcaneMain* x = new ArcaneMain(m_app_info, m_main_factory,
379 m_application_build_info,
382 m_exec_main = x;
383 }
384 else {
385 m_exec_main = m_main_factory->createArcaneMain(m_app_info);
386 }
387 m_exec_main->build();
388 ArcaneMain::m_is_master_io = m_exec_main->application()->parallelSuperMng()->isMasterIO();
389 m_exec_main->initialize();
390 IArcaneMain::setArcaneMain(m_exec_main);
391 }
392 catch (const ArithmeticException& ex) {
393 cerr << "** CATCH ARITHMETIC_EXCEPTION\n";
394 return arcanePrintArcaneException(ex, nullptr);
395 }
396 catch (const Exception& ex) {
397 return arcanePrintArcaneException(ex, nullptr);
398 }
399 catch (const std::exception& ex) {
400 return arcanePrintStdException(ex, nullptr);
401 }
402 catch (...) {
403 return arcanePrintAnyException(nullptr);
404 }
405
406 // Redirige a nouveau les signaux car certaines
407 // routines d'initialisation (par exemple MPI) peuvent
408 // les detourner.
409 ArcaneMain::redirectSignals();
410
411 m_ret_val = 0;
412 m_clean_abort = false;
413
414#ifdef ARCANE_FLEXLM
415 try {
416 IApplication* app = m_exec_main->application();
417 ITraceMng* trace = app->traceMng();
418 IParallelSuperMng* parallel_super_mng = app->parallelSuperMng();
419 trace->info() << "Initializing license manager";
421
422 // La politique de licence parallèle est sous-traitée aux applications
423 // bool is_parallel = parallel_super_mng->isParallel();
424 // FlexLMTools<ArcaneFeatureModel> license_tool;
425 // Integer commSize = parallel_super_mng->commSize();
426 // if (is_parallel && commSize > 1)
427 // { // La fonctionnalité paralléle n'est activé que si nécessaire
428 // license_tool.getLicense(ArcaneFeatureModel::ArcaneParallel,commSize);
429 // }
430 }
431 catch (const Exception& ex) {
432 IApplication* app = m_exec_main->application();
433 ITraceMng* trace = app->traceMng();
434 m_ret_val = arcanePrintArcaneException(ex, trace);
435 if (ex.isCollective()) {
436 m_clean_abort = true;
437 }
438 }
439#endif
440 return 0;
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445// NOTE: Cette méthode ne doit pas lancer d'exceptions
446void ArcaneMainExecInfo::
447execute()
448{
449 if (m_ret_val != 0)
450 return;
451
452 if (m_direct_exec_functor)
453 m_exec_main->setDirectExecuteFunctor(m_direct_exec_functor);
454
456 if (ArcaneMain::m_exec_override_functor) {
457 // Obsolète. Ne plus utiliser.
458 IApplication* app = m_exec_main->application();
459 ArcaneMain::m_exec_override_functor->m_application = app;
460 ITraceMng* trace = app->traceMng();
461 trace->info() << "Calling overriding functor";
462 m_ret_val = ArcaneMain::callFunctorWithCatchedException(ArcaneMain::m_exec_override_functor->functor(),
463 m_exec_main, &m_clean_abort, true);
464 }
465 else
466 m_ret_val = ArcaneMain::callFunctorWithCatchedException(&exec_functor, m_exec_main, &m_clean_abort, true);
467}
468
469/*---------------------------------------------------------------------------*/
470/*---------------------------------------------------------------------------*/
471
472void ArcaneMainExecInfo::
473finalize()
474{
475 // Désactive les exceptions flottantes
476 platform::enableFloatingException(false);
477
478 // Si l'exécution s'est bien déroulée mais que l'utilisateur a spécifié un
479 // code d'erreur, on le récupère.
480 int exe_error_code = m_exec_main->errorCode();
481 if (m_ret_val == 0 && exe_error_code != 0) {
482 m_ret_val = exe_error_code;
483 }
484 else if (m_ret_val != 0)
485 m_exec_main->setErrorCode(m_ret_val);
486
487 m_exec_main->finalize();
488
489 if (m_ret_val != 0 && !m_clean_abort)
490 m_exec_main->doAbort();
491
492 // Destruction du code.
493 // Attention à ne pas détruire le gestionnaire avant car lorsqu'une exception
494 // de l'architecture est générée, elle utilise un ITraceMng pour afficher
495 // le message
496 delete m_exec_main;
497 m_exec_main = nullptr;
498#ifndef ARCANE_USE_MPC
499 IArcaneMain::setArcaneMain(m_exec_main);
500#endif
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
511{
512 if (!factory)
513 return 5;
514
516 int r = exec_info.initialize();
517 if (r != 0)
518 return r;
519
520 IDirectSubDomainExecuteFunctor* func = _staticInfo()->m_direct_exec_functor;
521 if (func)
522 exec_info.setDirectExecFunctor(func);
523 exec_info.execute();
524 exec_info.finalize();
525
526 return exec_info.returnValue();
527}
528
529/*---------------------------------------------------------------------------*/
530/*---------------------------------------------------------------------------*/
531
534 bool* clean_abort, bool is_print)
535{
536 int ret_val = 0;
537 *clean_abort = false;
538 IApplication* app = exec_main->application();
539 ITraceMng* trace = app->traceMng();
540 bool is_parallel = app->parallelSuperMng()->isParallel();
541 bool is_master = app->parallelSuperMng()->isMasterIO();
542 try {
543 functor->executeFunctor();
544 }
545 catch (const FatalErrorException& ex) {
546 if (ex.isCollective()) {
547 if (is_parallel) {
548 *clean_abort = true;
549 ret_val = 5;
550 if (is_master && is_print) {
551 std::ofstream ofile("fatal");
552 ofile << ret_val << '\n';
553 ofile.flush();
554 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
555 }
556 }
557 else {
558 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
559 ret_val = 4;
560 }
561 }
562 else {
563 trace->error() << Trace::Color::red() << "FatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
564 ret_val = 4;
565 }
566 }
567 catch (const SignalException& ex) {
568 trace->error() << "SignalException caught in ArcaneMain::callFunctor: " << ex << '\n';
569 ret_val = 6;
570 }
571 catch (const TimeoutException& ex) {
572 trace->error() << "TimeoutException caught in ArcaneMain::callFunctor: " << ex << '\n';
573 ret_val = 7;
574 }
575 catch (const ParallelFatalErrorException& ex) {
576 // TODO: utiliser le code de FatalErrorException en mode collectif.n
577 if (is_parallel) {
578 *clean_abort = true;
579 ret_val = 5;
580 if (is_master && is_print) {
581 std::ofstream ofile("fatal");
582 ofile << ret_val << '\n';
583 ofile.flush();
584 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
585 }
586 }
587 else {
588 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
589 ret_val = 4;
590 }
591 }
592 catch (const ArithmeticException& ex) {
593 cerr << "** ARITHMETIC EXCEPTION!\n";
594 ret_val = arcanePrintArcaneException(ex, trace);
595 if (ex.isCollective()) {
596 *clean_abort = true;
597 }
598 }
599 catch (const Exception& ex) {
600 ret_val = arcanePrintArcaneException(ex, trace);
601 if (ex.isCollective()) {
602 *clean_abort = true;
603 }
604 }
605 catch (const std::exception& ex) {
606 ret_val = arcanePrintStdException(ex, trace);
607 }
608 catch (...) {
609 ret_val = arcanePrintAnyException(trace);
610 }
611 return ret_val;
612}
613
614/*---------------------------------------------------------------------------*/
615/*---------------------------------------------------------------------------*/
616
617void ArcaneMain::
618_launchMissingInitException()
619{
620 cerr << "ArcaneMain: appel ArcaneMain::arcaneInitialize() manquant.\n";
621 throw std::exception();
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627void ArcaneMain::
628_checkHasInit()
629{
630 if (m_nb_arcane_init <= 0)
631 _launchMissingInitException();
632}
633
634/*---------------------------------------------------------------------------*/
635/*---------------------------------------------------------------------------*/
636
637extern "C++" void arcaneInitCheckMemory();
638extern "C++" void arcaneExitCheckMemory();
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
642
645{
646 if (m_nb_arcane_init != 0) {
647 cerr << "WARNING: ArcaneMain::setHasGarbageCollector has to be called before arcaneInitialize\n";
648 return;
649 }
650 m_has_garbage_collector = true;
651}
652
653/*---------------------------------------------------------------------------*/
654/*---------------------------------------------------------------------------*/
655
658{
659 if (m_nb_arcane_init != 0) {
660 cerr << "WARNING: ArcaneMain::setHasDotNETRuntime has to be called before arcaneInitialize\n";
661 return;
662 }
664}
665
666/*---------------------------------------------------------------------------*/
667/*---------------------------------------------------------------------------*/
668
671{
672 m_exec_override_functor = functor;
673}
674
675/*---------------------------------------------------------------------------*/
676/*---------------------------------------------------------------------------*/
677
680{
681 return _staticInfo()->m_has_dotnet_wrapper;
682}
683
684/*---------------------------------------------------------------------------*/
685/*---------------------------------------------------------------------------*/
686/*
687 * \brief Positionne le chemin contenant les bibliothèques dynamiques de Arcane.
688 *
689 * Il ne faut appeler qu'une seule fois cette méthode.
690 */
691void ArcaneMain::
692_setArcaneLibraryPath()
693{
696 if (!dll_full_path.null())
697 dir_name = platform::getFileDirName(dll_full_path);
698 if (dir_name.null())
699 dir_name = platform::getCurrentDirectory();
700 _staticInfo()->m_arcane_lib_path = dir_name;
701}
702
703/*---------------------------------------------------------------------------*/
704/*---------------------------------------------------------------------------*/
705
706void ArcaneMain::
707_checkCreateDynamicLibraryLoader()
708{
710 if (!x) {
711 platform::setDynamicLibraryLoader(createGlibDynamicLibraryLoader());
712 }
713}
714
715/*---------------------------------------------------------------------------*/
716/*---------------------------------------------------------------------------*/
717
720{
721 // Le premier thread qui arrive ici fait l'init.
722 // Les autres doivent attendre que l'init soit terminée.
723 if (m_nb_arcane_init.fetch_add(1) == 0) {
724 (void)_staticInfo();
725 Exception::staticInit();
726 dom::DOMImplementation::initialize();
728 // Crée le singleton gestionnaire des types
730 initializeStringConverter();
731 arcaneInitCheckMemory();
732 // Initialise le singleton du groupe vide et garde une référence dessus.
734 _checkCreateDynamicLibraryLoader();
735 m_is_init_done = 1;
736 }
737 else
738 // Attend que le thread qui fait l'init ait terminé
739 while (m_is_init_done.load() == 0)
740 ;
741}
742
743/*---------------------------------------------------------------------------*/
744/*---------------------------------------------------------------------------*/
745
748{
749 _checkHasInit();
750
751 if (m_nb_arcane_init.fetch_sub(1) == 1) {
753
756
757 {
759 if (x) {
760 x->closeLibraries();
761 delete x;
763 }
764 }
765 arcanePrintSpecificMemoryStats();
766 arcaneExitCheckMemory();
768 dom::DOMImplementation::terminate();
770 arcaneEndProgram();
771#ifdef ARCANE_FLEXLM
772 {
773 FlexLMMng::instance()->releaseAllLicenses();
774 }
775#endif
776 m_is_init_done = 0;
777 }
778}
779
780/*---------------------------------------------------------------------------*/
781/*---------------------------------------------------------------------------*/
782
785{
786 _staticInfo()->m_service_factory_infos.add(sri);
787}
788
789/*---------------------------------------------------------------------------*/
790/*---------------------------------------------------------------------------*/
791
794{
795 _staticInfo()->m_module_factory_infos.add(mfi);
796}
797
798/*---------------------------------------------------------------------------*/
799/*---------------------------------------------------------------------------*/
800
803{
804 _staticInfo()->m_application_build_info_visitors.add(visitor);
805}
806
807/*---------------------------------------------------------------------------*/
808/*---------------------------------------------------------------------------*/
809
812{
813 return _staticInfo()->m_app_build_info._internalApplicationInfo();
814}
815
816/*---------------------------------------------------------------------------*/
817/*---------------------------------------------------------------------------*/
818
824
825/*---------------------------------------------------------------------------*/
826/*---------------------------------------------------------------------------*/
827
833
834/*---------------------------------------------------------------------------*/
835/*---------------------------------------------------------------------------*/
836
839{
840 return _staticInfo()->m_app_build_info;
841}
842
843/*---------------------------------------------------------------------------*/
844/*---------------------------------------------------------------------------*/
845
848{
849 return m_p->m_application_build_info;
850}
851
852/*---------------------------------------------------------------------------*/
853/*---------------------------------------------------------------------------*/
854
855ApplicationBuildInfo& ArcaneMain::
856_applicationBuildInfo()
857{
858 return m_p->m_application_build_info;
859}
860
861/*---------------------------------------------------------------------------*/
862/*---------------------------------------------------------------------------*/
863
866{
867 return m_p->m_dotnet_info;
868}
869
870/*---------------------------------------------------------------------------*/
871/*---------------------------------------------------------------------------*/
872
875{
876 return m_p->m_accelerator_info;
877}
878
879/*---------------------------------------------------------------------------*/
880/*---------------------------------------------------------------------------*/
881
884{
885 return _staticInfo()->m_init_time_accelerator;
886}
887
888/*---------------------------------------------------------------------------*/
889/*---------------------------------------------------------------------------*/
890
893{
894 _checkHasInit();
895
897 if (!factory) {
898 factory = m_default_main_factory;
899 if (!factory) {
900 factory = new ArcaneBatchMainFactory();
901 default_factory = factory;
902 }
903 }
904
905 int ret = _arcaneMain(app_info, factory);
906
907 default_factory = nullptr;
908
909 // Le code d'erreur 5 représente une erreur en parallèle pour tous les
910 // processeurs.
911 if (ret != 0 && ret != 5)
912 cerr << "* Process return: " << ret << '\n';
913 if (ret == 5)
914 ret = 4;
915
916 return ret;
917}
918
919/*---------------------------------------------------------------------------*/
920/*---------------------------------------------------------------------------*/
921
922int ArcaneMain::
924{
925 _staticInfo()->m_direct_exec_functor = func;
926 return run();
927}
928
929/*---------------------------------------------------------------------------*/
930/*---------------------------------------------------------------------------*/
931
932int ArcaneMain::
933_checkTestLoggerResult()
934{
935 if (!m_is_use_test_logger)
936 return 0;
937 if (!m_is_master_io)
938 return 0;
939 return TestLogger::compare();
940}
941
942/*---------------------------------------------------------------------------*/
943/*---------------------------------------------------------------------------*/
944
945int ArcaneMain::
946_initRuntimes()
947{
948 ArcaneMainAutoDetectRuntimeHelper auto_detect_helper;
949 return auto_detect_helper.check();
950}
951
952/*---------------------------------------------------------------------------*/
953/*---------------------------------------------------------------------------*/
954
956run()
957{
958 int r = _initRuntimes();
959 if (r != 0)
960 return r;
961
963
964 // Si on arrive ici et que le runtime C# est déjà chargé
965 // (parce que le Main est en C# par exemple), on ne lance pas le wrapper
967 if (!is_in_dotnet && dotnet_info.isUsingDotNetRuntime()) {
968 r = _runDotNet();
969 // Avant la version 3.7.8 on n'appelait par arcaneFinalize() car cela pouvait
970 // poser des problèmes avec le Garbage Collector de '.Net'. Normalement ces
971 // problèmes sont corrigés mais on autorise le comportement d'avant au cas où.
972 bool do_finalize = false;
973 String x = platform::getEnvironmentVariable("ARCANE_DOTNET_USE_LEGACY_DESTROY");
974 if (x == "1")
975 do_finalize = false;
976 if (x == "0")
977 do_finalize = true;
978 if (do_finalize)
980 }
981 else {
983 r = arcaneMain(defaultApplicationInfo(), nullptr);
985 }
986 if (r != 0)
987 return r;
988 return _checkTestLoggerResult();
989}
990
991/*---------------------------------------------------------------------------*/
992/*---------------------------------------------------------------------------*/
993
994int ArcaneMain::
995_runDotNet()
996{
997 auto si = _staticInfo();
998 si->m_has_dotnet_wrapper = true;
999
1000 // TODO: vérifier que l'init n'a pas été faite.
1001
1002 // Pour pouvoir exécuter le code .Net, il faut
1003 // appeler la méthode 'arcane_mono_main' qui se trouve
1004 // dans la bibliothèque dynamique 'arcane_mono'.
1005
1007
1010
1011 DotNetMainFunctor my_functor = nullptr;
1012 String os_dir(si->m_arcane_lib_path);
1013
1014 try {
1015 _checkCreateDynamicLibraryLoader();
1016
1018 if (!dll_loader)
1019 ARCANE_FATAL("No dynamic library available for running .Net");
1020
1021 String dll_name = "arcane_mono";
1022 String symbol_name = "arcane_mono_main2";
1023
1024 String runtime_name = dotnet_info.embeddedRuntime();
1025
1026 if (runtime_name.null() || runtime_name == "mono")
1027 // Mono est le défaut si rien n'est spécifié.
1028 ;
1029 else if (runtime_name == "coreclr") {
1030 dll_name = "arcane_dotnet_coreclr";
1031 symbol_name = "arcane_dotnet_coreclr_main";
1032 }
1033 else
1034 ARCANE_FATAL("Unknown '.Net' runtime '{0}'. Valid values are 'mono' or 'coreclr'", runtime_name);
1035
1036 IDynamicLibrary* dl = dll_loader->open(os_dir, dll_name);
1037 if (!dl)
1038 ARCANE_FATAL("Can not found dynamic library '{0}' for using .Net", dll_name);
1039
1040 bool is_found = false;
1041 void* functor_addr = dl->getSymbolAddress(symbol_name, &is_found);
1042 if (!is_found)
1043 ARCANE_FATAL("Can not find symbol '{0}' in library '{1}'", symbol_name, dll_name);
1044
1045 my_functor = reinterpret_cast<DotNetMainFunctor>(functor_addr);
1046 }
1047 catch (const Exception& ex) {
1048 return arcanePrintArcaneException(ex, nullptr);
1049 }
1050 catch (const std::exception& ex) {
1051 return arcanePrintStdException(ex, nullptr);
1052 }
1053 catch (...) {
1054 return arcanePrintAnyException(nullptr);
1055 }
1056
1057 if (my_functor) {
1058 const CommandLineArguments& cmd_args = app_info.commandLineArguments();
1059 // TODO: vérifier que l'assembly 'Arcane.Main.dll' existe bien.
1060 String new_name = os_dir + "/Arcane.Main.dll";
1061 return (*my_functor)(cmd_args, new_name);
1062 }
1063 return (-1);
1064}
1065
1066/*---------------------------------------------------------------------------*/
1067/*---------------------------------------------------------------------------*/
1068// Ne pas appeler directement mais passer par ArcaneMainAutoDetectHelper.
1069void ArcaneMain::
1070_checkAutoDetectMPI()
1071{
1072 // N'active pas MPI si on utilise le service de parallélisme 'Sequential'
1073 String mp_service = defaultApplicationInfo().commandLineArguments().getParameter("MessagePassingService");
1074 if (mp_service=="Sequential")
1075 return;
1076
1077 auto si = _staticInfo();
1078 // Pour pouvoir automatiquement enregisrer MPI, il faut
1079 // appeler la méthode 'arcaneAutoDetectMessagePassingServiceMPI' qui se trouve
1080 // dans la bibliothèque dynamique 'arcane_mpi'.
1081
1082 typedef void (*ArcaneAutoDetectMPIFunctor)();
1083
1084 _checkCreateDynamicLibraryLoader();
1085
1086 IDynamicLibraryLoader* dll_loader = platform::getDynamicLibraryLoader();
1087 if (!dll_loader)
1088 return;
1089
1090 String os_dir(si->m_arcane_lib_path);
1091 String dll_name = "arcane_mpi";
1092 String symbol_name = "arcaneAutoDetectMessagePassingServiceMPI";
1093 IDynamicLibrary* dl = dll_loader->open(os_dir, dll_name);
1094 if (!dl)
1095 return;
1096
1097 bool is_found = false;
1098 void* functor_addr = dl->getSymbolAddress(symbol_name, &is_found);
1099 if (!is_found)
1100 return;
1101
1102 auto my_functor = reinterpret_cast<ArcaneAutoDetectMPIFunctor>(functor_addr);
1103 if (my_functor)
1104 (*my_functor)();
1105}
1106
1107/*---------------------------------------------------------------------------*/
1108/*---------------------------------------------------------------------------*/
1121{
1122 has_accelerator = false;
1123
1124 auto si = _staticInfo();
1125 AcceleratorRuntimeInitialisationInfo& init_info = si->m_accelerator_init_info;
1126 if (!init_info.isUsingAcceleratorRuntime())
1127 return 0;
1128 String runtime_name = init_info.acceleratorRuntime();
1129 if (runtime_name.empty())
1130 return 0;
1131
1132 try {
1133 // Pour l'instant, seul les runtimes 'cuda' et 'hip' sont autorisés
1134 if (runtime_name != "cuda" && runtime_name != "hip" && runtime_name != "sycl")
1135 ARCANE_FATAL("Invalid accelerator runtime '{0}'. Only 'cuda', 'hip' or 'sycl' is allowed", runtime_name);
1136
1137 // Pour pouvoir automatiquement enregisrer un runtime accélérateur de nom \a NAME,
1138 // il faut appeler la méthode 'arcaneRegisterAcceleratorRuntime${NAME}' qui se trouve
1139 // dans la bibliothèque dynamique 'arcane_${NAME}'.
1140
1142
1143 _checkCreateDynamicLibraryLoader();
1144
1146 if (!dll_loader)
1147 ARCANE_FATAL("No dynamic library available for running accelerator runtime");
1148
1149 String os_dir(si->m_arcane_lib_path);
1150 String dll_name = "arcane_accelerator_" + runtime_name + "_runtime";
1151 String symbol_name = "arcaneRegisterAcceleratorRuntime" + runtime_name;
1153 if (!dl)
1154 ARCANE_FATAL("Can not found dynamic library '{0}' for using accelerator runtime", dll_name);
1155
1156 bool is_found = false;
1157 void* functor_addr = dl->getSymbolAddress(symbol_name, &is_found);
1158 if (!is_found || !functor_addr)
1159 ARCANE_FATAL("Can not find symbol '{0}' in library '{1}'", symbol_name, dll_name);
1160
1163
1164 String verbose_str = Arcane::platform::getEnvironmentVariable("ARCANE_DEBUG_ACCELERATOR");
1165 if (!verbose_str.null())
1166 runtime_info.setVerbose(true);
1167
1168 (*my_functor)(runtime_info);
1169 has_accelerator = true;
1170 }
1171 catch (const Exception& ex) {
1172 return arcanePrintArcaneException(ex, nullptr);
1173 }
1174 catch (const std::exception& ex) {
1175 return arcanePrintStdException(ex, nullptr);
1176 }
1177 catch (...) {
1178 return arcanePrintAnyException(nullptr);
1179 }
1180 return 0;
1181}
1182
1183/*---------------------------------------------------------------------------*/
1184/*---------------------------------------------------------------------------*/
1185
1186/*---------------------------------------------------------------------------*/
1187/*---------------------------------------------------------------------------*/
1188
1189IMainFactory* ArcaneMain::m_default_main_factory = nullptr;
1190ArcaneMainExecutionOverrideFunctor* ArcaneMain::m_exec_override_functor = nullptr;
1191
1192/*---------------------------------------------------------------------------*/
1193/*---------------------------------------------------------------------------*/
1194
1195ArcaneMain::
1196ArcaneMain(const ApplicationInfo& app_info, IMainFactory* factory)
1197: m_p(new Impl(app_info))
1198, m_main_factory(factory)
1199{
1200}
1201
1202/*---------------------------------------------------------------------------*/
1203/*---------------------------------------------------------------------------*/
1204
1205ArcaneMain::
1206ArcaneMain(const ApplicationInfo& app_info, IMainFactory* factory,
1207 const ApplicationBuildInfo& app_build_info,
1208 const DotNetRuntimeInitialisationInfo& dotnet_info,
1209 const AcceleratorRuntimeInitialisationInfo& accelerator_info)
1210: m_p(new Impl(app_info, app_build_info, dotnet_info, accelerator_info))
1211, m_main_factory(factory)
1212{
1213}
1214
1215/*---------------------------------------------------------------------------*/
1216/*---------------------------------------------------------------------------*/
1217
1218ArcaneMain::
1219~ArcaneMain()
1220{
1221 delete m_application;
1222 delete m_p;
1223}
1224
1225/*---------------------------------------------------------------------------*/
1226/*---------------------------------------------------------------------------*/
1227
1228/*---------------------------------------------------------------------------*/
1229/*---------------------------------------------------------------------------*/
1230
1232build()
1233{
1234 _parseApplicationBuildInfoArgs();
1235 m_application = m_main_factory->createApplication(this);
1236 m_p->m_thread_binding_mng.initialize(m_application->traceMng(),
1237 m_p->m_application_build_info.threadBindingStrategy());
1238}
1239
1240/*---------------------------------------------------------------------------*/
1241/*---------------------------------------------------------------------------*/
1242
1244applicationInfo() const
1245{
1246 return m_p->m_app_info;
1247}
1248
1249/*---------------------------------------------------------------------------*/
1250/*---------------------------------------------------------------------------*/
1251
1252void ArcaneMain::
1253_parseApplicationBuildInfoArgs()
1254{
1255 ApplicationBuildInfo& abi = _applicationBuildInfo();
1256 abi.parseArguments(m_p->m_app_info.commandLineArguments());
1257 // Appelle les visiteurs enregistrés.
1258 {
1259 auto& x = _staticInfo()->m_application_build_info_visitors;
1260 for (IApplicationBuildInfoVisitor* v : x) {
1261 if (v)
1262 v->visit(abi);
1263 }
1264 }
1265 abi.setDefaultServices();
1266}
1267
1268/*---------------------------------------------------------------------------*/
1269/*---------------------------------------------------------------------------*/
1270
1272initialize()
1273{
1274 m_application->initialize();
1275
1277 service_loader->loadApplicationServices(m_application);
1278}
1279
1280/*---------------------------------------------------------------------------*/
1281/*---------------------------------------------------------------------------*/
1282
1285{
1286 return _staticInfo()->m_service_factory_infos;
1287}
1288
1289/*---------------------------------------------------------------------------*/
1290/*---------------------------------------------------------------------------*/
1291
1294{
1295 return _staticInfo()->m_module_factory_infos;
1296}
1297
1298/*---------------------------------------------------------------------------*/
1299/*---------------------------------------------------------------------------*/
1300
1302execute()
1303{
1304 return 0;
1305}
1306
1307/*---------------------------------------------------------------------------*/
1308/*---------------------------------------------------------------------------*/
1309
1311doAbort()
1312{
1313 ::abort();
1314}
1315
1316/*---------------------------------------------------------------------------*/
1317/*---------------------------------------------------------------------------*/
1318
1321{
1322 m_error_code = errcode;
1323 if (errcode != 0) {
1324 // Seul le proc maitre écrit le fichier sauf s'il s'agit d'un fatal car
1325 // dans ce cas n'importe quel PE peut le faire.
1326 if (ArcaneMain::m_is_master_io || errcode == 4) {
1327 String errname = "fatal_" + String::fromNumber(errcode);
1328 std::ofstream ofile(errname.localstr());
1329 ofile.close();
1330 }
1331 }
1332}
1333
1334/*---------------------------------------------------------------------------*/
1335/*---------------------------------------------------------------------------*/
1336
1339{
1340 // Si vrai, affichage des informations internes
1341 bool arcane_internal = false;
1342 // Si vrai, affichage des informations internes pour chaque boucle en temps
1343 bool arcane_all_internal = false;
1344 // Si vrai, génère un fichier contenant les infos internes du code.
1345 bool arcane_database = false;
1346 // Si vrai, affichage des informations sur les modules et services présents et une aide sommaire
1347 bool arcane_help = false;
1348
1349 String us_arcane_opt("-arcane_opt");
1350 String us_help("help");
1351 String us_arcane_internal("arcane_internal");
1352 String us_arcane_all_internal("arcane_all_internal");
1353 String us_arcane_database("arcane_database");
1354
1356 for (Integer i = 0, s = args.count(); i < s; ++i) {
1357 if (args[i].startsWith("-A")) {
1358 continue;
1359 }
1360 if (args[i] != us_arcane_opt) {
1361 unknown_args.add(args[i]);
1362 continue;
1363 }
1364 bool is_valid_opt = false;
1365 ++i;
1366 String str;
1367 if (i < s)
1368 str = args[i];
1369 if (str == us_arcane_internal) {
1370 arcane_internal = true;
1371 is_valid_opt = true;
1372 }
1373 if (str == us_arcane_all_internal) {
1374 arcane_all_internal = true;
1375 is_valid_opt = true;
1376 }
1377 if (str == us_arcane_database) {
1378 arcane_database = true;
1379 is_valid_opt = true;
1380 }
1381 if (str == us_help) {
1382 arcane_help = true;
1383 is_valid_opt = true;
1384 }
1385 if (!is_valid_opt) {
1386 // Si l'option n'est pas valide, la rajoute à la liste des options
1387 // non traitées
1389 if (!str.null())
1390 unknown_args.add(str);
1391 //trace->fatal() << "Unknown arcane option <" << str << ">\n";
1392 }
1393 }
1394
1395 bool do_stop = false;
1396 if (arcane_database) {
1398 dumper.dumpArcaneDatabase();
1399 do_stop = true;
1400 }
1401 if (arcane_internal) {
1403 dumper.dumpInternalInfos();
1404 do_stop = true;
1405 }
1406 if (arcane_all_internal) {
1408 dumper.dumpInternalAllInfos();
1409 do_stop = true;
1410 }
1411 if (arcane_help) {
1412 _dumpHelp();
1413 do_stop = true;
1414 }
1415
1416 args.clear();
1418 args.add(*i);
1419
1420 return do_stop;
1421}
1422
1423/*---------------------------------------------------------------------------*/
1424/*---------------------------------------------------------------------------*/
1425
1426void ArcaneMain::
1427_dumpHelp()
1428{
1429 // Utilise un multimap car plusieurs services peuvent avoir le même nom.
1430 typedef std::multimap<String, IServiceInfo*> ServiceList;
1432 Integer max_name_size = 0;
1433
1434 {
1435 // On veut lister par IServiceInfo. Comme il est possible qu'un service ait plusieurs
1436 // fabriques, on filtre grâce à done_set.
1437 std::set<IServiceInfo*> done_set;
1438 for (ServiceFactory2Collection::Enumerator j(application()->serviceFactories2()); ++j;) {
1439 IServiceInfo* si = (*j)->serviceInfo();
1440 if (done_set.find(si) != done_set.end()) {
1441 continue;
1442 }
1443 done_set.insert(si);
1444 const String& name = si->localName();
1445 max_name_size = math::max(max_name_size, CheckedConvert::toInteger(name.length()));
1446 service_list.insert(std::make_pair(name, si));
1447 }
1448 }
1449
1450 UniqueArray<String> module_names;
1451 for (EnumeratorT<IModuleFactoryInfo*> e = application()->moduleFactoryInfos(); ++e;) {
1452 IModuleFactoryInfo* mfi = (*e);
1453 const String& name = mfi->moduleName();
1454 max_name_size = math::max(max_name_size, CheckedConvert::toInteger(name.length()));
1455 module_names.add(name);
1456 }
1457
1458 ITraceMng* trace = application()->traceMng();
1459 trace->info() << " ";
1460 trace->info() << std::setw(max_name_size) << "Module List";
1461 trace->info() << std::setw(max_name_size) << "-------------"
1462 << "--";
1463 for (int i = 0, n = module_names.size(); i < n; ++i) {
1464 trace->info() << std::setw(max_name_size) << module_names[i];
1465 }
1466
1467 trace->info() << " ";
1468 trace->info() << std::setw(max_name_size) << "Service List";
1469 trace->info() << std::setw(max_name_size) << "--------------"
1470 << "--";
1471 for (ServiceList::const_iterator i = service_list.begin(); i != service_list.end(); ++i) {
1472 IServiceInfo* si = i->second;
1473 OStringStream oss;
1474 oss() << std::setw(max_name_size) << i->first;
1475 StringCollection interfaces = si->implementedInterfaces();
1476 if (!interfaces.empty())
1477 oss() << " Implements : ";
1478 for (EnumeratorT<String> e(interfaces.enumerator()); ++e;) {
1479 oss() << e.current() << " ";
1480 }
1481 trace->info() << oss.str();
1482 }
1483
1484 const Integer option_size = 20;
1485 trace->info() << " ";
1486 trace->info() << std::setw(max_name_size) << "Usage";
1487 trace->info() << std::setw(max_name_size) << "-------"
1488 << "--";
1489 trace->info() << application()->applicationName() << ".exe [-arcane_opt OPTION] dataset_file.arc";
1490 trace->info() << "Where OPTION is";
1491 trace->info() << std::setw(option_size) << "help"
1492 << " : this help page and abort";
1493 trace->info() << std::setw(option_size) << "arcane_internal"
1494 << " : save into a file internal Arcane informations and abort execution";
1495 trace->info() << std::setw(option_size) << "arcane_all_internal"
1496 << " : save into a file timeloop informations and abort execution";
1497 trace->info() << std::setw(option_size) << "arcane_database"
1498 << " : save internal database infos in file 'arcane_database.json'";
1499 trace->info() << std::setw(option_size) << "init_only"
1500 << " : only run initialization step";
1501 trace->info() << std::setw(option_size) << "continue"
1502 << " : continue an interrupted run";
1503 trace->info() << std::setw(option_size) << "max_iteration"
1504 << " : define maximum iteration number";
1505 trace->info() << std::setw(option_size) << "casename"
1506 << " : define case name";
1507}
1508
1509/*---------------------------------------------------------------------------*/
1510/*---------------------------------------------------------------------------*/
1516extern "C" void
1518{
1519 const char* signal_str = "Unknown";
1520 bool is_alarm = false;
1522
1523 switch (val) {
1524 case SIGSEGV:
1525 signal_str = "Segmentation Fault";
1526 break;
1527 case SIGFPE:
1528 signal_str = "Floating exception";
1529 break;
1530#ifdef SIGBUS
1531 case SIGBUS:
1532 signal_str = "Bus Error";
1533 break;
1534#endif
1535#ifdef SIGSYS
1536 case SIGSYS:
1537 signal_str = "System signal";
1538 break;
1539#endif
1540#ifdef SIGPIPE
1541 case SIGPIPE:
1542 signal_str = "Broken pipe";
1543 break;
1544#endif
1545#ifdef SIGALRM
1546 case SIGALRM:
1547 signal_str = "Sigalarm";
1548 is_alarm = true;
1549 break;
1550#endif
1551#ifdef SIGVTALRM
1552 case SIGVTALRM:
1553 signal_str = "Sigalarm(VirtualTime)";
1555 is_alarm = true;
1556 break;
1557#endif
1558 }
1559
1560 cerr << "Signal Caught !!! number=" << val << " name=" << signal_str << ".\n";
1561#ifdef ARCANE_DEBUG
1562 //arcaneDebugPause("SIGNAL");
1563#endif
1564
1565#ifndef ARCANE_OS_WIN32
1566 // Pour éviter que tous les PE écrivent le même fichier pour les SIGALRM,
1567 // seul le proc maitre le fait. Dans le cas des autres signaux, tout le monde
1568 // le fait.
1569 bool create_file = ArcaneMain::isMasterIO() || (!is_alarm);
1570 if (create_file) {
1571 // Crée le fichier 'signal_*' pour indiquer en parallèle qu'un
1572 // signal a été envoyé
1573 mode_t mode = S_IRUSR | S_IWUSR;
1574 char path[256];
1575 sprintf(path, "signal_%d", written_signal_number);
1576 path[255] = '\0';
1577 int fd = ::open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
1578 if (fd != (-1))
1579 ::close(fd);
1580 }
1581#endif
1582
1583 // Repositionne les signaux pour la prochaine fois, si le signal est
1584 // un signal qui peut être reçu plusieurs fois.
1585 arcaneRedirectSignals(arcaneSignalHandler);
1586
1587 Arcane::arcaneCallDefaultSignal(val);
1588 //::exit(val);
1589}
1590
1591/*---------------------------------------------------------------------------*/
1592/*---------------------------------------------------------------------------*/
1593
1594} // End namespace Arcane
1595
1596/*---------------------------------------------------------------------------*/
1597/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Informations pour initialiser le runtime accélérateur.
Informations pour construire une instance de IApplication.
String threadBindingStrategy() const
Stratégie pour punaiser les threads des tâches.
Informations sur une application.
const CommandLineArguments & commandLineArguments() const
Arguments de la ligne de commande.
void args(StringList &args) const
Remplit args avec les arguments de la ligne de commande.
IArcaneMain * createArcaneMain(const ApplicationInfo &app_info) override
Crée une instance de IArcaneMain.
Classe pour gérer les appels aux mécanismes d'auto-détection des runtimes (MPI,Accélérateurs).
void executeFunctor() override
Exécute la méthode associé
int initialize()
Création de l'instance 'IArcaneMain'.
const ApplicationInfo & m_app_info
ATTENTION: référence.
std::atomic< Int32 > m_nb_autodetect
Nombre de fois qu'on a lancé l'auto-détection pour MPI et les accélérateurs.
Real m_init_time_accelerator
Temps passé (en seconde) dans l'initialisation pour les accélérateurs.
Int32 m_autodetect_return_value
Code retour pour l'auto-détection.
Classe de gestion de l'exécution.
Definition ArcaneMain.h:80
static ApplicationBuildInfo & defaultApplicationBuildInfo()
Informations pour l'initialisation des accélerateurs.
static AcceleratorRuntimeInitialisationInfo & defaultAcceleratorRuntimeInitialisationInfo()
Informations pour l'initialisation des accélerateurs.
static std::atomic< Int32 > m_nb_arcane_init
Nombre de fois que arcaneInitialize() a été appelé
Definition ArcaneMain.h:353
static DotNetRuntimeInitialisationInfo & defaultDotNetRuntimeInitialisationInfo()
Informations pour l'initialisation du runtime '.Net'.
static void arcaneInitialize()
Initialise Arcane.
static void addApplicationBuildInfoVisitor(IApplicationBuildInfoVisitor *visitor)
Ajoute un visiteur pour remplir ApplicationBuildInfo.
const DotNetRuntimeInitialisationInfo & dotnetRuntimeInitialisationInfo() const override
Informations d'initialisation du runtime '.Net'.
static int _checkAutoDetectAccelerator(bool &has_accelerator)
Détecte et charge la gestion du runtime des accélérateurs.
static void arcaneFinalize()
Termine l'utilisation Arcane.
static int _arcaneMain(const ApplicationInfo &, IMainFactory *)
Point d'entrée de l'exécutable.
static Real initializationTimeForAccelerator()
Retourne le temps (en seconde) pour l'initialisation des runtimes accélérateurs pour ce processus.
const ApplicationInfo & applicationInfo() const override
Informations sur l'éxécutable.
ServiceFactoryInfoCollection registeredServiceFactoryInfos() override
Liste des fabriques de service enregistrées.
const AcceleratorRuntimeInitialisationInfo & acceleratorRuntimeInitialisationInfo() const override
Informations d'initialisation du runtime pour les accélérateurs.
static int callFunctorWithCatchedException(IFunctor *functor, IArcaneMain *amain, bool *clean_abort, bool is_print=true)
Appelle le fonctor functor en récupérant les éventuelles exceptions.
ModuleFactoryInfoCollection registeredModuleFactoryInfos() override
Liste des fabriques de module enregistrées.
void setErrorCode(int errcode) override
Positionne le code de retour.
static void setHasDotNETRuntime()
Indique que l'on tourne dans le runtime .NET.
IApplication * application() const override
Application.
Definition ArcaneMain.h:321
static void setHasGarbageCollector()
Indique que certains objets sont gérés par un ramasse-miette.
static std::atomic< Int32 > m_is_init_done
1 si init terminé, 0 sinon
Definition ArcaneMain.h:355
static int run()
Point d'entrée de l'exécutable dans Arcane.
static void addServiceFactoryInfo(IServiceFactoryInfo *factory)
Ajoute une fabrique de service.
void build() override
Construit les membres la classe. L'instance n'est pas utilisable tant que cette méthode n'a pas été a...
static ApplicationInfo & defaultApplicationInfo()
Infos par défaut de l'application.
static void setExecuteOverrideFunctor(ArcaneMainExecutionOverrideFunctor *functor)
static bool hasDotNetWrapper()
Indique si on exécute une assembly '.Net' depuis un main en C++.
const ApplicationBuildInfo & applicationBuildInfo() const override
Informations pour construire l'instance IApplication.
int execute() override
Lance l'exécution. Cette méthode ne retourne que lorsqu'on quitte le programme.
void doAbort() override
Effectue un abort.
static void setDefaultMainFactory(IMainFactory *mf)
Positionne la fabrique par défaut.
void initialize() override
Initialise l'instance. L'instance n'est pas utilisable tant que cette méthode n'a pas été appelée.
bool parseArgs(StringList args) override
Analyse les arguments.
static void addModuleFactoryInfo(IModuleFactoryInfo *factory)
Ajoute une fabrique de module.
Exception lorsqu'une erreur arithmétique survient.
void clear()
Supprime tous les éléments de la collection.
Definition Collection.h:68
Integer count() const
Nombre d'éléments de la collection.
Definition Collection.h:70
Arguments de la ligne de commande.
Informations pour l'initialisation du runtime '.Net'.
static FlexLMMng * instance()
Accès au singleton.
Interface de l'application.
virtual String applicationName() const =0
Nom de l'application.
Interface de la classe de gestion du code.
Definition IArcaneMain.h:54
virtual IApplication * application() const =0
Application.
virtual void finalize()=0
Effectue les dernières opérations avant destruction de l'instance.
virtual void initialize()=0
Initialise l'instance. L'instance n'est pas utilisable tant que cette méthode n'a pas été appelée.
virtual int execute()=0
Lance l'exécution. Cette méthode ne retourne que lorsqu'on quitte le programme.
static IArcaneMain * arcaneMain()
virtual void setErrorCode(int errcode)=0
Positionne le code de retour.
static void setArcaneMain(IArcaneMain *arcane_main)
virtual void doAbort()=0
Effectue un abort.
virtual bool parseArgs(StringList args)=0
Analyse les arguments.
virtual int errorCode() const =0
Code d'erreur de l'exécution.
virtual void build()=0
Construit les membres la classe. L'instance n'est pas utilisable tant que cette méthode n'a pas été a...
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
virtual void initialize()=0
Initialise l'instance. L'instance n'est pas utilisable tant que cette méthode n'a pas été appelée.
Interface d'un fonctor pour exécuter du code directement après la création d'un sous-domaine sans pas...
Interface d'une chargeur dynamique de bibliothèque.
virtual IDynamicLibrary * open(const String &directory, const String &name)=0
Charge une bibliothèque dynamique.
Interface d'une bibliothèque dynamique.
Manufacture des classes d'Arcane.
virtual IApplication * createApplication(IArcaneMain *)=0
Crée une instance d'un superviseur.
virtual IServiceLoader * createServiceLoader()=0
Crée une instance du chargeur de services.
virtual IArcaneMain * createArcaneMain(const ApplicationInfo &app_info)=0
Crée une instance de IArcaneMain.
Informations sur la fabrique d'un module.
Classe abstraite du superviseur de parallélisme.
Informations sur la fabrique d'un service.
Interface des informations d'un service ou d'un module.
virtual String localName() const =0
Partie locale du nom du service.
Sorties des informations internes de Arcane.
static void _buildSharedNull()
static void _destroySharedNull()
static void _destroySingleton()
Détruit le singleton.
static ItemTypeMng * _singleton()
Instance singleton du type.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Manufacture des classes d'Arcane.
Definition MainFactory.h:53
Exception lorsqu'une erreur fatale 'parallèle' est générée.
Exception lorsqu'un signal survient.
Classe de base d'une exception.
Exception lorsqu'une erreur fatale est survenue.
virtual void executeFunctor()=0
Exécute la méthode associé
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
virtual TraceMessage error()=0
Flot pour un message d'erreur.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
Definition MathUtils.h:392
Integer toInteger(Real r)
Converti un Int64 en un Integer.
String getLoadedSharedLibraryFullPath(const String &dll_name)
Retourne le chemin complet d'une bibliothèque dynamique chargée.
IDynamicLibraryLoader * getDynamicLibraryLoader()
Service utilisé pour charger dynamiquement des bibliothèques.
void platformInitialize()
Initialisations spécifiques à une platforme.
void platformTerminate()
Routines de fin de programme spécifiques à une platforme.
void setHasDotNETRuntime(bool v)
Positionne si le code s'exécute avec le runtime .NET.
IDynamicLibraryLoader * setDynamicLibraryLoader(IDynamicLibraryLoader *idll)
Positionne le service utilisé pour charger dynamiquement des bibliothèques.
bool hasDotNETRuntime()
Vrai si le code s'exécute avec le runtime .NET.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Collection< String > StringCollection
Collection de chaînes de caractères.
Definition UtilsTypes.h:664
void arcaneSignalHandler(int val)
Fonction appelee lorsque le programme est interrompu par le signal 'val'.
List< IService * > ServiceList
Tableau de services.
Int32 Integer
Type représentant un entier.