Arcane  v4.1.4.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-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ArcaneMain.cc (C) 2000-2026 */
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/List.h"
18#include "arcane/utils/Iterator.h"
19#include "arcane/utils/ScopedPtr.h"
20#include "arcane/utils/PlatformUtils.h"
21#include "arcane/utils/FatalErrorException.h"
22#include "arcane/utils/ParallelFatalErrorException.h"
23#include "arcane/utils/OStringStream.h"
24#include "arcane/utils/ApplicationInfo.h"
25#include "arcane/utils/ValueConvert.h"
26#include "arcane/utils/ITraceMng.h"
27#include "arcane/utils/SignalException.h"
28#include "arcane/utils/TimeoutException.h"
29#include "arcane/utils/ArithmeticException.h"
30#include "arcane/utils/StringBuilder.h"
31#include "arccore/base/internal/IDynamicLibraryLoader.h"
32#include "arcane/utils/CheckedConvert.h"
33#include "arcane/utils/CommandLineArguments.h"
34#include "arcane/utils/TestLogger.h"
36
37#include "arccore/base/internal/ConvertInternal.h"
39#include "arccore/common/internal/MemoryUtilsInternal.h"
40#include "arccore/common/accelerator/internal/RuntimeLoader.h"
41
42#include "arcane/core/IMainFactory.h"
43#include "arcane/core/IApplication.h"
44#include "arcane/core/IServiceLoader.h"
45#include "arcane/core/IParallelMng.h"
46#include "arcane/core/IParallelSuperMng.h"
47#include "arcane/core/ISession.h"
48#include "arcane/core/VariableRef.h"
49#include "arcane/core/ItemTypeMng.h"
50#include "arcane/core/ServiceUtils.h"
51#include "arcane/core/CaseOptions.h"
52#include "arcane/core/ItemGroupImpl.h"
53#include "arcane/core/DotNetRuntimeInitialisationInfo.h"
54#include "arcane/core/AcceleratorRuntimeInitialisationInfo.h"
55#include "arcane/core/ApplicationBuildInfo.h"
56
57#include "arcane/core/IServiceFactory.h"
58#include "arcane/core/IModuleFactory.h"
59
60#include "arcane/impl/MainFactory.h"
61#include "arcane/impl/InternalInfosDumper.h"
62#include "arcane/impl/internal/ArcaneMainExecInfo.h"
63#include "arcane/impl/internal/ThreadBindingMng.h"
64
65#include "arccore/common/accelerator/internal/RegisterRuntimeInfo.h"
66
67#include "arcane_internal_config.h"
68
69#include <signal.h>
70#include <exception>
71#ifndef ARCANE_OS_WIN32
72#include <unistd.h>
73#include <sys/stat.h>
74#include <fcntl.h>
75#endif
76
77#include <set>
78#include <map>
79#include <chrono>
80
81#ifdef ARCANE_FLEXLM
82#include "arcane/impl/FlexLMTools.h"
83#endif
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87namespace Arcane
88{
90{
91 public:
92
93 List<IServiceFactoryInfo*> m_service_factory_infos;
94 List<IModuleFactoryInfo*> m_module_factory_infos;
95 List<IApplicationBuildInfoVisitor*> m_application_build_info_visitors;
96 ApplicationBuildInfo m_app_build_info;
97 DotNetRuntimeInitialisationInfo m_dotnet_init_info;
98 AcceleratorRuntimeInitialisationInfo m_accelerator_init_info;
99 bool m_has_dotnet_wrapper = false;
100 String m_dotnet_assembly;
101 String m_arcane_lib_path;
102 IDirectSubDomainExecuteFunctor* m_direct_exec_functor = nullptr;
104 std::atomic<Int32> m_nb_autodetect = 0;
109};
110} // namespace Arcane
111
112namespace
113{
114Arcane::ArcaneMainStaticInfo* global_static_info = nullptr;
115Arcane::ArcaneMainStaticInfo* _staticInfo()
116{
117 // TODO: voir s'il faut protéger en multi-threading.
118 if (!global_static_info)
119 global_static_info = new Arcane::ArcaneMainStaticInfo();
120 return global_static_info;
121}
122void _deleteStaticInfo()
123{
124 delete global_static_info;
125 global_static_info = nullptr;
126}
127} // namespace
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
132extern "C" void arcaneEndProgram()
133{
134 // Juste la pour faire un point d'entrée à third.
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140extern "C" {
141typedef void (*fSignalFunc)(int);
142void arcaneSignalHandler(int);
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148namespace Arcane
149{
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154extern "C++" ARCANE_UTILS_EXPORT void
155arcaneRedirectSignals(fSignalFunc sig_func);
156
157extern "C++" ARCANE_UTILS_EXPORT void
158arcaneCallDefaultSignal(int val);
159
160extern "C++" ARCANE_UTILS_EXPORT void
161initializeStringConverter();
162
163extern "C++" ARCANE_IMPL_EXPORT IArcaneMain*
164createArcaneMainBatch(const ApplicationInfo& exe_info, IMainFactory*);
165
166extern "C++" ARCANE_IMPL_EXPORT ICodeService*
167createArcaneCodeService(IApplication* app);
168
169extern "C++" ARCCORE_COMMON_EXPORT void
170arccorePrintSpecificMemoryStats();
171
172std::atomic<Int32> ArcaneMain::m_nb_arcane_init(0);
173std::atomic<Int32> ArcaneMain::m_is_init_done(0);
174bool ArcaneMain::m_has_garbage_collector = false;
175bool ArcaneMain::m_is_master_io = true;
176bool ArcaneMain::m_is_use_test_logger = false;
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
182: public MainFactory
183{
184 public:
185
187 {
188 return createArcaneMainBatch(app_info, this);
189 }
190};
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
196{
197 public:
198
199 explicit Impl(const ApplicationInfo& infos)
200 : m_app_info(infos)
201 , m_application_build_info(ArcaneMain::defaultApplicationBuildInfo())
204 {}
205 Impl(const ApplicationInfo& infos, const ApplicationBuildInfo& build_infos,
206 const DotNetRuntimeInitialisationInfo& dotnet_info,
207 const AcceleratorRuntimeInitialisationInfo& accelerator_info)
208 : m_app_info(infos)
209 , m_application_build_info(build_infos)
210 , m_dotnet_info(dotnet_info)
211 , m_accelerator_info(accelerator_info)
212 {}
213
214 public:
215
216 ApplicationInfo m_app_info;
217 ApplicationBuildInfo m_application_build_info;
219 AcceleratorRuntimeInitialisationInfo m_accelerator_info;
220 ThreadBindingMng m_thread_binding_mng;
221};
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229void ArcaneMain::
230redirectSignals()
231{
232 bool redirect_signals = true;
233 String rv = platform::getEnvironmentVariable("ARCANE_REDIRECT_SIGNALS");
234 (void)builtInGetValue(redirect_signals, rv);
235 if (redirect_signals) {
236 arcaneRedirectSignals(arcaneSignalHandler);
237 }
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243void ArcaneMain::
244setUseTestLogger(bool v)
245{
246 m_is_use_test_logger = v;
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
254{
255 m_default_main_factory = mf;
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261class ArcaneMainExecFunctor
262: public IFunctor
263{
264 public:
265
266 ArcaneMainExecFunctor(const ApplicationInfo& app_info, IArcaneMain* exec_main)
267 : m_app_info(app_info)
268 , m_exec_main(exec_main)
269 {
270 }
271
272 public:
273
274 void executeFunctor() override
275 {
276 StringList args;
277 m_app_info.args(args);
278 if (!m_exec_main->parseArgs(args))
279 m_exec_main->execute();
280 }
281
282 private:
283
284 const ApplicationInfo& m_app_info;
285 IArcaneMain* m_exec_main;
286};
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
297{
298 public:
299
300 Int32 check()
301 {
302 auto* x = _staticInfo();
303 if (x->m_nb_autodetect > 0)
304 return x->m_autodetect_return_value;
305
306 ArcaneMain::_setArcaneLibraryPath();
307
308 std::chrono::high_resolution_clock clock;
309
310 // TODO: rendre thread-safe
311 {
312 ArcaneMain::_checkAutoDetectMPI();
313
314 bool has_accelerator = false;
315 // Mesure le temps de l'initialisation.
316 // Comme ici on n'a pas encore initialié Arcane il ne faut
317 // pas utiliser de méthode du namespace 'platform'.
318 auto start_time = clock.now();
319 x->m_autodetect_return_value = ArcaneMain::_checkAutoDetectAccelerator(has_accelerator);
320 auto end_time = clock.now();
321 // Ne récupère le temps que si on a utilise un accélérateur
322 if (has_accelerator)
323 x->m_init_time_accelerator = _getTime(end_time,start_time);
324 ++x->m_nb_autodetect;
325 }
326 return x->m_autodetect_return_value;
327 }
328
329 template<typename TimeType>
330 Real _getTime(TimeType end_time,TimeType start_time)
331 {
332 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
333 Real x = static_cast<Real>(duration.count());
334 return x / 1.0e9;
335 }
336};
337
338/*---------------------------------------------------------------------------*/
339/*---------------------------------------------------------------------------*/
351{
352 if (m_exec_main)
353 return 0;
354
355 m_ret_val = 0;
356 m_clean_abort = false;
357
358 ArcaneMain::redirectSignals();
359
360 // Création de la classe d'exécution
361 try {
362 if (m_has_build_info) {
363 ArcaneMain* x = new ArcaneMain(m_app_info, m_main_factory,
364 m_application_build_info,
367 m_exec_main = x;
368 }
369 else {
370 m_exec_main = m_main_factory->createArcaneMain(m_app_info);
371 }
372 m_exec_main->build();
373 ArcaneMain::m_is_master_io = m_exec_main->application()->parallelSuperMng()->isMasterIO();
374 m_exec_main->initialize();
375 IArcaneMain::setArcaneMain(m_exec_main);
376 }
377 catch (const ArithmeticException& ex) {
378 cerr << "** CATCH ARITHMETIC_EXCEPTION\n";
379 return ExceptionUtils::print(ex, nullptr);
380 }
381 catch (const Exception& ex) {
382 return ExceptionUtils::print(ex, nullptr);
383 }
384 catch (const std::exception& ex) {
385 return ExceptionUtils::print(ex, nullptr);
386 }
387 catch (...) {
388 return ExceptionUtils::print(nullptr);
389 }
390
391 // Redirige a nouveau les signaux car certaines
392 // routines d'initialisation (par exemple MPI) peuvent
393 // les detourner.
394 ArcaneMain::redirectSignals();
395
396 m_ret_val = 0;
397 m_clean_abort = false;
398
399#ifdef ARCANE_FLEXLM
400 try {
401 IApplication* app = m_exec_main->application();
402 ITraceMng* trace = app->traceMng();
403 IParallelSuperMng* parallel_super_mng = app->parallelSuperMng();
404 trace->info() << "Initializing license manager";
405 FlexLMMng::instance()->init(parallel_super_mng);
406
407 // La politique de licence parallèle est sous-traitée aux applications
408 // bool is_parallel = parallel_super_mng->isParallel();
409 // FlexLMTools<ArcaneFeatureModel> license_tool;
410 // Integer commSize = parallel_super_mng->commSize();
411 // if (is_parallel && commSize > 1)
412 // { // La fonctionnalité paralléle n'est activé que si nécessaire
413 // license_tool.getLicense(ArcaneFeatureModel::ArcaneParallel,commSize);
414 // }
415 }
416 catch (const Exception& ex) {
417 IApplication* app = m_exec_main->application();
418 ITraceMng* trace = app->traceMng();
419 m_ret_val = arcanePrintArcaneException(ex, trace);
420 if (ex.isCollective()) {
421 m_clean_abort = true;
422 }
423 }
424#endif
425 return 0;
426}
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430// NOTE: Cette méthode ne doit pas lancer d'exceptions
431void ArcaneMainExecInfo::
432execute()
433{
434 if (m_ret_val != 0)
435 return;
436
437 if (m_direct_exec_functor)
438 m_exec_main->setDirectExecuteFunctor(m_direct_exec_functor);
439
440 ArcaneMainExecFunctor exec_functor(m_app_info, m_exec_main);
441 if (ArcaneMain::m_exec_override_functor) {
442 // Obsolète. Ne plus utiliser.
443 IApplication* app = m_exec_main->application();
444 ArcaneMain::m_exec_override_functor->m_application = app;
445 ITraceMng* trace = app->traceMng();
446 trace->info() << "Calling overriding functor";
447 m_ret_val = ArcaneMain::callFunctorWithCatchedException(ArcaneMain::m_exec_override_functor->functor(),
448 m_exec_main, &m_clean_abort, true);
449 }
450 else
451 m_ret_val = ArcaneMain::callFunctorWithCatchedException(&exec_functor, m_exec_main, &m_clean_abort, true);
452}
453
454/*---------------------------------------------------------------------------*/
455/*---------------------------------------------------------------------------*/
456
457void ArcaneMainExecInfo::
458finalize()
459{
460 // Désactive les exceptions flottantes
462
463 // Si l'exécution s'est bien déroulée mais que l'utilisateur a spécifié un
464 // code d'erreur, on le récupère.
465 int exe_error_code = m_exec_main->errorCode();
466 if (m_ret_val == 0 && exe_error_code != 0) {
467 m_ret_val = exe_error_code;
468 }
469 else if (m_ret_val != 0)
470 m_exec_main->setErrorCode(m_ret_val);
471
472 m_exec_main->finalize();
473
474 if (m_ret_val != 0 && !m_clean_abort)
475 m_exec_main->doAbort();
476
477 // Destruction du code.
478 // Attention à ne pas détruire le gestionnaire avant car lorsqu'une exception
479 // de l'architecture est générée, elle utilise un ITraceMng pour afficher
480 // le message
481 delete m_exec_main;
482 m_exec_main = nullptr;
483#ifndef ARCANE_USE_MPC
484 IArcaneMain::setArcaneMain(m_exec_main);
485#endif
486}
487
488/*---------------------------------------------------------------------------*/
489/*---------------------------------------------------------------------------*/
495_arcaneMain(const ApplicationInfo& app_info, IMainFactory* factory)
496{
497 if (!factory)
498 return 5;
499
500 ArcaneMainExecInfo exec_info(app_info, factory);
501 int r = exec_info.initialize();
502 if (r != 0)
503 return r;
504
505 IDirectSubDomainExecuteFunctor* func = _staticInfo()->m_direct_exec_functor;
506 if (func)
507 exec_info.setDirectExecFunctor(func);
508 exec_info.execute();
509 exec_info.finalize();
510
511 return exec_info.returnValue();
512}
513
514/*---------------------------------------------------------------------------*/
515/*---------------------------------------------------------------------------*/
516
519 bool* clean_abort, bool is_print)
520{
521 int ret_val = 0;
522 *clean_abort = false;
523 IApplication* app = exec_main->application();
524 ITraceMng* trace = app->traceMng();
525 bool is_parallel = app->parallelSuperMng()->isParallel();
526 bool is_master = app->parallelSuperMng()->isMasterIO();
527 try {
528 functor->executeFunctor();
529 }
530 catch (const FatalErrorException& ex) {
531 if (ex.isCollective()) {
532 if (is_parallel) {
533 *clean_abort = true;
534 ret_val = 5;
535 if (is_master && is_print) {
536 std::ofstream ofile("fatal");
537 ofile << ret_val << '\n';
538 ofile.flush();
539 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
540 }
541 }
542 else {
543 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
544 ret_val = 4;
545 }
546 }
547 else {
548 trace->error() << Trace::Color::red() << "FatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
549 ret_val = 4;
550 }
551 }
552 catch (const SignalException& ex) {
553 trace->error() << "SignalException caught in ArcaneMain::callFunctor: " << ex << '\n';
554 ret_val = 6;
555 }
556 catch (const TimeoutException& ex) {
557 trace->error() << "TimeoutException caught in ArcaneMain::callFunctor: " << ex << '\n';
558 ret_val = 7;
559 }
560 catch (const ParallelFatalErrorException& ex) {
561 // TODO: utiliser le code de FatalErrorException en mode collectif.n
562 if (is_parallel) {
563 *clean_abort = true;
564 ret_val = 5;
565 if (is_master && is_print) {
566 std::ofstream ofile("fatal");
567 ofile << ret_val << '\n';
568 ofile.flush();
569 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
570 }
571 }
572 else {
573 trace->error() << "ParallelFatalErrorException caught in ArcaneMain::callFunctor: " << ex << '\n';
574 ret_val = 4;
575 }
576 }
577 catch (const ArithmeticException& ex) {
578 cerr << "** ARITHMETIC EXCEPTION!\n";
579 ret_val = ExceptionUtils::print(ex, trace);
580 if (ex.isCollective()) {
581 *clean_abort = true;
582 }
583 }
584 catch (const Exception& ex) {
585 ret_val = ExceptionUtils::print(ex, trace);
586 if (ex.isCollective()) {
587 *clean_abort = true;
588 }
589 }
590 catch (const std::exception& ex) {
591 ret_val = ExceptionUtils::print(ex, trace);
592 }
593 catch (...) {
594 ret_val = ExceptionUtils::print(trace);
595 }
596 return ret_val;
597}
598
599/*---------------------------------------------------------------------------*/
600/*---------------------------------------------------------------------------*/
601
602void ArcaneMain::
603_launchMissingInitException()
604{
605 std::cerr << "ERROR: ArcaneMain: missing call to ArcaneMain::arcaneInitialize().\n";
606 throw std::runtime_error("Missing call to ArcaneMain::arcaneInitialize()");
607}
608
609/*---------------------------------------------------------------------------*/
610/*---------------------------------------------------------------------------*/
611
612void ArcaneMain::
613_checkHasInit()
614{
615 if (m_nb_arcane_init <= 0)
616 _launchMissingInitException();
617}
618
619/*---------------------------------------------------------------------------*/
620/*---------------------------------------------------------------------------*/
621
622extern "C++" void arcaneInitCheckMemory();
623extern "C++" void arcaneExitCheckMemory();
624
625/*---------------------------------------------------------------------------*/
626/*---------------------------------------------------------------------------*/
627
630{
631 if (m_nb_arcane_init != 0) {
632 cerr << "WARNING: ArcaneMain::setHasGarbageCollector has to be called before arcaneInitialize\n";
633 return;
634 }
635 m_has_garbage_collector = true;
636}
637
638/*---------------------------------------------------------------------------*/
639/*---------------------------------------------------------------------------*/
640
643{
644 if (m_nb_arcane_init != 0) {
645 cerr << "WARNING: ArcaneMain::setHasDotNETRuntime has to be called before arcaneInitialize\n";
646 return;
647 }
649}
650
651/*---------------------------------------------------------------------------*/
652/*---------------------------------------------------------------------------*/
653
656{
657 m_exec_override_functor = functor;
658}
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
662
665{
666 return _staticInfo()->m_has_dotnet_wrapper;
667}
668
669/*---------------------------------------------------------------------------*/
670/*---------------------------------------------------------------------------*/
671/*
672 * \brief Positionne le chemin contenant les bibliothèques dynamiques de Arcane.
673 *
674 * Il ne faut appeler qu'une seule fois cette méthode.
675 */
676void ArcaneMain::
677_setArcaneLibraryPath()
678{
679 String dir_name;
680 String dll_full_path = platform::getLoadedSharedLibraryFullPath("arcane_impl");
681 if (!dll_full_path.null())
682 dir_name = platform::getFileDirName(dll_full_path);
683 if (dir_name.null())
685 _staticInfo()->m_arcane_lib_path = dir_name;
686}
687
688/*---------------------------------------------------------------------------*/
689/*---------------------------------------------------------------------------*/
690
693{
694 // Le premier thread qui arrive ici fait l'init.
695 // Les autres doivent attendre que l'init soit terminée.
696 if (m_nb_arcane_init.fetch_add(1) == 0) {
697 (void)_staticInfo();
699 dom::DOMImplementation::initialize();
701
702 // Regarde si on souhaite utiliser l'ancien mécanisme (avant la 3.15)
703 // pour convertir les chaînes de caractères en types numériques
704 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_USE_LEGACY_BUILTINVALUECONVERT", true))
706
707 // Crée le singleton gestionnaire des types
709 initializeStringConverter();
710 arcaneInitCheckMemory();
711 // Initialise le singleton du groupe vide et garde une référence dessus.
713 m_is_init_done = 1;
714 }
715 else
716 // Attend que le thread qui fait l'init ait terminé
717 while (m_is_init_done.load() == 0)
718 ;
719}
720
721/*---------------------------------------------------------------------------*/
722/*---------------------------------------------------------------------------*/
723
726{
727 _checkHasInit();
728
729 if (m_nb_arcane_init.fetch_sub(1) == 1) {
730 _deleteStaticInfo();
731
734
735 {
737 if (x) {
738 x->closeLibraries();
739 }
740 }
741 arccorePrintSpecificMemoryStats();
742 arcaneExitCheckMemory();
744 dom::DOMImplementation::terminate();
746 arcaneEndProgram();
747#ifdef ARCANE_FLEXLM
748 {
750 }
751#endif
752 m_is_init_done = 0;
753 }
754}
755
756/*---------------------------------------------------------------------------*/
757/*---------------------------------------------------------------------------*/
758
761{
762 _staticInfo()->m_service_factory_infos.add(sri);
763}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
770{
771 _staticInfo()->m_module_factory_infos.add(mfi);
772}
773
774/*---------------------------------------------------------------------------*/
775/*---------------------------------------------------------------------------*/
776
779{
780 _staticInfo()->m_application_build_info_visitors.add(visitor);
781}
782
783/*---------------------------------------------------------------------------*/
784/*---------------------------------------------------------------------------*/
785
788{
789 return _staticInfo()->m_app_build_info._internalApplicationInfo();
790}
791
792/*---------------------------------------------------------------------------*/
793/*---------------------------------------------------------------------------*/
794
797{
798 return _staticInfo()->m_dotnet_init_info;
799}
800
801/*---------------------------------------------------------------------------*/
802/*---------------------------------------------------------------------------*/
803
806{
807 return _staticInfo()->m_accelerator_init_info;
808}
809
810/*---------------------------------------------------------------------------*/
811/*---------------------------------------------------------------------------*/
812
815{
816 return _staticInfo()->m_app_build_info;
817}
818
819/*---------------------------------------------------------------------------*/
820/*---------------------------------------------------------------------------*/
821
824{
825 return m_p->m_application_build_info;
826}
827
828/*---------------------------------------------------------------------------*/
829/*---------------------------------------------------------------------------*/
830
831ApplicationBuildInfo& ArcaneMain::
832_applicationBuildInfo()
833{
834 return m_p->m_application_build_info;
835}
836
837/*---------------------------------------------------------------------------*/
838/*---------------------------------------------------------------------------*/
839
842{
843 return m_p->m_dotnet_info;
844}
845
846/*---------------------------------------------------------------------------*/
847/*---------------------------------------------------------------------------*/
848
851{
852 return m_p->m_accelerator_info;
853}
854
855/*---------------------------------------------------------------------------*/
856/*---------------------------------------------------------------------------*/
857
860{
861 return _staticInfo()->m_init_time_accelerator;
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
868arcaneMain(const ApplicationInfo& app_info, IMainFactory* factory)
869{
870 _checkHasInit();
871
872 ScopedPtrT<IMainFactory> default_factory;
873 if (!factory) {
874 factory = m_default_main_factory;
875 if (!factory) {
876 factory = new ArcaneBatchMainFactory();
877 default_factory = factory;
878 }
879 }
880
881 int ret = _arcaneMain(app_info, factory);
882
883 default_factory = nullptr;
884
885 // Le code d'erreur 5 représente une erreur en parallèle pour tous les
886 // processeurs.
887 if (ret != 0 && ret != 5)
888 cerr << "* Process return: " << ret << '\n';
889 if (ret == 5)
890 ret = 4;
891
892 return ret;
893}
894
895/*---------------------------------------------------------------------------*/
896/*---------------------------------------------------------------------------*/
897
898int ArcaneMain::
899_internalRun(IDirectSubDomainExecuteFunctor* func)
900{
901 _staticInfo()->m_direct_exec_functor = func;
902 return run();
903}
904
905/*---------------------------------------------------------------------------*/
906/*---------------------------------------------------------------------------*/
907
908int ArcaneMain::
909_checkTestLoggerResult()
910{
911 if (!m_is_use_test_logger)
912 return 0;
913 if (!m_is_master_io)
914 return 0;
915 return TestLogger::compare();
916}
917
918/*---------------------------------------------------------------------------*/
919/*---------------------------------------------------------------------------*/
920
921int ArcaneMain::
922_initRuntimes()
923{
924 ArcaneMainAutoDetectRuntimeHelper auto_detect_helper;
925 return auto_detect_helper.check();
926}
927
928/*---------------------------------------------------------------------------*/
929/*---------------------------------------------------------------------------*/
930
932run()
933{
934 int r = _initRuntimes();
935 if (r != 0)
936 return r;
937
939
940 // Si on arrive ici et que le runtime C# est déjà chargé
941 // (parce que le Main est en C# par exemple), on ne lance pas le wrapper
942 bool is_in_dotnet = platform::hasDotNETRuntime();
943 if (!is_in_dotnet && dotnet_info.isUsingDotNetRuntime()) {
944 r = _runDotNet();
945 // Avant la version 3.7.8 on n'appelait par arcaneFinalize() car cela pouvait
946 // poser des problèmes avec le Garbage Collector de '.Net'. Normalement ces
947 // problèmes sont corrigés mais on autorise le comportement d'avant au cas où.
948 bool do_finalize = false;
949 String x = platform::getEnvironmentVariable("ARCANE_DOTNET_USE_LEGACY_DESTROY");
950 if (x == "1")
951 do_finalize = false;
952 if (x == "0")
953 do_finalize = true;
954 if (do_finalize)
956 }
957 else {
959 r = arcaneMain(defaultApplicationInfo(), nullptr);
961 }
962 if (r != 0)
963 return r;
964 return _checkTestLoggerResult();
965}
966
967/*---------------------------------------------------------------------------*/
968/*---------------------------------------------------------------------------*/
969
970int ArcaneMain::
971_runDotNet()
972{
973 auto si = _staticInfo();
974 si->m_has_dotnet_wrapper = true;
975
976 // TODO: vérifier que l'init n'a pas été faite.
977
978 // Pour pouvoir exécuter le code .Net, il faut
979 // appeler la méthode 'arcane_mono_main' qui se trouve
980 // dans la bibliothèque dynamique 'arcane_mono'.
981
982 typedef int (*DotNetMainFunctor)(const CommandLineArguments& cmd_args, const String& assembly_name);
983
984 const ApplicationInfo& app_info = defaultApplicationInfo();
986
987 DotNetMainFunctor my_functor = nullptr;
988 String os_dir(si->m_arcane_lib_path);
989
990 try {
992
993 String dll_name = "arcane_mono";
994 String symbol_name = "arcane_mono_main2";
995
996 String runtime_name = dotnet_info.embeddedRuntime();
997
998 if (runtime_name.null() || runtime_name == "mono")
999 // Mono est le défaut si rien n'est spécifié.
1000 ;
1001 else if (runtime_name == "coreclr") {
1002 dll_name = "arcane_dotnet_coreclr";
1003 symbol_name = "arcane_dotnet_coreclr_main";
1004 }
1005 else
1006 ARCANE_FATAL("Unknown '.Net' runtime '{0}'. Valid values are 'mono' or 'coreclr'", runtime_name);
1007
1008 IDynamicLibrary* dl = dll_loader->open(os_dir, dll_name);
1009 if (!dl)
1010 ARCANE_FATAL("Can not found dynamic library '{0}' for using .Net", dll_name);
1011
1012 bool is_found = false;
1013 void* functor_addr = dl->getSymbolAddress(symbol_name, &is_found);
1014 if (!is_found)
1015 ARCANE_FATAL("Can not find symbol '{0}' in library '{1}'", symbol_name, dll_name);
1016
1017 my_functor = reinterpret_cast<DotNetMainFunctor>(functor_addr);
1018 }
1019 catch (const Exception& ex) {
1020 return ExceptionUtils::print(ex, nullptr);
1021 }
1022 catch (const std::exception& ex) {
1023 return ExceptionUtils::print(ex, nullptr);
1024 }
1025 catch (...) {
1026 return ExceptionUtils::print(nullptr);
1027 }
1028
1029 if (my_functor) {
1030 const CommandLineArguments& cmd_args = app_info.commandLineArguments();
1031 // TODO: vérifier que l'assembly 'Arcane.Main.dll' existe bien.
1032 String new_name = os_dir + "/Arcane.Main.dll";
1033 return (*my_functor)(cmd_args, new_name);
1034 }
1035 return (-1);
1036}
1037
1038/*---------------------------------------------------------------------------*/
1039/*---------------------------------------------------------------------------*/
1040// Ne pas appeler directement mais passer par ArcaneMainAutoDetectHelper.
1041void ArcaneMain::
1042_checkAutoDetectMPI()
1043{
1044 auto si = _staticInfo();
1045 // Pour pouvoir automatiquement enregisrer MPI, il faut
1046 // appeler la méthode 'arcaneAutoDetectMessagePassingServiceMPI' qui se trouve
1047 // dans la bibliothèque dynamique 'arcane_mpi'.
1048
1049 typedef void (*ArcaneAutoDetectMPIFunctor)();
1050
1051 IDynamicLibraryLoader* dll_loader = IDynamicLibraryLoader::getDefault();
1052
1053 String os_dir(si->m_arcane_lib_path);
1054 String dll_name = "arcane_mpi";
1055 String symbol_name = "arcaneAutoDetectMessagePassingServiceMPI";
1056 IDynamicLibrary* dl = dll_loader->open(os_dir, dll_name);
1057 if (!dl)
1058 return;
1059
1060 bool is_found = false;
1061 void* functor_addr = dl->getSymbolAddress(symbol_name, &is_found);
1062 if (!is_found)
1063 return;
1064
1065 auto my_functor = reinterpret_cast<ArcaneAutoDetectMPIFunctor>(functor_addr);
1066 if (my_functor)
1067 (*my_functor)();
1068}
1069
1070/*---------------------------------------------------------------------------*/
1071/*---------------------------------------------------------------------------*/
1083_checkAutoDetectAccelerator(bool& has_accelerator)
1084{
1085 has_accelerator = false;
1086 String default_runtime_name;
1087#if defined(ARCANE_ACCELERATOR_RUNTIME)
1088 default_runtime_name = ARCANE_ACCELERATOR_RUNTIME;
1089#endif
1090 auto si = _staticInfo();
1091 AcceleratorRuntimeInitialisationInfo& init_info = si->m_accelerator_init_info;
1092 if (!init_info.isUsingAcceleratorRuntime())
1093 return 0;
1094 return Accelerator::Impl::RuntimeLoader::loadRuntime(init_info, default_runtime_name, si->m_arcane_lib_path, has_accelerator);
1095}
1096
1097/*---------------------------------------------------------------------------*/
1098/*---------------------------------------------------------------------------*/
1099
1100/*---------------------------------------------------------------------------*/
1101/*---------------------------------------------------------------------------*/
1102
1103IMainFactory* ArcaneMain::m_default_main_factory = nullptr;
1104ArcaneMainExecutionOverrideFunctor* ArcaneMain::m_exec_override_functor = nullptr;
1105
1106/*---------------------------------------------------------------------------*/
1107/*---------------------------------------------------------------------------*/
1108
1109ArcaneMain::
1110ArcaneMain(const ApplicationInfo& app_info, IMainFactory* factory)
1111: m_p(new Impl(app_info))
1112, m_main_factory(factory)
1113{
1114}
1115
1116/*---------------------------------------------------------------------------*/
1117/*---------------------------------------------------------------------------*/
1118
1119ArcaneMain::
1120ArcaneMain(const ApplicationInfo& app_info, IMainFactory* factory,
1121 const ApplicationBuildInfo& app_build_info,
1122 const DotNetRuntimeInitialisationInfo& dotnet_info,
1123 const AcceleratorRuntimeInitialisationInfo& accelerator_info)
1124: m_p(new Impl(app_info, app_build_info, dotnet_info, accelerator_info))
1125, m_main_factory(factory)
1126{
1127}
1128
1129/*---------------------------------------------------------------------------*/
1130/*---------------------------------------------------------------------------*/
1131
1132ArcaneMain::
1133~ArcaneMain()
1134{
1135 // S'assure qu'on retire les observateurs associés au TheadBindingMng
1136 // avant la finalisation pour éviter de punaiser les threads alors que
1137 // cela ne sert plus à rien.
1138 m_p->m_thread_binding_mng.finalize();
1139 delete m_application;
1140 delete m_p;
1141}
1142
1143/*---------------------------------------------------------------------------*/
1144/*---------------------------------------------------------------------------*/
1145
1146/*---------------------------------------------------------------------------*/
1147/*---------------------------------------------------------------------------*/
1148
1150build()
1151{
1152 _parseApplicationBuildInfoArgs();
1153 m_application = m_main_factory->createApplication(this);
1154 m_p->m_thread_binding_mng.initialize(m_application->traceMng(),
1155 m_p->m_application_build_info.threadBindingStrategy());
1156}
1157
1158/*---------------------------------------------------------------------------*/
1159/*---------------------------------------------------------------------------*/
1160
1162applicationInfo() const
1163{
1164 return m_p->m_app_info;
1165}
1166
1167/*---------------------------------------------------------------------------*/
1168/*---------------------------------------------------------------------------*/
1169
1170void ArcaneMain::
1171_parseApplicationBuildInfoArgs()
1172{
1173 ApplicationBuildInfo& abi = _applicationBuildInfo();
1174 abi.parseArguments(m_p->m_app_info.commandLineArguments());
1175 // Appelle les visiteurs enregistrés.
1176 {
1177 auto& x = _staticInfo()->m_application_build_info_visitors;
1178 for (IApplicationBuildInfoVisitor* v : x) {
1179 if (v)
1180 v->visit(abi);
1181 }
1182 }
1183 abi.setDefaultServices();
1184}
1185
1186/*---------------------------------------------------------------------------*/
1187/*---------------------------------------------------------------------------*/
1188
1190initialize()
1191{
1192 m_application->initialize();
1193
1194 ScopedPtrT<IServiceLoader> service_loader(m_main_factory->createServiceLoader());
1195 service_loader->loadApplicationServices(m_application);
1196}
1197
1198/*---------------------------------------------------------------------------*/
1199/*---------------------------------------------------------------------------*/
1200
1203{
1204 return _staticInfo()->m_service_factory_infos;
1205}
1206
1207/*---------------------------------------------------------------------------*/
1208/*---------------------------------------------------------------------------*/
1209
1212{
1213 return _staticInfo()->m_module_factory_infos;
1214}
1215
1216/*---------------------------------------------------------------------------*/
1217/*---------------------------------------------------------------------------*/
1218
1220execute()
1221{
1222 return 0;
1223}
1224
1225/*---------------------------------------------------------------------------*/
1226/*---------------------------------------------------------------------------*/
1227
1229doAbort()
1230{
1231 ::abort();
1232}
1233
1234/*---------------------------------------------------------------------------*/
1235/*---------------------------------------------------------------------------*/
1236
1238setErrorCode(int errcode)
1239{
1240 m_error_code = errcode;
1241 if (errcode != 0) {
1242 // Seul le proc maitre écrit le fichier sauf s'il s'agit d'un fatal car
1243 // dans ce cas n'importe quel PE peut le faire.
1244 if (ArcaneMain::m_is_master_io || errcode == 4) {
1245 String errname = "fatal_" + String::fromNumber(errcode);
1246 std::ofstream ofile(errname.localstr());
1247 ofile.close();
1248 }
1249 }
1250}
1251
1252/*---------------------------------------------------------------------------*/
1253/*---------------------------------------------------------------------------*/
1254
1257{
1258 // Si vrai, affichage des informations internes
1259 bool arcane_internal = false;
1260 // Si vrai, affichage des informations internes pour chaque boucle en temps
1261 bool arcane_all_internal = false;
1262 // Si vrai, génère un fichier contenant les infos internes du code.
1263 bool arcane_database = false;
1264 // Si vrai, affichage des informations sur les modules et services présents et une aide sommaire
1265 bool arcane_help = false;
1266
1267 String us_arcane_opt("-arcane_opt");
1268 String us_help("help");
1269 String us_arcane_internal("arcane_internal");
1270 String us_arcane_all_internal("arcane_all_internal");
1271 String us_arcane_database("arcane_database");
1272
1273 StringList unknown_args;
1274 for (Integer i = 0, s = args.count(); i < s; ++i) {
1275 if (args[i].startsWith("-A")) {
1276 continue;
1277 }
1278 if (args[i] != us_arcane_opt) {
1279 unknown_args.add(args[i]);
1280 continue;
1281 }
1282 bool is_valid_opt = false;
1283 ++i;
1284 String str;
1285 if (i < s)
1286 str = args[i];
1287 if (str == us_arcane_internal) {
1288 arcane_internal = true;
1289 is_valid_opt = true;
1290 }
1291 if (str == us_arcane_all_internal) {
1292 arcane_all_internal = true;
1293 is_valid_opt = true;
1294 }
1295 if (str == us_arcane_database) {
1296 arcane_database = true;
1297 is_valid_opt = true;
1298 }
1299 if (str == us_help) {
1300 arcane_help = true;
1301 is_valid_opt = true;
1302 }
1303 if (!is_valid_opt) {
1304 // Si l'option n'est pas valide, la rajoute à la liste des options
1305 // non traitées
1306 unknown_args.add(us_arcane_opt);
1307 if (!str.null())
1308 unknown_args.add(str);
1309 //trace->fatal() << "Unknown arcane option <" << str << ">\n";
1310 }
1311 }
1312
1313 bool do_stop = false;
1314 if (arcane_database) {
1316 dumper.dumpArcaneDatabase();
1317 do_stop = true;
1318 }
1319 if (arcane_internal) {
1321 dumper.dumpInternalInfos();
1322 do_stop = true;
1323 }
1324 if (arcane_all_internal) {
1326 dumper.dumpInternalAllInfos();
1327 do_stop = true;
1328 }
1329 if (arcane_help) {
1330 _dumpHelp();
1331 do_stop = true;
1332 }
1333
1334 args.clear();
1335 for (StringList::Enumerator i(unknown_args); ++i;)
1336 args.add(*i);
1337
1338 return do_stop;
1339}
1340
1341/*---------------------------------------------------------------------------*/
1342/*---------------------------------------------------------------------------*/
1343
1344void ArcaneMain::
1345_dumpHelp()
1346{
1347 // Utilise un multimap car plusieurs services peuvent avoir le même nom.
1348 typedef std::multimap<String, IServiceInfo*> ServiceList;
1349 ServiceList service_list;
1350 Integer max_name_size = 0;
1351
1352 {
1353 // On veut lister par IServiceInfo. Comme il est possible qu'un service ait plusieurs
1354 // fabriques, on filtre grâce à done_set.
1355 std::set<IServiceInfo*> done_set;
1356 for (ServiceFactory2Collection::Enumerator j(application()->serviceFactories2()); ++j;) {
1357 IServiceInfo* si = (*j)->serviceInfo();
1358 if (done_set.find(si) != done_set.end()) {
1359 continue;
1360 }
1361 done_set.insert(si);
1362 const String& name = si->localName();
1363 max_name_size = math::max(max_name_size, CheckedConvert::toInteger(name.length()));
1364 service_list.insert(std::make_pair(name, si));
1365 }
1366 }
1367
1368 UniqueArray<String> module_names;
1369 for (EnumeratorT<IModuleFactoryInfo*> e = application()->moduleFactoryInfos(); ++e;) {
1370 IModuleFactoryInfo* mfi = (*e);
1371 const String& name = mfi->moduleName();
1372 max_name_size = math::max(max_name_size, CheckedConvert::toInteger(name.length()));
1373 module_names.add(name);
1374 }
1375
1376 ITraceMng* trace = application()->traceMng();
1377 trace->info() << " ";
1378 trace->info() << std::setw(max_name_size) << "Module List";
1379 trace->info() << std::setw(max_name_size) << "-------------"
1380 << "--";
1381 for (int i = 0, n = module_names.size(); i < n; ++i) {
1382 trace->info() << std::setw(max_name_size) << module_names[i];
1383 }
1384
1385 trace->info() << " ";
1386 trace->info() << std::setw(max_name_size) << "Service List";
1387 trace->info() << std::setw(max_name_size) << "--------------"
1388 << "--";
1389 for (ServiceList::const_iterator i = service_list.begin(); i != service_list.end(); ++i) {
1390 IServiceInfo* si = i->second;
1391 OStringStream oss;
1392 oss() << std::setw(max_name_size) << i->first;
1393 StringCollection interfaces = si->implementedInterfaces();
1394 if (!interfaces.empty())
1395 oss() << " Implements : ";
1396 for (EnumeratorT<String> e(interfaces.enumerator()); ++e;) {
1397 oss() << e.current() << " ";
1398 }
1399 trace->info() << oss.str();
1400 }
1401
1402 const Integer option_size = 20;
1403 trace->info() << " ";
1404 trace->info() << std::setw(max_name_size) << "Usage";
1405 trace->info() << std::setw(max_name_size) << "-------"
1406 << "--";
1407 trace->info() << application()->applicationName() << ".exe [-arcane_opt OPTION] dataset_file.arc";
1408 trace->info() << "Where OPTION is";
1409 trace->info() << std::setw(option_size) << "help"
1410 << " : this help page and abort";
1411 trace->info() << std::setw(option_size) << "arcane_internal"
1412 << " : save into a file internal Arcane informations and abort execution";
1413 trace->info() << std::setw(option_size) << "arcane_all_internal"
1414 << " : save into a file timeloop informations and abort execution";
1415 trace->info() << std::setw(option_size) << "arcane_database"
1416 << " : save internal database infos in file 'arcane_database.json'";
1417 trace->info() << std::setw(option_size) << "init_only"
1418 << " : only run initialization step";
1419 trace->info() << std::setw(option_size) << "continue"
1420 << " : continue an interrupted run";
1421 trace->info() << std::setw(option_size) << "max_iteration"
1422 << " : define maximum iteration number";
1423 trace->info() << std::setw(option_size) << "casename"
1424 << " : define case name";
1425}
1426
1427/*---------------------------------------------------------------------------*/
1428/*---------------------------------------------------------------------------*/
1434extern "C" void
1436{
1437 const char* signal_str = "Unknown";
1438 bool is_alarm = false;
1439 int written_signal_number = val;
1440
1441 switch (val) {
1442 case SIGSEGV:
1443 signal_str = "Segmentation Fault";
1444 break;
1445 case SIGFPE:
1446 signal_str = "Floating exception";
1447 break;
1448#ifdef SIGBUS
1449 case SIGBUS:
1450 signal_str = "Bus Error";
1451 break;
1452#endif
1453#ifdef SIGSYS
1454 case SIGSYS:
1455 signal_str = "System signal";
1456 break;
1457#endif
1458#ifdef SIGPIPE
1459 case SIGPIPE:
1460 signal_str = "Broken pipe";
1461 break;
1462#endif
1463#ifdef SIGALRM
1464 case SIGALRM:
1465 signal_str = "Sigalarm";
1466 is_alarm = true;
1467 break;
1468#endif
1469#ifdef SIGVTALRM
1470 case SIGVTALRM:
1471 signal_str = "Sigalarm(VirtualTime)";
1472 written_signal_number = SIGALRM;
1473 is_alarm = true;
1474 break;
1475#endif
1476 }
1477
1478 cerr << "Signal Caught !!! number=" << val << " name=" << signal_str << ".\n";
1479#ifdef ARCANE_DEBUG
1480 //arcaneDebugPause("SIGNAL");
1481#endif
1482
1483#ifndef ARCANE_OS_WIN32
1484 // Pour éviter que tous les PE écrivent le même fichier pour les SIGALRM,
1485 // seul le proc maitre le fait. Dans le cas des autres signaux, tout le monde
1486 // le fait.
1487 bool create_file = ArcaneMain::isMasterIO() || (!is_alarm);
1488 if (create_file) {
1489 // Crée le fichier 'signal_*' pour indiquer en parallèle qu'un
1490 // signal a été envoyé
1491 mode_t mode = S_IRUSR | S_IWUSR;
1492 char path[256];
1493 sprintf(path, "signal_%d", written_signal_number);
1494 path[255] = '\0';
1495 int fd = ::open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
1496 if (fd != (-1))
1497 ::close(fd);
1498 }
1499#endif
1500
1501 // Repositionne les signaux pour la prochaine fois, si le signal est
1502 // un signal qui peut être reçu plusieurs fois.
1503 arcaneRedirectSignals(arcaneSignalHandler);
1504
1505 Arcane::arcaneCallDefaultSignal(val);
1506 //::exit(val);
1507}
1508
1509/*---------------------------------------------------------------------------*/
1510/*---------------------------------------------------------------------------*/
1511
1512} // End namespace Arcane
1513
1514/*---------------------------------------------------------------------------*/
1515/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires pour la gestion des exceptions.
ARCCORE_COMMON_EXPORT Int32 print(ITraceMng *tm, bool is_no_continue=true)
Imprime un message pour une exception inconnue.
Fonctions de gestion mémoire et des allocateurs.
static int loadRuntime(AcceleratorRuntimeInitialisationInfo &init_info, const String &default_runtime_name, const String &library_path, bool &has_accelerator)
Détecte et charge la bibliothèque de gestion du runtime des accélérateurs.
Informations pour construire une instance de IApplication.
void parseArguments(const CommandLineArguments &args)
Analyse les arguments de args.
Informations sur une application.
const CommandLineArguments & commandLineArguments() const
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.
Integer count() const
Nombre d'éléments de la collection.
static void setUseFromChars(bool v)
Indique si on utilise 'std::from_chars' pour convertir les chaînes de caractères en un type numérique...
Classe template pour convertir un type.
Informations pour l'initialisation du runtime '.Net'.
Classe de base d'une exception.
bool isCollective() const
Vrai s'il s'agit d'une erreur collective (concerne tous les processeurs)
Exception lorsqu'une erreur fatale est survenue.
static FlexLMMng * instance()
Accès au singleton.
void init(IParallelSuperMng *parallel_super_mng)
Initialise le gestionnaire de licences.
void releaseAllLicenses()
Relache toutes les licences allouées.
Interface de l'application.
virtual String applicationName() const =0
Nom de l'application.
virtual IParallelSuperMng * parallelSuperMng()=0
Gestionnaire superviseur du parallélisme.
Interface de la classe de gestion du code.
Definition IArcaneMain.h:54
virtual IApplication * application() const =0
Application.
static IArcaneMain * arcaneMain()
static void setArcaneMain(IArcaneMain *arcane_main)
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
Interface d'un chargeur de cas.
Interface d'un fonctor pour exécuter du code directement après la création d'un sous-domaine sans pas...
Interface d'un chargeur dynamique de bibliothèque.
virtual IDynamicLibrary * open(const String &directory, const String &name)=0
Charge une bibliothèque dynamique.
static IDynamicLibraryLoader * getDefault()
Service utilisé pour charger dynamiquement des bibliothèques.
Manufacture des classes d'Arcane.
Informations sur la fabrique d'un module.
Classe abstraite du superviseur de parallélisme.
virtual bool isMasterIO() const =0
true si l'instance est un gestionnaire maître des entrées/sorties.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
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.
Interface du gestionnaire de traces.
virtual TraceMessage error()=0
Flot pour un message d'erreur.
virtual TraceMessage info()=0
Flot pour un message d'information.
Sorties des informations internes de Arcane.
void dumpArcaneDatabase()
Sauve les informations internes de Arcane dans un fichier json.
static void _buildSharedNull()
static void _destroySharedNull()
static void _destroySingleton()
Détruit le singleton.
static ItemTypeMng * _singleton()
Instance singleton du type.
Implémentation d'une collection d'éléments sous forme de vecteur.
Exception lorsqu'une erreur fatale 'parallèle' est générée.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Exception lorsqu'un signal survient.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:305
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:228
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
Definition MathUtils.h:392
void platformInitialize()
Initialisations spécifiques à une platforme.
ARCCORE_BASE_EXPORT String getCurrentDirectory()
Chemin du répertoire courant.
ARCCORE_BASE_EXPORT String getFileDirName(const String &file_name)
Retourne le nom du répertoire d'un fichier.
void platformTerminate()
Routines de fin de programme spécifiques à une platforme.
ARCCORE_BASE_EXPORT String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
void setHasDotNETRuntime(bool v)
Positionne si le code s'exécute avec le runtime .NET.
ARCCORE_BASE_EXPORT String getLoadedSharedLibraryFullPath(const String &dll_name)
Retourne le chemin complet d'une bibliothèque dynamique chargée.
ARCCORE_BASE_EXPORT void enableFloatingException(bool active)
Active ou désactive les exceptions lors d'un calcul flottant. Cette opération n'est pas supportée sur...
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 -*-
Int32 Integer
Type représentant un entier.
Collection< IServiceFactoryInfo * > ServiceFactoryInfoCollection
Collection d'informations sur les fabriques de service.
Collection< String > StringCollection
Collection de chaînes de caractères.
Definition UtilsTypes.h:506
void arcaneSignalHandler(int val)
Fonction appelee lorsque le programme est interrompu par le signal 'val'.
List< String > StringList
Tableau de chaînes de caractères unicode.
Definition UtilsTypes.h:509
Collection< IModuleFactoryInfo * > ModuleFactoryInfoCollection
Collection d'informations sur les fabriques de module.
List< IService * > ServiceList
Tableau de services.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.