Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
Application.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/* Application.cc (C) 2000-2026 */
9/* */
10/* Supervisor. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
15
16#include "arcane/utils/Iostream.h"
17#include "arcane/utils/Iterator.h"
18#include "arcane/utils/List.h"
19#include "arcane/utils/ScopedPtr.h"
20#include "arcane/utils/Deleter.h"
21#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/ValueConvert.h"
23#include "arcane/utils/OStringStream.h"
24#include "arcane/utils/ITraceMng.h"
25#include "arcane/utils/TraceClassConfig.h"
26#include "arcane/utils/IMemoryInfo.h"
27#include "arcane/utils/IStackTraceService.h"
28#include "arcane/utils/ISymbolizerService.h"
29#include "arcane/utils/IProcessorAffinityService.h"
30#include "arcane/utils/IOnlineDebuggerService.h"
31#include "arcane/utils/StringBuilder.h"
32#include "arcane/utils/IProfilingService.h"
33#include "arcane/utils/IThreadImplementationService.h"
34#include "arccore/base/internal/IDynamicLibraryLoader.h"
35#include "arcane/utils/IPerformanceCounterService.h"
36#include "arcane/utils/ITraceMngPolicy.h"
37#include "arcane/utils/JSONReader.h"
38#include "arcane/utils/Profiling.h"
39
40#include "arccore/base/internal/DependencyInjection.h"
41//#include "arccore/concurrency/internal/TaskFactoryInternal.h"
42#include "arccore/concurrency/internal/ConcurrencyApplication.h"
43
44#include "arcane/core/ArcaneVersion.h"
45#include "arcane/core/ISubDomain.h"
46#include "arcane/core/IIOMng.h"
47#include "arcane/core/IXmlDocumentHolder.h"
48#include "arcane/core/IParallelSuperMng.h"
49#include "arcane/core/IMainFactory.h"
50#include "arcane/core/IArcaneMain.h"
51#include "arcane/core/IRessourceMng.h"
52#include "arcane/core/IServiceLoader.h"
53#include "arcane/core/IServiceMng.h"
54#include "arcane/core/ICodeService.h"
55#include "arcane/core/ISession.h"
56#include "arcane/core/IDataFactory.h"
57#include "arcane/core/IDataFactoryMng.h"
58#include "arcane/core/IXmlDocumentHolder.h"
59#include "arcane/core/XmlNode.h"
60#include "arcane/core/XmlNodeList.h"
61#include "arcane/core/ItemTypeMng.h"
63#include "arcane/core/IPhysicalUnitSystemService.h"
64#include "arcane/core/ServiceBuilder.h"
65#include "arcane/core/Configuration.h"
66#include "arcane/core/Directory.h"
67#include "arcane/core/IServiceAndModuleFactoryMng.h"
68#include "arcane/core/ApplicationBuildInfo.h"
69
70#include "arcane/core/IItemEnumeratorTracer.h"
71#include "arcane/impl/Application.h"
72#include "arcane/impl/ConfigurationReader.h"
73#include "arcane/impl/ArcaneMain.h"
74
75// These files are only used to display sizes
76// of classes defined in these files
78#include "arcane/core/Item.h"
79#include "arcane/core/IndexedItemConnectivityView.h"
80#include "arcane/core/UnstructuredMeshConnectivity.h"
81
82#include "arccore_version.h"
83
84#ifdef ARCANE_OS_WIN32
85#include <windows.h>
86#endif
87
88#include <vector>
89#include <set>
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94namespace Arcane
95{
96
97extern "C++" ARCANE_UTILS_EXPORT void
98arcaneSetPauseOnError(bool v);
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103extern "C++" IPhysicalUnitSystemService*
104createNullPhysicalUnitSystemService();
105extern "C++" IConfigurationMng*
106arcaneCreateConfigurationMng(ITraceMng* tm);
107extern "C++" ARCANE_IMPL_EXPORT IServiceAndModuleFactoryMng*
108arcaneCreateServiceAndModuleFactoryMng(ITraceMng* tm);
109extern "C++" ARCANE_IMPL_EXPORT Ref<IItemEnumeratorTracer>
110arcaneCreateItemEnumeratorTracer(ITraceMng* tm, Ref<IPerformanceCounterService> perf_counter);
111extern "C++" ARCANE_IMPL_EXPORT Ref<ICodeService>
112createArcaneCodeService(IApplication* app);
113extern "C++" ARCANE_CORE_EXPORT void
114arcaneSetSingletonItemEnumeratorTracer(Ref<IItemEnumeratorTracer> tracer);
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
119extern "C++" IApplication*
120arcaneCreateApplication(IArcaneMain* am)
121{
122 IApplication* sm = new Application(am);
123 sm->build();
124 return sm;
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130namespace
131{
133 _stringListToArray(const StringList& slist)
134 {
136 for (const String& s : slist)
137 a.add(s);
138 return a;
139 }
141 _stringListToCoreArray(const StringList& slist)
142 {
144 for (const String& s : slist)
145 a.add(s);
146 return a;
147 }
148} // namespace
149
150/*---------------------------------------------------------------------------*/
151/*---------------------------------------------------------------------------*/
152
153#if 0
154class Application::CoreApplication
155{
156 public:
157
158 void setTraceMng(ReferenceCounter<ITraceMng> tm) { m_trace = tm; }
159 void setCoreServices(const ApplicationCoreBuildInfo& build_info);
160
161 template <typename InterfaceType> Ref<InterfaceType>
162 tryCreateServiceUsingInjector(const StringList& names, String* found_name, bool has_trace);
163
164 public:
165
166 ReferenceCounter<ITraceMng> m_trace;
167 Ref<IStackTraceService> m_stack_trace_service;
168 Ref<ISymbolizerService> m_symbolizer_service;
169 Ref<IThreadImplementationService> m_thread_implementation_service;
170 Ref<IThreadImplementation> m_thread_implementation;
171 Ref<ITaskImplementation> m_task_implementation;
173 String m_used_thread_service_name;
175 String m_used_task_service_name;
176};
177#endif
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
189, m_namespace_uri(arcaneNamespaceURI())
190, m_local_name("Application")
191, m_arcane_main(am)
193, m_main_service_factory_infos(am->registeredServiceFactoryInfos())
194, m_main_module_factory_infos(am->registeredModuleFactoryInfos())
195, m_has_garbage_collector(am->hasGarbageCollector())
196{
197 m_core_application = std::make_unique<ConcurrencyApplication>();
198 // Initializes threads with a service that does nothing.
199 platform::setThreadImplementationService(&m_null_thread_implementation);
200}
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
212{
214 m_core_application->m_task_implementation.reset();
215
216 // Remove the services that the instance placed
217 if (platform::getProcessorAffinityService() == m_processor_affinity_service.get())
219
220 if (platform::getStackTraceService() == m_core_application->m_stack_trace_service.get())
222
223 if (platform::getSymbolizerService() == m_core_application->m_symbolizer_service.get())
225
226 if (platform::getProfilingService() == m_profiling_service.get())
228
229 if (platform::getPerformanceCounterService() == m_performance_counter_service.get())
231
232 delete m_service_and_module_factory_mng;
233
234 m_sessions.each(Deleter());
235
236 delete m_configuration_mng;
237 delete m_ressource_mng;
238
239 m_owned_sequential_parallel_super_mng.reset();
240 m_parallel_super_mng.reset();
241
242 m_data_factory_mng.reset();
243 delete m_io_mng;
244 delete m_service_mng;
245
246 m_trace = nullptr;
247 // The m_trace_policy must be destroyed after m_trace because the latter
248 // may use it.
249 delete m_trace_policy;
250
251 // Remove the reference to the thread manager. This must be done last because
252 // other managers may use it.
253 if (platform::getThreadImplementationService() == m_core_application->m_thread_implementation.get())
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
270template <typename InterfaceType> Ref<InterfaceType> Application::
271_tryCreateService(const StringList& names, String* found_name)
272{
273 if (found_name)
274 (*found_name) = String();
276 for (String s : names) {
277 auto t = sf.createReference(s, SB_AllowNull);
278 if (t.get()) {
279 if (found_name)
280 (*found_name) = s;
281 return t;
282 }
283 }
284 return {};
285}
286
287/*---------------------------------------------------------------------------*/
288/*---------------------------------------------------------------------------*/
289
290namespace
291{
292
300 template <typename InterfaceType> Ref<InterfaceType>
301 _tryCreateServiceUsingInjector(const StringList& names, String* found_name, ITraceMng* tm)
302 {
303 DependencyInjection::Injector injector;
304 injector.fillWithGlobalFactories();
305 // Adds the ITraceMng* instance
306 injector.bind(tm);
307
308 if (found_name)
309 (*found_name) = String();
310 for (String s : names) {
311 auto t = injector.createInstance<InterfaceType>(s, true);
312 if (t.get()) {
313 if (found_name)
314 (*found_name) = s;
315 return t;
316 }
317 }
318 return {};
319 }
320
321} // namespace
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
327build()
328{
329 const ApplicationBuildInfo& build_info = applicationBuildInfo();
330
331 // Creation of TraceMngPolicy. Complete initialization will be done later
332 // because we need additional information like the MPI rank and
333 // having read configuration files.
334 m_trace_policy = m_main_factory->createTraceMngPolicy(this);
335
336 // Always the first after TraceMngPolicy
337 m_trace = m_main_factory->createTraceMng();
338
339 {
340 // TODO: position these information in ApplicationBuildInfo.
341 Int32 output_level = build_info.outputLevel();
342 if (output_level != Trace::UNSPECIFIED_VERBOSITY_LEVEL) {
343 m_trace_policy->setVerbosityLevel(output_level);
344 m_trace_policy->setStandardOutputVerbosityLevel(output_level);
345 }
346 Int32 verbosity_level = build_info.verbosityLevel();
347 if (verbosity_level != Trace::UNSPECIFIED_VERBOSITY_LEVEL) {
348 m_trace_policy->setVerbosityLevel(verbosity_level);
349 }
350
351 bool has_output_file = build_info.isMasterHasOutputFile();
352 m_trace_policy->setIsMasterHasOutputFile(has_output_file);
353
354 // Positions the verbosity level leaving at least the level
355 // default. Without this, some initialization messages may not
356 // display, which can be problematic in case of issues or crashes.
357 Int32 minimal_verbosity_level = build_info.minimalVerbosityLevel();
358 if (minimal_verbosity_level == Trace::UNSPECIFIED_VERBOSITY_LEVEL)
359 minimal_verbosity_level = Trace::DEFAULT_VERBOSITY_LEVEL;
360 m_trace_policy->setDefaultVerboseLevel(m_trace.get(), minimal_verbosity_level);
361 }
362
363 arcaneGlobalMemoryInfo()->setTraceMng(traceMng());
364
365 {
366 // Displays some information during initialization starting at level 4
367 m_trace->info(4) << "*** Initialization informations:";
368 m_trace->info(4) << "*** PID: " << platform::getProcessId();
369 m_trace->info(4) << "*** Host: " << platform::getHostName();
370
372 if (dynamic_library_loader) {
373 String os_dir(m_exe_info.dataOsDir());
374#ifdef ARCANE_OS_WIN32
375 {
376 // On Windows, if the process is launched via 'dotnet', for example,
377 // the search paths for LoadLibrary() may have been modified
378 // and it no longer searches by default in the current directory
379 // to load native libraries. To correct this problem
380 // we reposition the behavior that allows adding paths
381 // users and we add 'os_dir' to this path.
382 // Without this, dependencies on libraries loaded by LoadLibrary()
383 // will not be found. For example, 'arcane_thread.dll' depends on 'tbb.dll' and
384 // both are in the same directory but if the directory is not
385 // in the allowed list, then 'tbb.dll' will not be found.
386 //
387 // NOTE: We might be able to avoid this by using LoadLibraryEx() and
388 // specifying LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR as the search flag.
389 // To check if this works when we no longer use the glib
390 // dynamic loader.
391 m_trace->info(4) << "Adding '" << os_dir << "' to search library path";
392 std::wstring wide_os_dir = StringUtils::convertToStdWString(os_dir);
393 SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
394 AddDllDirectory(wide_os_dir.c_str());
395 }
396#endif
397 for (StringCollection::Enumerator i(m_exe_info.dynamicLibrariesName()); ++i;) {
398 String name = *i;
399 m_trace->info(4) << "*** Trying to load dynamic library: " << name;
400 IDynamicLibrary* dl = dynamic_library_loader->open(os_dir, name);
401 if (!dl)
402 m_trace->info(4) << "WARNING: Can not load library '" << name << "'";
403 }
404 }
405
406#ifdef ARCANE_OS_WIN32
407 if (dynamic_library_loader) {
408 String os_dir(m_exe_info.dataOsDir());
409 // TODO: Add the directory containing 'arcane_impl' which is known
410 // in ArcaneMain to m_arcane_lib_path.
411 String dyn_lib_names[5] = {
412 "arcane_mpi",
413 "arcane_std",
414 "arcane_mesh",
415 "arcane_thread",
416 "arcane_mpithread",
417 };
418 for (Integer i = 0; i < 5; ++i)
419 dynamic_library_loader->open(os_dir, dyn_lib_names[i]);
420 }
421#endif
422
423 m_configuration_mng = arcaneCreateConfigurationMng(traceMng());
424
425 {
426 m_service_and_module_factory_mng = arcaneCreateServiceAndModuleFactoryMng(traceMng());
428 m_service_and_module_factory_mng->addGlobalFactory(*i);
430 m_service_and_module_factory_mng->addGlobalFactory(*i);
431
432 m_service_and_module_factory_mng->createAllServiceRegistererFactories();
433 }
434
435 m_service_mng = m_main_factory->createServiceMng(this);
436
437 String pause_on_error = platform::getEnvironmentVariable("ARCANE_PAUSE_ON_ERROR");
438 if (!pause_on_error.null())
439 arcaneSetPauseOnError(true);
440
441 {
442 m_core_application->setTraceMng(m_trace);
443 const auto& b = applicationBuildInfo();
444 auto task_names = _stringListToCoreArray(b.taskImplementationServices());
445 auto thread_names = _stringListToCoreArray(b.threadImplementationServices());
446 Int32 nb_task_thread = b.nbTaskThread();
447 ConcurrencyApplicationBuildInfo c(task_names.constView(), thread_names.constView(), nb_task_thread);
448 m_core_application->setCoreServices(c);
449 }
450
451 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_LOOP_PROFILING_LEVEL", true))
453
454 // Search for the service used for profiling
455 {
456 String profile_str = platform::getEnvironmentVariable("ARCANE_PROFILING");
457 if (!profile_str.null()) {
459 auto sv = sf.createReference(profile_str + "ProfilingService", SB_AllowNull);
460 if (sv.get()) {
461 m_profiling_service = sv;
463 }
464 else
465 ARCANE_FATAL("Can not find profiling service (name='{0}')", profile_str);
466 }
467 }
468
469 // By default, we hook the Hyoda service
470 {
472 auto sv = sf.createReference("Hyoda", SB_AllowNull);
473 if (sv.get()) {
474 m_online_debugger = sv;
476 }
477 }
478
479 // Search for the service used for processor affinity management
480 {
481 StringList names;
482 names.add("HWLoc");
483 String found_name;
484 auto sv = _tryCreateServiceUsingInjector<IProcessorAffinityService>(names, &found_name, m_trace.get());
485 if (sv.get()) {
486 m_processor_affinity_service = sv;
488 }
489 else {
490 m_trace->info(4) << "Can not find implementation for IProcessorAffinityService "
491 << "(names=" << _stringListToArray(names) << ").";
492 }
493 }
494
495 // Search for the service used for parallelism
496 String message_passing_service = build_info.messagePassingService();
497 if (message_passing_service.null())
498 message_passing_service = build_info.internalDefaultMessagePassingService();
500 auto sm = sf.createReference(message_passing_service, SB_AllowNull);
501 if (!sm)
502 ARCANE_FATAL("Can not find message passing service '{0}'", message_passing_service);
503
505 m_parallel_super_mng->initialize();
506
507 IParallelSuperMng* seq_sm = nullptr;
508 if (sm->isParallel()) {
509 m_owned_sequential_parallel_super_mng = sf.createReference("SequentialParallelSuperMng", SB_AllowNull);
510 seq_sm = m_owned_sequential_parallel_super_mng.get();
511 if (!seq_sm)
512 ARCANE_FATAL("Can not find service 'SequentialParallelSuperMng'");
513 seq_sm->initialize();
514 }
515 else
516 seq_sm = m_parallel_super_mng.get();
517
519
521 m_io_mng = m_main_factory->createIOMng(this);
522 m_data_factory_mng = m_main_factory->createDataFactoryMngRef(this);
523 }
524
525 {
526 VersionInfo version_info = m_exe_info.codeVersion();
527 int vmajor = version_info.versionMajor();
528 int vminor = version_info.versionMinor();
529 int vpatch = version_info.versionPatch();
530 m_main_version_str = String::format("{0}.{1}.{2}", vmajor, vminor, vpatch);
531 m_major_and_minor_version_str = String::format("{0}.{1}", vmajor, vminor);
533 if (vpatch != 0)
535 }
536
537 m_targetinfo_str = m_exe_info.targetFullName();
538 m_application_name = m_exe_info.applicationName();
539 m_code_name = m_exe_info.codeName();
540
541 // Get the user name
543
544 // Get the path to the user configuration directory
545 // TODO: it must be changed because in the new POSIX recommendations,
546 // the configuration directory is '.config/arcane'.
548 if (m_user_config_path.null()) {
549 Directory user_home_env(platform::getHomeDirectory());
550 m_user_config_path = Directory(user_home_env, ".arcane").path();
551 }
552
553 {
554 bool is_parallel = parallelSuperMng()->isParallel();
555 bool is_debug = applicationInfo().isDebug();
556 // Creation and initialization of TraceMngPolicy.
557 m_trace_policy->setIsParallel(is_parallel);
558 m_trace_policy->setIsDebug(is_debug);
559 bool is_parallel_output = is_parallel && is_debug;
560 // Allows forcing outputs even in optimized mode
561 {
562 String s = platform::getEnvironmentVariable("ARCANE_PARALLEL_OUTPUT");
563 if (!s.null())
564 is_parallel_output = true;
565 if (s == "0")
566 is_parallel_output = false;
567 }
568 m_trace_policy->setIsParallelOutput(is_parallel_output);
569 }
570
571 m_is_master = m_parallel_super_mng->commRank() == 0;
572
573 m_trace->info(4) << "*** UserName: " << m_user_name;
574 m_trace->info(4) << "*** HomeDirectory: " << platform::getHomeDirectory();
575
576#ifdef ARCANE_CHECK_MEMORY
577 arcaneGlobalMemoryInfo()->setTraceMng(m_trace);
578#endif
579}
580
581/*---------------------------------------------------------------------------*/
582/*---------------------------------------------------------------------------*/
583
586{
587 if (m_is_init) {
588 m_trace->warning() << "Application is already initialised";
589 return;
590 }
591
592 bool is_debug = m_exe_info.isDebug();
593
594 // Analyze the user configuration file
596
597 //m_trace->info() << "Application init trace mng rank=" << m_parallel_super_mng->traceRank();
598 m_trace_policy->setDefaultClassConfigXmlBuffer(userConfigBuffer());
599 m_trace_policy->initializeTraceMng(m_trace.get(), m_parallel_super_mng->traceRank());
600
601 m_trace->logdate() << "Begin execution.";
602
603 if (is_debug)
604 m_trace->info() << "WARNING: Execution in DEBUG mode!";
605
606#ifdef ARCANE_CHECK
607 m_trace->info() << "WARNING: Compilation in CHECK mode !";
608#endif
609
610 // Active or deactivate a partial check mode if the corresponding environment variable
611 // is set.
612 String check_str = platform::getEnvironmentVariable("ARCANE_CHECK");
613 if (!check_str.null()) {
614 bool is_check = check_str != "0";
615 m_trace->info() << "WARNING: Setting CHECK mode to " << is_check;
616 arcaneSetCheck(is_check);
617 }
618 if (arcaneIsCheck()) {
619 m_trace->info() << "WARNING: Execution in CHECK mode!";
620 }
621
622#ifdef ARCANE_TRACE
623 m_trace->info() << "WARNING: Execution in TRACE mode !";
624#endif
625#ifdef ARCANE_64BIT
626 m_trace->info() << "Using 64bits version!";
627#endif
628
629 m_trace->info() << "** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- **";
630 m_trace->info() << "** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- **";
631 m_trace->info() << " ";
632 m_trace->info() << " "
633 << m_exe_info.applicationName();
634 m_trace->info() << " ";
635 VersionInfo version_info = m_exe_info.codeVersion();
636 m_trace->info() << " Version "
637 << version_info.versionMajor() << "."
638 << version_info.versionMinor() << "."
639 << version_info.versionPatch();
640
641 m_trace->info() << " ";
642 m_trace->info() << "** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- **";
643 m_trace->info() << "** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- ** -- **";
644 m_trace->info() << "Date: " << platform::getCurrentDateTime();
645 m_trace->info() << "MemoryUsage: " << static_cast<Int64>(platform::getMemoryUsed() / 1.0e6) << " (MegaBytes)";
646 m_trace->info() << "ArccoreVersion: " << ARCCORE_VERSION_STR_FULL;
647 m_trace->info() << "ArcaneVersion: " << ARCANE_VERSION_STR_FULL
648 << " (Compiler: " << platform::getCompilerId() << ")";
649 m_trace->info() << "Current process pid=" << platform::getProcessId()
650 << " machine=" << platform::getHostName();
651 m_trace->info() << "MessagePassing service=" << applicationBuildInfo().messagePassingService();
652
654 m_trace->info() << "Stack trace service is available";
655 }
657 m_trace->info() << "Symbolizer service is available";
658 }
659
660#ifdef ARCANE_USE_LIBXML2
661 m_trace->info() << "Using 'libxml2' for XML parsing";
662#endif
663
664 // Display info about processors
665 {
667 if (pas) {
668 pas->printInfos();
669 }
670 }
671
672 // Display if we have a debug service
674 m_trace->info() << "Hyoda service is now hooked";
675 }
676 else {
677 m_trace->info() << "Unknown online debugger service";
678 }
679
680 m_is_init = true;
681
682 // Analyze the code configuration file.
683 _readCodeConfigurationFile();
684
685 {
686 // Construction of internal types
688 }
689
690 {
691 ByteConstSpan runtime_config = m_exe_info.runtimeConfigFileContent();
692 if (!runtime_config.empty()) {
693 m_trace->info() << "Reading configuration parameters from runtime config file";
694 JSONDocument jdoc;
695 jdoc.parse(runtime_config);
696 JSONValue config = jdoc.root().child("configuration");
697 ConfigurationReader cr(m_trace.get(), m_configuration_mng->defaultConfiguration());
698 cr.addValuesFromJSON(config, ConfigurationReader::P_GlobalRuntime);
699 }
700 }
701 {
702 if (!m_config_root_element.null()) {
703 XmlNode configuration_elem = m_config_root_element.child("configuration");
704 if (!configuration_elem.null()) {
705 m_trace->info() << "Reading configuration parameters from code config file";
706 ConfigurationReader cr(m_trace.get(), m_configuration_mng->defaultConfiguration());
707 cr.addValuesFromXmlNode(configuration_elem, ConfigurationReader::P_Global);
708 }
709 }
710 }
711
712 _initDataInitialisationPolicy();
713
714 {
715 if (!m_core_application->m_used_thread_service_name.null())
716 m_trace->info() << "Service used for thread management : '" << m_core_application->m_used_thread_service_name << "'";
717 else
718 m_trace->info() << "No thread management active";
719
720 if (!m_core_application->m_used_task_service_name.null()) {
721 m_trace->info() << "Service used for task management : '" << m_core_application->m_used_task_service_name
722 << "' (max_task_thread=" << TaskFactory::nbAllowedThread() << ")";
723 std::ostringstream ostr;
725 m_trace->info() << "TaskManagement infos:" << ostr.str();
726 }
727 else
728 m_trace->info() << "No task management active";
729 }
730
731 // Search for the service used to manage the unit system.
732 {
734 String service_name = "Udunits";
735 auto sv = sf.createReference(service_name, SB_AllowNull);
736 if (sv.get()) {
737 m_trace->info() << "UnitSystem service found name=" << service_name;
738 }
739 else {
740 m_trace->info() << "No unit system service found";
741 sv = makeRef(createNullPhysicalUnitSystemService());
742 }
743 m_physical_unit_system_service = sv;
744 }
745
746 // Searches for the service used to manage performance counters.
747 {
748 String service_name = "LinuxPerfPerformanceCounterService";
749 String env_service_name = platform::getEnvironmentVariable("ARCANE_PERFORMANCE_COUNTER_SERVICE");
750 if (!env_service_name.null())
751 service_name = env_service_name + "PerformanceCounterService";
753 auto p = sbuilder.createReference(service_name, SB_AllowNull);
754 m_performance_counter_service = p;
755 if (p.get()) {
756 m_trace->info() << "PerformanceCounterService found name=" << service_name;
757 }
758 else {
759 m_trace->info() << "No performance counter service found";
760 }
761 }
762
763 // Initializes the enumerator tracer.
764 {
765 bool force_tracer = false;
766 String trace_str = platform::getEnvironmentVariable("ARCANE_TRACE_ENUMERATOR");
767 if (!trace_str.null() || ProfilingRegistry::profilingLevel() >= 1 || force_tracer) {
768 if (!TaskFactory::isActive()) {
770 auto p = m_performance_counter_service;
771 if (p.get()) {
772 m_trace->info() << "Enumerator tracing is enabled";
773 Ref<IItemEnumeratorTracer> tracer(arcaneCreateItemEnumeratorTracer(traceMng(), p));
774 arcaneSetSingletonItemEnumeratorTracer(tracer);
775 p->initialize();
776 p->start();
777 }
778 else
779 m_trace->info() << "WARNING: enumerator tracing is not available because no performance counter service is available.";
780 }
781 else
782 m_trace->info() << "WARNING: enumerator tracing is not available when using multi-tasking.";
783 }
784 }
785
786 m_trace->info() << "sizeof(ItemInternal)=" << sizeof(ItemInternal)
787 << " sizeof(ItemInternalConnectivityList)=" << sizeof(ItemInternalConnectivityList)
788 << " sizeof(ItemSharedInfo)=" << sizeof(ItemSharedInfo);
789 m_trace->info() << "sizeof(ItemLocalId)=" << sizeof(ItemLocalId)
790 << " sizeof(ItemConnectivityContainerView)=" << sizeof(ItemConnectivityContainerView)
791 << " sizeof(UnstructuredMeshConnectivityView)=" << sizeof(UnstructuredMeshConnectivityView);
792 m_trace->info() << "sizeof(Item)=" << sizeof(Item)
793 << " sizeof(ItemEnumerator)=" << sizeof(ItemEnumerator)
794 << " sizeof(ItemVectorView)=" << sizeof(ItemVectorView)
795 << " sizeof(ItemVectorViewConstIterator)=" << sizeof(ItemVectorViewConstIterator)
796 << " ItemEnumeratorVersion=" << ItemEnumerator::version();
797 m_trace->info() << "sizeof(eItemKind)=" << sizeof(eItemKind)
798 << " sizeof(IndexedItemConnectivityViewBase)=" << sizeof(IndexedItemConnectivityViewBase);
799
800 {
801 Real init_time_accelerator = ArcaneMain::initializationTimeForAccelerator() * 1000.0;
802 if (init_time_accelerator != 0.0)
803 m_trace->info() << "Time (in ms) to initialize Accelerators = " << init_time_accelerator;
804 }
805}
806
807/*---------------------------------------------------------------------------*/
808/*---------------------------------------------------------------------------*/
809
810void Application::
811_readCodeConfigurationFile()
812{
813 // Analyzes the code configuration file.
814 const ApplicationBuildInfo& build_info = applicationBuildInfo();
815
816 // Retrieves the configuration file name.
817 // If null, it indicates that there is no configuration file.
818 // If empty (default), it retrieves the name from the code name.
819 // Otherwise, it uses the name specified in the configuration.
820
821 // Note that this value must be the same for all PE otherwise it
822 // will block (TODO: potentially reduce)
823 String config_file_name = build_info.configFileName();
824
825 bool use_config_file = true;
826 if (config_file_name.null()) {
827 use_config_file = false;
828 }
829 else if (config_file_name.empty()) {
830 // First checks the current directory, otherwise checks the shared
831 // data directory (share).
832 // For parallel performance reasons, only the master processor
833 // performs the test.
834 StringBuilder buf;
835 if (m_is_master) {
836 buf = m_exe_info.codeName();
837 buf += ".config";
838 if (!platform::isFileReadable(buf.toString())) {
839 buf = m_exe_info.dataDir();
840 buf += "/";
841 buf += m_exe_info.codeName();
842 buf += ".config";
843 }
844 else {
845 m_trace->info() << "Using configuration file in current directory.";
846 }
847 }
848 config_file_name = buf.toString();
849 }
850 m_trace->info() << "Using configuration file: '" << config_file_name << "'";
851
852 if (use_config_file) {
853 bool bad_file = m_io_mng->collectiveRead(config_file_name, m_config_bytes);
854 if (bad_file)
855 ARCANE_FATAL("Can not read configuration file '{0}'", config_file_name);
856 m_config_document = m_io_mng->parseXmlBuffer(m_config_bytes, config_file_name);
857 if (!m_config_document.get())
858 ARCANE_FATAL("Can not parse configuration file '{0}'", config_file_name);
859 m_config_root_element = m_config_document->documentNode().documentElement();
860 }
861}
862
863/*---------------------------------------------------------------------------*/
864/*---------------------------------------------------------------------------*/
865
871{
872 Directory user_config_dir(m_user_config_path);
873 String buf = user_config_dir.file("config.xml");
874
875 //ByteUniqueArray bytes;
876 bool bad_file = m_io_mng->collectiveRead(buf, m_user_config_bytes);
877 if (bad_file) {
878 if (m_is_master)
879 m_trace->log() << "No user configuration file '" << buf << "'";
880 return;
881 }
882
883 IXmlDocumentHolder* doc = m_io_mng->parseXmlBuffer(m_user_config_bytes, buf);
884 if (!doc) {
885 if (m_is_master)
886 m_trace->log() << "Can not parse user configuration file '" << buf << "'";
887 return;
888 }
889
892}
893
894/*---------------------------------------------------------------------------*/
895/*---------------------------------------------------------------------------*/
896
897namespace
898{
899 bool _hasExtension(ICodeService* service, const String& extension)
900 {
901 StringCollection extensions = service->validExtensions();
902 for (StringCollection::Enumerator j(extensions); ++j;) {
903 if ((*j) == extension)
904 return true;
905 }
906 return false;
907 }
908} // namespace
909
910/*---------------------------------------------------------------------------*/
911/*---------------------------------------------------------------------------*/
912
914getCodeService(const String& u_file_name)
915{
916 ServiceBuilder<ICodeService> builder(this);
917 auto services = builder.createAllInstances();
918
919 // Checks if a service manages the '.arc' extension.
920 // If none exists, ArcaneCodeService is used for
921 // this extension.
922 {
923 bool has_arc_extension = false;
924 for (Integer i = 0, n = services.size(); i < n; ++i) {
925 ICodeService* code_service = services[i].get();
926 if (_hasExtension(code_service, "arc")) {
927 has_arc_extension = true;
928 break;
929 }
930 }
931 if (!has_arc_extension) {
932 services.add(createArcaneCodeService(this));
933 }
934 }
935
936 // Finds the file extension and stores it in \a case_ext
937 std::string_view fview = u_file_name.toStdStringView();
938 std::size_t extension_pos = fview.find_last_of('.');
939 if (extension_pos == std::string_view::npos)
940 return {};
941 fview.remove_prefix(extension_pos + 1);
942 String case_ext(fview);
943
944 Ref<ICodeService> found_service;
945 for (const auto& code_service : services) {
946 StringCollection extensions = code_service->validExtensions();
947 for (StringCollection::Enumerator j(extensions); ++j;) {
948 if (case_ext == (*j)) {
949 found_service = code_service;
950 break;
951 }
952 }
953 if (found_service.get())
954 break;
955 }
956 // TODO: return a reference.
957 return found_service;
958}
959
960/*---------------------------------------------------------------------------*/
961/*---------------------------------------------------------------------------*/
962
964addSession(ISession* session)
965{
966 m_sessions.add(session);
967}
968
969/*---------------------------------------------------------------------------*/
970/*---------------------------------------------------------------------------*/
971
973removeSession(ISession* session)
974{
975 m_sessions.remove(session);
976}
977
978/*---------------------------------------------------------------------------*/
979/*---------------------------------------------------------------------------*/
980
983{
984 return m_service_and_module_factory_mng->serviceFactories2();
985}
986
987/*---------------------------------------------------------------------------*/
988/*---------------------------------------------------------------------------*/
989
992{
993 return m_service_and_module_factory_mng->moduleFactoryInfos();
994}
995
996/*---------------------------------------------------------------------------*/
997/*---------------------------------------------------------------------------*/
998
999void Application::
1000_initDataInitialisationPolicy()
1001{
1002 String data_init_policy = platform::getEnvironmentVariable("ARCANE_DATA_INIT_POLICY");
1004 bool is_changed = false;
1005 if (data_init_policy == "DEFAULT") {
1006 init_policy = DIP_InitWithDefault;
1007 is_changed = true;
1008 }
1009 else if (data_init_policy == "NAN") {
1010 init_policy = DIP_InitWithNan;
1011 is_changed = true;
1012 }
1013 else if (data_init_policy == "NONE") {
1014 init_policy = DIP_None;
1015 is_changed = true;
1016 }
1017 else if (data_init_policy == "LEGACY") {
1018 init_policy = DIP_Legacy;
1019 is_changed = true;
1020 }
1021 else if (data_init_policy == "NAN_AND_DEFAULT") {
1023 is_changed = true;
1024 }
1025 if (is_changed) {
1027 init_policy = getGlobalDataInitialisationPolicy();
1028 m_trace->info() << "Change data initialisation policy: " << data_init_policy
1029 << " (" << (int)init_policy << ")";
1030 }
1031 m_trace->info() << "Data initialisation policy is : " << (int)init_policy;
1032}
1033
1034/*---------------------------------------------------------------------------*/
1035/*---------------------------------------------------------------------------*/
1036
1039{
1040 return m_arcane_main->applicationBuildInfo();
1041}
1042
1043/*---------------------------------------------------------------------------*/
1044/*---------------------------------------------------------------------------*/
1045
1048{
1049 return m_arcane_main->dotnetRuntimeInitialisationInfo();
1050}
1051
1052/*---------------------------------------------------------------------------*/
1053/*---------------------------------------------------------------------------*/
1054
1057{
1058 return m_arcane_main->acceleratorRuntimeInitialisationInfo();
1059}
1060
1061/*---------------------------------------------------------------------------*/
1062/*---------------------------------------------------------------------------*/
1063
1065createAndInitializeTraceMng(ITraceMng* parent_trace, const String& file_suffix)
1066{
1069 tmp->initializeTraceMng(tm, parent_trace, file_suffix);
1070 return tm;
1071}
1072
1073/*---------------------------------------------------------------------------*/
1074/*---------------------------------------------------------------------------*/
1075
1078{
1079 return m_data_factory_mng->deprecatedOldFactory();
1080}
1081
1082/*---------------------------------------------------------------------------*/
1083/*---------------------------------------------------------------------------*/
1084
1086dataFactoryMng() const
1087{
1088 return m_data_factory_mng.get();
1089}
1090
1091/*---------------------------------------------------------------------------*/
1092/*---------------------------------------------------------------------------*/
1093
1094} // End namespace Arcane
1095
1096/*---------------------------------------------------------------------------*/
1097/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Classes, Types, and macros for managing concurrency.
Types and macros for iterating over mesh entities.
Utility functions for character strings.
std::wstring convertToStdWString(const String &str)
Returns the conversion of str to std::wstring.
Definition String.cc:1299
Information for constructing an instance of IApplication.
String configFileName() const
Name of the code configuration file.
const String & dataDir() const
Returns the path where data files are located.
const String & codeName() const
Returns the name of the calculation code linked to the application.
bool isDebug() const
Returns true if running in debug mode.
String m_user_config_path
User configuration directory.
void _openUserConfig()
Analyzes the user configuration file.
ReferenceCounter< ITraceMng > m_trace
Trace manager.
~Application() override
Destroys the manager.
ModuleFactoryInfoCollection m_main_module_factory_infos
Array of module factories.
IDataFactory * dataFactory() override
Data factory.
ScopedPtrT< IXmlDocumentHolder > m_config_document
Configuration DOM tree.
const ApplicationBuildInfo & applicationBuildInfo() const override
Instance build parameter information.
ApplicationInfo m_exe_info
Executable information.
String m_major_and_minor_version_str
Version M.m.
ITraceMngPolicy * getTraceMngPolicy() override
Trace manager configuration policy.
String m_version_str
Configuration info.
ITraceMng * createAndInitializeTraceMng(ITraceMng *parent_trace, const String &file_suffix) override
Creates and initializes an instance of ITraceMng.
IMainFactory * m_main_factory
Main factory.
const DotNetRuntimeInitialisationInfo & dotnetRuntimeInitialisationInfo() const override
'.Net' runtime initialization information.
IMainFactory * mainFactory() const override
Main factory.
SessionList m_sessions
List of sessions.
Ref< InterfaceType > _tryCreateService(const StringList &names, String *found_name)
const AcceleratorRuntimeInitialisationInfo & acceleratorRuntimeInitialisationInfo() const override
Runtime initialization information for accelerators.
String m_user_name
User name.
IRessourceMng * m_ressource_mng
Resource manager.
const ApplicationInfo & applicationInfo() const override
Executable information.
Definition Application.h:88
IDataFactoryMng * dataFactoryMng() const override
Data factory.
XmlNode m_user_config_root_element
User configuration root element.
String m_main_version_str
Version in Major.minor.beta format.
void initialize() override
Initializes the instance. The instance is not usable until this method has been called.
ModuleFactoryInfoCollection moduleFactoryInfos() override
List of module factory information.
UniqueArray< Byte > m_user_config_bytes
File containing the user configuration.
bool m_is_init
true if already initialized
void build() override
Constructs the instance members. The instance is not usable until this method has been called....
ITraceMng * traceMng() const override
Trace manager.
Definition Application.h:75
XmlNode m_config_root_element
Configuration root element.
String m_application_name
Application name.
String m_targetinfo_str
Configuration info.
ScopedPtrT< IXmlDocumentHolder > m_user_config_document
User configuration DOM tree.
ServiceFactoryInfoCollection m_main_service_factory_infos
Array of service factories.
ServiceFactory2Collection serviceFactories2() override
List of service factories.
bool hasGarbageCollector() const override
Indicates that certain objects are managed via a garbage collector.
Ref< ICodeService > getCodeService(const String &file_name) override
Returns the case loader corresponding to the file given by file_name.
Ref< IParallelSuperMng > m_parallel_super_mng
Parallelism manager.
IServiceMng * m_service_mng
Service manager.
void removeSession(ISession *s) override
Removes the session session.
IIOMng * m_io_mng
Input/output manager.
UniqueArray< Byte > m_config_bytes
File containing the configuration.
void addSession(ISession *s) override
Adds the session session.
Ref< IDataFactoryMng > m_data_factory_mng
Data factory.
IParallelSuperMng * m_sequential_parallel_super_mng
Sequential parallelism manager.
Application(IArcaneMain *)
Constructs a supervisor with execution information, e.g.
IParallelSuperMng * parallelSuperMng() override
Supervisory parallelism manager.
Definition Application.h:79
static Real initializationTimeForAccelerator()
Returns the time (in seconds) for the initialization of accelerator runtimes for this process.
Configuration file readers.
void addValuesFromXmlNode(const XmlNode &element, Integer priority)
Adds values to the configuration.
void addValuesFromJSON(const JSONValue &jv, Integer priority)
Adds values to the configuration.
Template class for converting a type.
Utility class for destroying objects allocated by new.
Definition Deleter.h:33
Class managing a directory.
Definition Directory.h:36
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Definition Directory.cc:120
String path() const override
Returns the path of the directory.
Definition Directory.cc:111
Information for the initialization of the '.Net' runtime.
Application interface.
Interface of the code management class.
Definition IArcaneMain.h:55
Interface of a case loader.
virtual StringCollection validExtensions() const =0
Returns the list of file extensions processed by the instance. The extension does not include the '....
Configuration manager.
Interface of the data factory manager.
Interface of a data factory.
Interface of a dynamic library loader.
virtual IDynamicLibrary * open(const String &directory, const String &name)=0
Loads a dynamic library.
static IDynamicLibraryLoader * getDefault()
Service used for dynamically loading libraries.
Interface of a dynamic library.
virtual ITraceMng * createTraceMng()=0
Creates a trace manager.
Abstract class of the parallelism supervisor.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
virtual void initialize()=0
Initializes the instance.
Interface of a service managing a unit system.
Interface of a CPU core affinity management service.
virtual void printInfos()=0
Displays complete topology information via info().
static IRessourceMng * createDefault(IApplication *)
Creation of a default history manager.
Interface of a service and module factory manager.
Interface for a case execution session.
Definition ISession.h:38
Interface for the configuration manager of a trace manager.
virtual void initializeTraceMng(ITraceMng *trace, Int32 rank)=0
Initializes trace.
Manager of a DOM document.
virtual XmlNode documentNode()=0
Document node. This node is null if the document does not exist.
Base class for a view on unstructured connectivity.
Views of containers holding connectivity. This class allows the containers used to be opaque outside ...
Enumerator over a list of entities.
Connectivity information, for an entity family, allowing transition between old and new connectivity ...
Internal structure of a mesh entity.
Index of an Item in a variable.
Definition ItemLocalId.h:42
Internal shared structure of a mesh entity.
void build(IParallelSuperMng *parallel_mng, ITraceMng *trace)
Effective constructor.
static ItemTypeMng * _singleton()
Singleton instance of the type.
Iterator for the ItemVectorView class.
View on a vector of entities.
Base class for a mesh element.
Definition Item.h:84
void parse(Span< const Byte > bytes)
Reads the file in UTF-8 format.
JSONValue root() const
Root element.
JSONValue child(StringView name) const
Child value with name name. Returns a null value if not found.
static void setProfilingLevel(Int32 level)
Sets the profiling level.
Definition Profiling.cc:309
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Utility class for instantiating a service of a given interface.
UniqueArray< Ref< InterfaceType > > createAllInstances()
Creates an instance of every service that implements InterfaceType.
Ref< InterfaceType > createReference(const String &name, eServiceBuilderProperties properties=SB_None)
Creates an instance implementing the InterfaceType interface.
bool null() const
Returns true if the string is null.
Definition String.cc:306
bool empty() const
True if the string is empty (null or "").
Definition String.cc:317
std::string_view toStdStringView() const
Returns an STL view of the current string.
Definition String.cc:350
static Int32 nbAllowedThread()
Maximum number of threads used to manage tasks.
static void terminate()
Indicates that threads will no longer be used. This method must not be called when tasks are active.
static bool isActive()
Indicates whether tasks are active. Tasks are active if an implementation is available and if the req...
static void printInfos(std::ostream &o)
Prints information about the implementation.
1D data vector with value semantics (STL style).
View of the standard connectivities of an unstructured mesh.
Information about a version.
Definition VersionInfo.h:47
int versionMajor() const
Returns the major version number.
Definition VersionInfo.h:65
int versionMinor() const
Returns the minor version number.
Definition VersionInfo.h:68
int versionPatch() const
Returns the patch version number.
Definition VersionInfo.h:71
Node of a DOM tree.
Definition XmlNode.h:51
XmlNode documentElement() const
Returns the document element.
Definition XmlNode.cc:565
bool null() const
True if the node is null.
Definition XmlNode.h:303
IPerformanceCounterService * setPerformanceCounterService(IPerformanceCounterService *service)
Sets the service used to manage internal processor counters.
String getCompilerId()
Character string used to identify the compiler used to compile Arccore.
IStackTraceService * setStackTraceService(IStackTraceService *service)
Sets the service used to obtain the call stack.
ISymbolizerService * setSymbolizerService(ISymbolizerService *service)
Sets the service to obtain information about source code symbols.
IOnlineDebuggerService * setOnlineDebuggerService(IOnlineDebuggerService *service)
Sets the service to be used for the online debug architecture.
double getMemoryUsed()
Memory used in bytes.
String getCurrentDateTime()
Current date and time in ISO 8601 format.
String getHostName()
Name of the machine running the process.
IProfilingService * getProfilingService()
Service used to obtain profiling information.
bool isFileReadable(const String &file_name)
Checks if the file file_name is accessible and readable.
IProfilingService * setProfilingService(IProfilingService *service)
Sets the service used to obtain profiling information.
IStackTraceService * getStackTraceService()
Service used to obtain the call stack.
ISymbolizerService * getSymbolizerService()
Service used to obtain information about source code symbols.
String getHomeDirectory()
Directory containing user documents.
IProcessorAffinityService * setProcessorAffinityService(IProcessorAffinityService *service)
Sets the service used for managing processor affinity.
IProcessorAffinityService * getProcessorAffinityService()
Service used for managing processor affinity.
IThreadImplementation * getThreadImplementationService()
Service used to manage threads.
IPerformanceCounterService * getPerformanceCounterService()
Service used to obtain internal processor counters.
IThreadImplementation * setThreadImplementationService(IThreadImplementation *service)
Sets the service used to manage threads.
String getEnvironmentVariable(const String &name)
Environment variable named name.
IOnlineDebuggerService * getOnlineDebuggerService()
Service used to set up an online debug architecture.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
void setGlobalDataInitialisationPolicy(eDataInitialisationPolicy init_policy)
Sets the initialization policy for variables.
Definition DataTypes.cc:158
@ SB_AllowNull
Allows the service to be absent.
bool arcaneIsCheck()
True if running in check mode.
Definition Misc.cc:66
eDataInitialisationPolicy
Possible data initialization policy.
Definition DataTypes.h:135
@ DIP_InitInitialWithNanResizeWithDefault
Initialization with NaN upon creation and default constructor thereafter.
Definition DataTypes.h:175
@ DIP_Legacy
Initialization in historical mode.
Definition DataTypes.h:166
@ DIP_None
No forced initialization.
Definition DataTypes.h:137
@ DIP_InitWithNan
Initialization with NaN (Not a Number).
Definition DataTypes.h:153
@ DIP_InitWithDefault
Initialization with the default constructor.
Definition DataTypes.h:144
std::int64_t Int64
Signed integer type of 64 bits.
eDataInitialisationPolicy getGlobalDataInitialisationPolicy()
Gets the initialization policy for variables.
Definition DataTypes.cc:164
Int32 Integer
Type representing an integer.
Collection< String > StringCollection
Collection of strings.
Definition UtilsTypes.h:506
Collection< Internal::IServiceFactory2 * > ServiceFactory2Collection
Collection of service factories.
List< String > StringList
Unicode string list.
Definition UtilsTypes.h:509
Collection< IModuleFactoryInfo * > ModuleFactoryInfoCollection
Collection of module factory information.
void arcaneSetCheck(bool v)
Activates or deactivates verification mode.
Definition Misc.cc:71
eItemKind
Mesh entity type.
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.