Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ArcaneLauncher.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/* ArcaneLauncher.cc (C) 2000-2025 */
9/* */
10/* Class managing the execution launch. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/launcher/ArcaneLauncher.h"
15
16#include "arcane/launcher/IDirectExecutionContext.h"
17#include "arcane/launcher/DirectSubDomainExecutionContext.h"
18#include "arcane/launcher/GeneralHelp.h"
19
20#include "arcane/utils/FatalErrorException.h"
21#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/JSONReader.h"
23#include "arcane/utils/Exception.h"
24#include "arcane/utils/ParameterList.h"
25#include "arcane/utils/Ref.h"
27#include "arcane/utils/internal/ParallelLoopOptionsProperties.h"
28#include "arcane/utils/internal/ApplicationInfoProperties.h"
29#include "arcane/core/internal/DotNetRuntimeInitialisationInfoProperties.h"
30#include "arcane/accelerator/core/internal/AcceleratorRuntimeInitialisationInfoProperties.h"
31
32#include "arccore/common/internal/Property.h"
33#include "arccore/common/internal/ParameterListPropertyReader.h"
34#include "arccore/common/internal/JSONPropertyReader.h"
35
36#include "arcane/impl/ArcaneMain.h"
37#include "arcane/impl/ArcaneSimpleExecutor.h"
38
39#include "arcane/core/IDirectSubDomainExecuteFunctor.h"
40
41#include <iomanip>
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46namespace Arcane
47{
48
49/*---------------------------------------------------------------------------*/
50/*---------------------------------------------------------------------------*/
51
52namespace
53{
54 bool global_has_init_done = false;
55 bool _checkInitCalled()
56 {
57 if (!global_has_init_done) {
58 std::cerr << "ArcaneLauncher::init() has to be called before";
59 return true;
60 }
61 return false;
62 }
63
64} // namespace
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69class DirectExecutionContextImpl
71{
72 public:
73
74 explicit DirectExecutionContextImpl(ArcaneSimpleExecutor* simple_exec)
75 : m_simple_exec(simple_exec)
76 {}
77
78 public:
79
84 ISubDomain* createSequentialSubDomain(const String& case_file_name) override
85 {
86 return m_simple_exec->createSubDomain(case_file_name);
87 }
88 ISubDomain* subDomain() const { return nullptr; }
89
90 private:
91
92 ArcaneSimpleExecutor* m_simple_exec;
93};
94
95/*---------------------------------------------------------------------------*/
96/*---------------------------------------------------------------------------*/
97
98void _checkReadConfigFile(StringView config_file_name)
99{
100 // TODO: in parallel, only one PE should perform the reading.
101 if (config_file_name.empty())
102 return;
103 std::cout << "TRY_READING_CONFIG " << config_file_name << "\n";
104 if (!platform::isFileReadable(config_file_name))
105 return;
107 bool is_bad = platform::readAllFile(config_file_name, false, bytes);
108 if (is_bad)
109 return;
111 app_info.setRuntimeConfigFileContent(bytes);
112 JSONDocument jdoc;
113 jdoc.parse(bytes);
114 JSONValue config = jdoc.root().child("configuration");
115 if (config.null())
116 return;
117 std::cout << "READING CONFIG\n";
118 properties::readFromJSON<ApplicationInfo, ApplicationInfoProperties>(config, app_info);
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
125run()
126{
127 return ArcaneMain::run();
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
171{
172 String exe_full_path = platform::getExeFullPath();
173 String exe_dir = platform::getFileDirName(exe_full_path);
174 return exe_dir;
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
180class DirectCodeFunctor
181: public IFunctor
182{
183 public:
184
185 typedef std::function<int(IDirectExecutionContext*)> OldFunctorType;
186 typedef std::function<int(DirectExecutionContext&)> FunctorType;
187
188 public:
189
190 DirectCodeFunctor(ArcaneSimpleExecutor* x, FunctorType* ft)
191 : m_simple_executor(x)
192 , m_functor(ft)
193 {}
194 DirectCodeFunctor(ArcaneSimpleExecutor* x, OldFunctorType* ft)
195 : m_simple_executor(x)
196 , m_old_functor(ft)
197 {}
198 void executeFunctor() override
199 {
200 DirectExecutionContextImpl direct_context_impl(m_simple_executor);
201 if (m_functor) {
202 DirectExecutionContext direct_context(&direct_context_impl);
203 m_return_value = (*m_functor)(direct_context);
204 }
205 else if (m_old_functor)
206 m_return_value = (*m_old_functor)(&direct_context_impl);
207 }
208 int returnValue() const { return m_return_value; }
209
210 public:
211
212 ArcaneSimpleExecutor* m_simple_executor = nullptr;
213 OldFunctorType* m_old_functor = nullptr;
214 FunctorType* m_functor = nullptr;
215 int m_return_value = 0;
216};
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220// Obsolete
222runDirect(std::function<int(IDirectExecutionContext* c)> func)
223{
224 if (_checkInitCalled())
225 return (-1);
226 int final_return = 0;
227 {
228 ArcaneSimpleExecutor simple_exec;
229 int r = simple_exec.initialize();
230 if (r != 0)
231 return r;
232 // Encapsulates the code in a functor that will handle exceptions. Without
233 // this, in case of an exception and if the calling code does nothing, we
234 // will have a call to std::terminate
235 DirectCodeFunctor direct_functor(&simple_exec, &func);
236 simple_exec.runCode(&direct_functor);
237 final_return = direct_functor.returnValue();
238 }
239 return final_return;
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
246run(std::function<int(DirectExecutionContext&)> func)
247{
248 if (_checkInitCalled())
249 return (-1);
250
251 int final_return = 0;
252 {
253 ArcaneSimpleExecutor simple_exec;
254 int r = simple_exec.initialize();
255 if (r != 0)
256 return r;
257 // Encapsulates the code in a functor that will handle exceptions. Without
258 // this, in case of an exception and if the calling code does nothing, we
259 // will have a call to std::terminate
260 DirectCodeFunctor direct_functor(&simple_exec, &func);
261 simple_exec.runCode(&direct_functor);
262 final_return = direct_functor.returnValue();
263 }
264 return final_return;
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270class ArcaneLauncherDirectExecuteFunctor
272{
273 public:
274
275 ArcaneLauncherDirectExecuteFunctor(std::function<int(DirectSubDomainExecutionContext&)> func)
276 : m_function(func)
277 {}
278
279 public:
280
281 int execute() override
282 {
283 if (!m_sub_domain)
284 ARCANE_FATAL("Can not execute 'IDirectSubDomainExecuteFunctor' without sub domain");
285 DirectSubDomainExecutionContext direct_context(m_sub_domain);
286 return m_function(direct_context);
287 }
288 void setSubDomain(ISubDomain* sd) override { m_sub_domain = sd; }
289
290 private:
291
292 std::function<int(DirectSubDomainExecutionContext&)> m_function;
293
294 public:
295
296 ISubDomain* m_sub_domain = nullptr;
297};
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
303run(std::function<int(DirectSubDomainExecutionContext&)> func)
304{
305 if (_checkInitCalled())
306 return (-1);
307
308 ArcaneLauncherDirectExecuteFunctor direct_exec(func);
309 // In direct execution, by default there is no configuration file for the
310 // code. If the user has not provided a configuration file, we set it to
311 // the null string.
313 // The default is the empty string. The null string explicitly indicates
314 // that no configuration file is desired
315 if (config_file.empty())
317 int r = ArcaneMain::_internalRun(&direct_exec);
318 return r;
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
323
324namespace
325{
326 class MyVisitor
328 {
329 public:
330
331 void visit(const properties::IPropertySetting* s) override
332 {
333 if (!s->commandLineArgument().null()) {
334 std::cout << "ARG:" << std::setw(30) << s->commandLineArgument()
335 << " " << s->description() << "\n";
336 }
337 }
338 };
339
340 void
341 _listPropertySettings()
342 {
343 using namespace Arcane::properties;
344 MyVisitor my_visitor;
345 visitAllRegisteredProperties(&my_visitor);
346 }
347} // namespace
348
350init(const CommandLineArguments& args)
351{
352 try {
353 if (global_has_init_done)
354 ARCANE_FATAL("ArcaneLauncher::init() has already been called");
355 global_has_init_done = true;
356 auto& application_info = applicationInfo();
357 application_info.setCommandLineArguments(args);
358 bool do_list = false;
359 if (do_list)
360 _listPropertySettings();
362 String runtime_config_file_name = cargs.getParameter("RuntimeConfigFile");
363 if (!runtime_config_file_name.empty())
364 _checkReadConfigFile(runtime_config_file_name);
365 properties::readFromParameterList<ApplicationInfo, ApplicationInfoProperties>(args.parameters(), application_info);
367 properties::readFromParameterList<DotNetRuntimeInitialisationInfo, DotNetRuntimeInitialisationInfoProperties>(args.parameters(), dotnet_info);
369 properties::readFromParameterList<AcceleratorRuntimeInitialisationInfo, Accelerator::AcceleratorRuntimeInitialisationInfoProperties>(args.parameters(), accelerator_info);
370 ParallelLoopOptions loop_options;
371 properties::readFromParameterList<ParallelLoopOptions, ParallelLoopOptionsProperties>(args.parameters(), loop_options);
373 }
374 catch (const Exception& ex) {
375 cerr << ex << '\n';
376 cerr << "** (ArcaneLauncher) Can't continue with the execution.\n";
377 throw;
378 }
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
386{
387 return global_has_init_done;
388}
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
398
399/*---------------------------------------------------------------------------*/
400/*---------------------------------------------------------------------------*/
401
402void ArcaneLauncher::
403_initStandalone()
404{
405 if (!global_has_init_done)
406 ARCANE_FATAL("ArcaneLauncher::init() has to be called before");
407 // This is necessary to potentially dynamically load the runtime associated
408 // with accelerators
409 ArcaneMain::_initRuntimes();
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
417{
418 _initStandalone();
419 return {};
420}
421
422/*---------------------------------------------------------------------------*/
423/*---------------------------------------------------------------------------*/
424
425StandaloneSubDomain ArcaneLauncher::
426createStandaloneSubDomain(const String& case_file_name)
427{
428 _initStandalone();
429 StandaloneSubDomain s;
430 s._initUniqueInstance(case_file_name);
431 return s;
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
437void ArcaneLauncher::
438_notifyRemoveStandaloneSubDomain()
439{
440}
441
442/*---------------------------------------------------------------------------*/
443/*---------------------------------------------------------------------------*/
444
450
451/*---------------------------------------------------------------------------*/
452/*---------------------------------------------------------------------------*/
453
455printHelp()
456{
457 if (applicationInfo().commandLineArguments().needHelp()) {
458 GeneralHelp::printHelp();
459 return true;
460 }
461 return false;
462}
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467} // End namespace Arcane
468
469/*---------------------------------------------------------------------------*/
470/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Classes, Types, and macros for managing concurrency.
Information for constructing an instance of IApplication.
String configFileName() const
Name of the code configuration file.
void setConfigFileName(const String &name)
Sets the code configuration file.
Application information.
const CommandLineArguments & commandLineArguments() const
Command line arguments.
int execute() override
Executes the functor's operation.
void setSubDomain(ISubDomain *sd) override
Positions the associated subdomain. This method must be called before execute().
static StandaloneAcceleratorMng createStandaloneAcceleratorMng()
Creates a standalone implementation to manage accelerators.
static int run()
Entry point of the executable in Arcane.
static String getExeDirectory()
Full name of the directory where the executable is located.
static DotNetRuntimeInitialisationInfo & dotNetRuntimeInitialisationInfo()
Information for '.Net' runtime initialization.
static bool needHelp()
Requests help with the "--help" or "-h" option.
static void init(const CommandLineArguments &args)
Positions information from command-line arguments and initializes the launcher.
static ApplicationBuildInfo & applicationBuildInfo()
Application execution parameter information.
static StandaloneSubDomain createStandaloneSubDomain(const String &case_file_name)
Creates a standalone implementation to manage a subdomain.
static bool isInitialized()
Indicates if init() has already been called.
static bool printHelp()
Display of generic Arcane help.
static ApplicationInfo & applicationInfo()
Application information.
static AcceleratorRuntimeInitialisationInfo & acceleratorRuntimeInitialisationInfo()
Information for accelerator initialization.
static int runDirect(std::function< int(IDirectExecutionContext *)> func)
static void setDefaultMainFactory(IMainFactory *mf)
Positions the default factory for creating the different managers.
static ApplicationBuildInfo & defaultApplicationBuildInfo()
Information for accelerator initialization.
static AcceleratorRuntimeInitialisationInfo & defaultAcceleratorRuntimeInitialisationInfo()
Information for accelerator initialization.
static DotNetRuntimeInitialisationInfo & defaultDotNetRuntimeInitialisationInfo()
Information for .Net runtime initialization.
static int run()
Entry point of the executable in Arcane.
static ApplicationInfo & defaultApplicationInfo()
Default application info.
static void setDefaultMainFactory(IMainFactory *mf)
Sets the default factory.
Class for directly executing code without going through the time loop.
const ParameterList & parameters() const
List of parameters.
bool needHelp() const
Method to determine if the user requested help on the command line.
String getParameter(const String &param_name) const
Retrieves the parameter with name param_name.
void executeFunctor() override
Executes the associated method.
ISubDomain * createSequentialSubDomain(const String &case_file_name) override
Create a sequential sub-domain with the dataset file named case_file_name.
ISubDomain * createSequentialSubDomain() override
Create a sequential sub-domain without a dataset.
Direct execution context with subdomain creation.
Information for the initialization of the '.Net' runtime.
Implementation of the execution management class.
Interface of a functor to execute code directly after the creation of a subdomain without going throu...
Factory for Arcane classes.
Interface of the subdomain manager.
Definition ISubDomain.h:75
void parse(Span< const Byte > bytes)
Reads the file in UTF-8 format.
JSONValue child(StringView name) const
Child value with name name. Returns a null value if not found.
Execution options for a parallel loop in multi-threading.
Standalone implementation of 'IAcceleratorMng.h'.
View of a UTF-8 character string.
Definition StringView.h:44
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
static void setDefaultParallelLoopOptions(const ParallelLoopOptions &v)
Sets the default parallel loop execution options.
1D data vector with value semantics (STL style).
Property parameter interface.
Definition Property.h:118
virtual String description() const =0
Property description.
virtual String commandLineArgument() const =0
Command line argument name (null if none).
Property visitor interface.
Definition Property.h:190
String getFileDirName(const String &file_name)
Returns the directory name of a file.
bool isFileReadable(const String &file_name)
Checks if the file file_name is accessible and readable.
String getExeFullPath()
Returns the full name with the executable path.
bool readAllFile(StringView filename, bool is_binary, ByteArray &out_bytes)
Reads the content of a file and stores it in out_bytes.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --