Arcane  v4.1.2.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-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ArcaneMain.cc (C) 2000-2025 */
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 // N'active pas MPI si on utilise le service de parallélisme 'Sequential'
1045 String mp_service = defaultApplicationInfo().commandLineArguments().getParameter("MessagePassingService");
1046 if (mp_service=="Sequential")
1047 return;
1048
1049 auto si = _staticInfo();
1050 // Pour pouvoir automatiquement enregisrer MPI, il faut
1051 // appeler la méthode 'arcaneAutoDetectMessagePassingServiceMPI' qui se trouve
1052 // dans la bibliothèque dynamique 'arcane_mpi'.
1053
1054 typedef void (*ArcaneAutoDetectMPIFunctor)();
1055
1056 IDynamicLibraryLoader* dll_loader = IDynamicLibraryLoader::getDefault();
1057
1058 String os_dir(si->m_arcane_lib_path);
1059 String dll_name = "arcane_mpi";
1060 String symbol_name = "arcaneAutoDetectMessagePassingServiceMPI";
1061 IDynamicLibrary* dl = dll_loader->open(os_dir, dll_name);
1062 if (!dl)
1063 return;
1064
1065 bool is_found = false;
1066 void* functor_addr = dl->getSymbolAddress(symbol_name, &is_found);
1067 if (!is_found)
1068 return;
1069
1070 auto my_functor = reinterpret_cast<ArcaneAutoDetectMPIFunctor>(functor_addr);
1071 if (my_functor)
1072 (*my_functor)();
1073}
1074
1075/*---------------------------------------------------------------------------*/
1076/*---------------------------------------------------------------------------*/
1088_checkAutoDetectAccelerator(bool& has_accelerator)
1089{
1090 has_accelerator = false;
1091 String default_runtime_name;
1092#if defined(ARCANE_ACCELERATOR_RUNTIME)
1093 default_runtime_name = ARCANE_ACCELERATOR_RUNTIME;
1094#endif
1095 auto si = _staticInfo();
1096 AcceleratorRuntimeInitialisationInfo& init_info = si->m_accelerator_init_info;
1097 if (!init_info.isUsingAcceleratorRuntime())
1098 return 0;
1099 return Accelerator::Impl::RuntimeLoader::loadRuntime(init_info, default_runtime_name, si->m_arcane_lib_path, has_accelerator);
1100}
1101
1102/*---------------------------------------------------------------------------*/
1103/*---------------------------------------------------------------------------*/
1104
1105/*---------------------------------------------------------------------------*/
1106/*---------------------------------------------------------------------------*/
1107
1108IMainFactory* ArcaneMain::m_default_main_factory = nullptr;
1109ArcaneMainExecutionOverrideFunctor* ArcaneMain::m_exec_override_functor = nullptr;
1110
1111/*---------------------------------------------------------------------------*/
1112/*---------------------------------------------------------------------------*/
1113
1114ArcaneMain::
1115ArcaneMain(const ApplicationInfo& app_info, IMainFactory* factory)
1116: m_p(new Impl(app_info))
1117, m_main_factory(factory)
1118{
1119}
1120
1121/*---------------------------------------------------------------------------*/
1122/*---------------------------------------------------------------------------*/
1123
1124ArcaneMain::
1125ArcaneMain(const ApplicationInfo& app_info, IMainFactory* factory,
1126 const ApplicationBuildInfo& app_build_info,
1127 const DotNetRuntimeInitialisationInfo& dotnet_info,
1128 const AcceleratorRuntimeInitialisationInfo& accelerator_info)
1129: m_p(new Impl(app_info, app_build_info, dotnet_info, accelerator_info))
1130, m_main_factory(factory)
1131{
1132}
1133
1134/*---------------------------------------------------------------------------*/
1135/*---------------------------------------------------------------------------*/
1136
1137ArcaneMain::
1138~ArcaneMain()
1139{
1140 // S'assure qu'on retire les observateurs associés au TheadBindingMng
1141 // avant la finalisation pour éviter de punaiser les threads alors que
1142 // cela ne sert plus à rien.
1143 m_p->m_thread_binding_mng.finalize();
1144 delete m_application;
1145 delete m_p;
1146}
1147
1148/*---------------------------------------------------------------------------*/
1149/*---------------------------------------------------------------------------*/
1150
1151/*---------------------------------------------------------------------------*/
1152/*---------------------------------------------------------------------------*/
1153
1155build()
1156{
1157 _parseApplicationBuildInfoArgs();
1158 m_application = m_main_factory->createApplication(this);
1159 m_p->m_thread_binding_mng.initialize(m_application->traceMng(),
1160 m_p->m_application_build_info.threadBindingStrategy());
1161}
1162
1163/*---------------------------------------------------------------------------*/
1164/*---------------------------------------------------------------------------*/
1165
1167applicationInfo() const
1168{
1169 return m_p->m_app_info;
1170}
1171
1172/*---------------------------------------------------------------------------*/
1173/*---------------------------------------------------------------------------*/
1174
1175void ArcaneMain::
1176_parseApplicationBuildInfoArgs()
1177{
1178 ApplicationBuildInfo& abi = _applicationBuildInfo();
1179 abi.parseArguments(m_p->m_app_info.commandLineArguments());
1180 // Appelle les visiteurs enregistrés.
1181 {
1182 auto& x = _staticInfo()->m_application_build_info_visitors;
1183 for (IApplicationBuildInfoVisitor* v : x) {
1184 if (v)
1185 v->visit(abi);
1186 }
1187 }
1188 abi.setDefaultServices();
1189}
1190
1191/*---------------------------------------------------------------------------*/
1192/*---------------------------------------------------------------------------*/
1193
1195initialize()
1196{
1197 m_application->initialize();
1198
1199 ScopedPtrT<IServiceLoader> service_loader(m_main_factory->createServiceLoader());
1200 service_loader->loadApplicationServices(m_application);
1201}
1202
1203/*---------------------------------------------------------------------------*/
1204/*---------------------------------------------------------------------------*/
1205
1208{
1209 return _staticInfo()->m_service_factory_infos;
1210}
1211
1212/*---------------------------------------------------------------------------*/
1213/*---------------------------------------------------------------------------*/
1214
1217{
1218 return _staticInfo()->m_module_factory_infos;
1219}
1220
1221/*---------------------------------------------------------------------------*/
1222/*---------------------------------------------------------------------------*/
1223
1225execute()
1226{
1227 return 0;
1228}
1229
1230/*---------------------------------------------------------------------------*/
1231/*---------------------------------------------------------------------------*/
1232
1234doAbort()
1235{
1236 ::abort();
1237}
1238
1239/*---------------------------------------------------------------------------*/
1240/*---------------------------------------------------------------------------*/
1241
1243setErrorCode(int errcode)
1244{
1245 m_error_code = errcode;
1246 if (errcode != 0) {
1247 // Seul le proc maitre écrit le fichier sauf s'il s'agit d'un fatal car
1248 // dans ce cas n'importe quel PE peut le faire.
1249 if (ArcaneMain::m_is_master_io || errcode == 4) {
1250 String errname = "fatal_" + String::fromNumber(errcode);
1251 std::ofstream ofile(errname.localstr());
1252 ofile.close();
1253 }
1254 }
1255}
1256
1257/*---------------------------------------------------------------------------*/
1258/*---------------------------------------------------------------------------*/
1259
1262{
1263 // Si vrai, affichage des informations internes
1264 bool arcane_internal = false;
1265 // Si vrai, affichage des informations internes pour chaque boucle en temps
1266 bool arcane_all_internal = false;
1267 // Si vrai, génère un fichier contenant les infos internes du code.
1268 bool arcane_database = false;
1269 // Si vrai, affichage des informations sur les modules et services présents et une aide sommaire
1270 bool arcane_help = false;
1271
1272 String us_arcane_opt("-arcane_opt");
1273 String us_help("help");
1274 String us_arcane_internal("arcane_internal");
1275 String us_arcane_all_internal("arcane_all_internal");
1276 String us_arcane_database("arcane_database");
1277
1278 StringList unknown_args;
1279 for (Integer i = 0, s = args.count(); i < s; ++i) {
1280 if (args[i].startsWith("-A")) {
1281 continue;
1282 }
1283 if (args[i] != us_arcane_opt) {
1284 unknown_args.add(args[i]);
1285 continue;
1286 }
1287 bool is_valid_opt = false;
1288 ++i;
1289 String str;
1290 if (i < s)
1291 str = args[i];
1292 if (str == us_arcane_internal) {
1293 arcane_internal = true;
1294 is_valid_opt = true;
1295 }
1296 if (str == us_arcane_all_internal) {
1297 arcane_all_internal = true;
1298 is_valid_opt = true;
1299 }
1300 if (str == us_arcane_database) {
1301 arcane_database = true;
1302 is_valid_opt = true;
1303 }
1304 if (str == us_help) {
1305 arcane_help = true;
1306 is_valid_opt = true;
1307 }
1308 if (!is_valid_opt) {
1309 // Si l'option n'est pas valide, la rajoute à la liste des options
1310 // non traitées
1311 unknown_args.add(us_arcane_opt);
1312 if (!str.null())
1313 unknown_args.add(str);
1314 //trace->fatal() << "Unknown arcane option <" << str << ">\n";
1315 }
1316 }
1317
1318 bool do_stop = false;
1319 if (arcane_database) {
1321 dumper.dumpArcaneDatabase();
1322 do_stop = true;
1323 }
1324 if (arcane_internal) {
1326 dumper.dumpInternalInfos();
1327 do_stop = true;
1328 }
1329 if (arcane_all_internal) {
1331 dumper.dumpInternalAllInfos();
1332 do_stop = true;
1333 }
1334 if (arcane_help) {
1335 _dumpHelp();
1336 do_stop = true;
1337 }
1338
1339 args.clear();
1340 for (StringList::Enumerator i(unknown_args); ++i;)
1341 args.add(*i);
1342
1343 return do_stop;
1344}
1345
1346/*---------------------------------------------------------------------------*/
1347/*---------------------------------------------------------------------------*/
1348
1349void ArcaneMain::
1350_dumpHelp()
1351{
1352 // Utilise un multimap car plusieurs services peuvent avoir le même nom.
1353 typedef std::multimap<String, IServiceInfo*> ServiceList;
1354 ServiceList service_list;
1355 Integer max_name_size = 0;
1356
1357 {
1358 // On veut lister par IServiceInfo. Comme il est possible qu'un service ait plusieurs
1359 // fabriques, on filtre grâce à done_set.
1360 std::set<IServiceInfo*> done_set;
1361 for (ServiceFactory2Collection::Enumerator j(application()->serviceFactories2()); ++j;) {
1362 IServiceInfo* si = (*j)->serviceInfo();
1363 if (done_set.find(si) != done_set.end()) {
1364 continue;
1365 }
1366 done_set.insert(si);
1367 const String& name = si->localName();
1368 max_name_size = math::max(max_name_size, CheckedConvert::toInteger(name.length()));
1369 service_list.insert(std::make_pair(name, si));
1370 }
1371 }
1372
1373 UniqueArray<String> module_names;
1374 for (EnumeratorT<IModuleFactoryInfo*> e = application()->moduleFactoryInfos(); ++e;) {
1375 IModuleFactoryInfo* mfi = (*e);
1376 const String& name = mfi->moduleName();
1377 max_name_size = math::max(max_name_size, CheckedConvert::toInteger(name.length()));
1378 module_names.add(name);
1379 }
1380
1381 ITraceMng* trace = application()->traceMng();
1382 trace->info() << " ";
1383 trace->info() << std::setw(max_name_size) << "Module List";
1384 trace->info() << std::setw(max_name_size) << "-------------"
1385 << "--";
1386 for (int i = 0, n = module_names.size(); i < n; ++i) {
1387 trace->info() << std::setw(max_name_size) << module_names[i];
1388 }
1389
1390 trace->info() << " ";
1391 trace->info() << std::setw(max_name_size) << "Service List";
1392 trace->info() << std::setw(max_name_size) << "--------------"
1393 << "--";
1394 for (ServiceList::const_iterator i = service_list.begin(); i != service_list.end(); ++i) {
1395 IServiceInfo* si = i->second;
1396 OStringStream oss;
1397 oss() << std::setw(max_name_size) << i->first;
1398 StringCollection interfaces = si->implementedInterfaces();
1399 if (!interfaces.empty())
1400 oss() << " Implements : ";
1401 for (EnumeratorT<String> e(interfaces.enumerator()); ++e;) {
1402 oss() << e.current() << " ";
1403 }
1404 trace->info() << oss.str();
1405 }
1406
1407 const Integer option_size = 20;
1408 trace->info() << " ";
1409 trace->info() << std::setw(max_name_size) << "Usage";
1410 trace->info() << std::setw(max_name_size) << "-------"
1411 << "--";
1412 trace->info() << application()->applicationName() << ".exe [-arcane_opt OPTION] dataset_file.arc";
1413 trace->info() << "Where OPTION is";
1414 trace->info() << std::setw(option_size) << "help"
1415 << " : this help page and abort";
1416 trace->info() << std::setw(option_size) << "arcane_internal"
1417 << " : save into a file internal Arcane informations and abort execution";
1418 trace->info() << std::setw(option_size) << "arcane_all_internal"
1419 << " : save into a file timeloop informations and abort execution";
1420 trace->info() << std::setw(option_size) << "arcane_database"
1421 << " : save internal database infos in file 'arcane_database.json'";
1422 trace->info() << std::setw(option_size) << "init_only"
1423 << " : only run initialization step";
1424 trace->info() << std::setw(option_size) << "continue"
1425 << " : continue an interrupted run";
1426 trace->info() << std::setw(option_size) << "max_iteration"
1427 << " : define maximum iteration number";
1428 trace->info() << std::setw(option_size) << "casename"
1429 << " : define case name";
1430}
1431
1432/*---------------------------------------------------------------------------*/
1433/*---------------------------------------------------------------------------*/
1439extern "C" void
1441{
1442 const char* signal_str = "Unknown";
1443 bool is_alarm = false;
1444 int written_signal_number = val;
1445
1446 switch (val) {
1447 case SIGSEGV:
1448 signal_str = "Segmentation Fault";
1449 break;
1450 case SIGFPE:
1451 signal_str = "Floating exception";
1452 break;
1453#ifdef SIGBUS
1454 case SIGBUS:
1455 signal_str = "Bus Error";
1456 break;
1457#endif
1458#ifdef SIGSYS
1459 case SIGSYS:
1460 signal_str = "System signal";
1461 break;
1462#endif
1463#ifdef SIGPIPE
1464 case SIGPIPE:
1465 signal_str = "Broken pipe";
1466 break;
1467#endif
1468#ifdef SIGALRM
1469 case SIGALRM:
1470 signal_str = "Sigalarm";
1471 is_alarm = true;
1472 break;
1473#endif
1474#ifdef SIGVTALRM
1475 case SIGVTALRM:
1476 signal_str = "Sigalarm(VirtualTime)";
1477 written_signal_number = SIGALRM;
1478 is_alarm = true;
1479 break;
1480#endif
1481 }
1482
1483 cerr << "Signal Caught !!! number=" << val << " name=" << signal_str << ".\n";
1484#ifdef ARCANE_DEBUG
1485 //arcaneDebugPause("SIGNAL");
1486#endif
1487
1488#ifndef ARCANE_OS_WIN32
1489 // Pour éviter que tous les PE écrivent le même fichier pour les SIGALRM,
1490 // seul le proc maitre le fait. Dans le cas des autres signaux, tout le monde
1491 // le fait.
1492 bool create_file = ArcaneMain::isMasterIO() || (!is_alarm);
1493 if (create_file) {
1494 // Crée le fichier 'signal_*' pour indiquer en parallèle qu'un
1495 // signal a été envoyé
1496 mode_t mode = S_IRUSR | S_IWUSR;
1497 char path[256];
1498 sprintf(path, "signal_%d", written_signal_number);
1499 path[255] = '\0';
1500 int fd = ::open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
1501 if (fd != (-1))
1502 ::close(fd);
1503 }
1504#endif
1505
1506 // Repositionne les signaux pour la prochaine fois, si le signal est
1507 // un signal qui peut être reçu plusieurs fois.
1508 arcaneRedirectSignals(arcaneSignalHandler);
1509
1510 Arcane::arcaneCallDefaultSignal(val);
1511 //::exit(val);
1512}
1513
1514/*---------------------------------------------------------------------------*/
1515/*---------------------------------------------------------------------------*/
1516
1517} // End namespace Arcane
1518
1519/*---------------------------------------------------------------------------*/
1520/*---------------------------------------------------------------------------*/
#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.
String getParameter(const String &param_name) const
Récupère le paramètre de nom param_name.
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:510
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:513
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.