Arcane  4.2.3.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
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-2026 */
9/* */
10/* Classe gérant le lancement de l'exécution. */
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#include "arcane/launcher/internal/ParamFile.h"
20
21#include "arcane/utils/FatalErrorException.h"
22#include "arcane/utils/PlatformUtils.h"
23#include "arcane/utils/JSONReader.h"
24#include "arcane/utils/Exception.h"
25#include "arcane/utils/ParameterList.h"
26#include "arcane/utils/Ref.h"
28#include "arcane/utils/internal/ParallelLoopOptionsProperties.h"
29#include "arcane/utils/internal/ApplicationInfoProperties.h"
30#include "arcane/core/internal/DotNetRuntimeInitialisationInfoProperties.h"
31#include "arcane/accelerator/core/internal/AcceleratorRuntimeInitialisationInfoProperties.h"
32
33#include "arccore/common/internal/Property.h"
34#include "arccore/common/internal/ParameterListPropertyReader.h"
35#include "arccore/common/internal/JSONPropertyReader.h"
36
37#include "arcane/impl/ArcaneMain.h"
38#include "arcane/impl/ArcaneSimpleExecutor.h"
39
40#include "arcane/core/IDirectSubDomainExecuteFunctor.h"
41
42#include <iomanip>
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47namespace Arcane
48{
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53namespace
54{
55 bool global_has_init_done = false;
56 bool _checkInitCalled()
57 {
58 if (!global_has_init_done) {
59 std::cerr << "ArcaneLauncher::init() doit être appelé avant";
60 return true;
61 }
62 return false;
63 }
64
65} // namespace
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
70class DirectExecutionContextImpl
72{
73 public:
74
75 explicit DirectExecutionContextImpl(ArcaneSimpleExecutor* simple_exec)
76 : m_simple_exec(simple_exec)
77 {}
78
79 public:
80
85 ISubDomain* createSequentialSubDomain(const String& case_file_name) override
86 {
87 return m_simple_exec->createSubDomain(case_file_name);
88 }
89 ISubDomain* subDomain() const { return nullptr; }
90
91 private:
92
93 ArcaneSimpleExecutor* m_simple_exec;
94};
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99void _checkReadConfigFile(StringView config_file_name)
100{
101 // TODO: en parallèle, un seul PE doit effectuer la lecture.
102 if (config_file_name.empty())
103 return;
104 std::cout << "TENTATIVE DE LECTURE DE LA CONFIGURATION " << config_file_name << "\n";
105 if (!platform::isFileReadable(config_file_name))
106 return;
108 bool is_bad = platform::readAllFile(config_file_name, false, bytes);
109 if (is_bad)
110 return;
112 app_info.setRuntimeConfigFileContent(bytes);
113 JSONDocument jdoc;
114 jdoc.parse(bytes);
115 JSONValue config = jdoc.root().child("configuration");
116 if (config.null())
117 return;
118 std::cout << "LECTURE DE LA CONFIGURATION\n";
119 properties::readFromJSON<ApplicationInfo, ApplicationInfoProperties>(config, app_info);
120}
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
126run()
127{
128 return ArcaneMain::run();
129}
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
136{
137 return ArcaneMain::defaultApplicationInfo();
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
145{
146 return ArcaneMain::defaultDotNetRuntimeInitialisationInfo();
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
154{
155 return ArcaneMain::defaultAcceleratorRuntimeInitialisationInfo();
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
163{
164 return ArcaneMain::defaultApplicationBuildInfo();
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
172{
173 String exe_full_path = platform::getExeFullPath();
174 String exe_dir = platform::getFileDirName(exe_full_path);
175 return exe_dir;
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
181class DirectCodeFunctor
182: public IFunctor
183{
184 public:
185
186 typedef std::function<int(IDirectExecutionContext*)> OldFunctorType;
187 typedef std::function<int(DirectExecutionContext&)> FunctorType;
188
189 public:
190
191 DirectCodeFunctor(ArcaneSimpleExecutor* x, FunctorType* ft)
192 : m_simple_executor(x)
193 , m_functor(ft)
194 {}
195 DirectCodeFunctor(ArcaneSimpleExecutor* x, OldFunctorType* ft)
196 : m_simple_executor(x)
197 , m_old_functor(ft)
198 {}
199 void executeFunctor() override
200 {
201 DirectExecutionContextImpl direct_context_impl(m_simple_executor);
202 if (m_functor) {
203 DirectExecutionContext direct_context(&direct_context_impl);
204 m_return_value = (*m_functor)(direct_context);
205 }
206 else if (m_old_functor)
207 m_return_value = (*m_old_functor)(&direct_context_impl);
208 }
209 int returnValue() const { return m_return_value; }
210
211 public:
212
213 ArcaneSimpleExecutor* m_simple_executor = nullptr;
214 OldFunctorType* m_old_functor = nullptr;
215 FunctorType* m_functor = nullptr;
216 int m_return_value = 0;
217};
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221// Obsolète
223runDirect(std::function<int(IDirectExecutionContext* c)> func)
224{
225 if (_checkInitCalled())
226 return (-1);
227 int final_return = 0;
228 {
229 ArcaneSimpleExecutor simple_exec;
230 int r = simple_exec.initialize();
231 if (r != 0)
232 return r;
233 // Encapsule le code dans un functor qui va gérer les
234 // exceptions. Sans cela, en cas d'exception et si le code
235 // appelant ne fait rien on aura un appel à std::terminate
236 DirectCodeFunctor direct_functor(&simple_exec, &func);
237 simple_exec.runCode(&direct_functor);
238 final_return = direct_functor.returnValue();
239 }
240 return final_return;
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
247run(std::function<int(DirectExecutionContext&)> func)
248{
249 if (_checkInitCalled())
250 return (-1);
251
252 int final_return = 0;
253 {
254 ArcaneSimpleExecutor simple_exec;
255 int r = simple_exec.initialize();
256 if (r != 0)
257 return r;
258 // Encapsule le code dans un functor qui va gérer les
259 // exceptions. Sans cela, en cas d'exception et si le code
260 // appelant ne fait rien on aura un appel à std::terminate
261 DirectCodeFunctor direct_functor(&simple_exec, &func);
262 simple_exec.runCode(&direct_functor);
263 final_return = direct_functor.returnValue();
264 }
265 return final_return;
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
271class ArcaneLauncherDirectExecuteFunctor
273{
274 public:
275
276 ArcaneLauncherDirectExecuteFunctor(std::function<int(DirectSubDomainExecutionContext&)> func)
277 : m_function(func)
278 {}
279
280 public:
281
282 int execute() override
283 {
284 if (!m_sub_domain)
285 ARCANE_FATAL("Impossible d'exécuter 'IDirectSubDomainExecuteFunctor' sans sous-domaine");
286 DirectSubDomainExecutionContext direct_context(m_sub_domain);
287 return m_function(direct_context);
288 }
289 void setSubDomain(ISubDomain* sd) override { m_sub_domain = sd; }
290
291 private:
292
293 std::function<int(DirectSubDomainExecutionContext&)> m_function;
294
295 public:
296
297 ISubDomain* m_sub_domain = nullptr;
298};
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
304run(std::function<int(DirectSubDomainExecutionContext&)> func)
305{
306 if (_checkInitCalled())
307 return (-1);
308
309 ArcaneLauncherDirectExecuteFunctor direct_exec(func);
310 // En exécution directe, par défaut il n'y a pas de fichier de configuration
311 // du code. Si l'utilisateur n'a pas positionné de fichier de configuration,
312 // alors on le positionne à la chaîne nulle.
314 // Le défaut est la chaîne vide. La chaîne nulle indique explicitement qu'on
315 // ne souhaite pas de fichier de configuration
316 if (config_file.empty())
318 int r = ArcaneMain::_internalRun(&direct_exec);
319 return r;
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
325namespace
326{
327 class MyVisitor
328 : public properties::IPropertyVisitor
329 {
330 public:
331
332 void visit(const properties::IPropertySetting* s) override
333 {
334 if (!s->commandLineArgument().null()) {
335 std::cout << "ARG:" << std::setw(30) << s->commandLineArgument()
336 << " " << s->description() << "\n";
337 }
338 }
339 };
340
341 void
342 _listPropertySettings()
343 {
344 using namespace Arcane::properties;
345 MyVisitor my_visitor;
346 visitAllRegisteredProperties(&my_visitor);
347 }
348} // namespace
349
351init(const CommandLineArguments& args)
352{
353 try {
354 if (global_has_init_done)
355 ARCANE_FATAL("ArcaneLauncher::init() a déjà été appelé");
356 global_has_init_done = true;
357 auto& application_info = applicationInfo();
358 application_info.setCommandLineArguments(args);
359 bool do_list = false;
360 if (do_list)
361 _listPropertySettings();
363 String runtime_config_file_name = cargs.getParameter("RuntimeConfigFile");
364 if (!runtime_config_file_name.empty())
365 _checkReadConfigFile(runtime_config_file_name);
366
367 String param_file_name = cargs.getParameter("ParamFile");
368 if (!param_file_name.empty()) {
369 String case_param_file_name = cargs.getParameter("Case");
370 ParamFile::editParams(param_file_name, case_param_file_name);
371 }
372
373
374 properties::readFromParameterList<ApplicationInfo, ApplicationInfoProperties>(args.parameters(), application_info);
376 properties::readFromParameterList<DotNetRuntimeInitialisationInfo, DotNetRuntimeInitialisationInfoProperties>(args.parameters(), dotnet_info);
378 properties::readFromParameterList<AcceleratorRuntimeInitialisationInfo, Accelerator::AcceleratorRuntimeInitialisationInfoProperties>(args.parameters(), accelerator_info);
379 ParallelLoopOptions loop_options;
380 properties::readFromParameterList<ParallelLoopOptions, ParallelLoopOptionsProperties>(args.parameters(), loop_options);
382 }
383 catch (const Exception& ex) {
384 cerr << ex << '\n';
385 cerr << "** (ArcaneLauncher) Impossible de continuer l'exécution.\n";
386 throw;
387 }
388}
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
395{
396 return global_has_init_done;
397}
398
399/*---------------------------------------------------------------------------*/
400/*---------------------------------------------------------------------------*/
401
404{
405 ArcaneMain::setDefaultMainFactory(mf);
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
411void ArcaneLauncher::
412_initStandalone()
413{
414 if (!global_has_init_done)
415 ARCANE_FATAL("ArcaneLauncher::init() doit être appelé avant");
416 // Ceci est nécessaire pour potentiellement charger dynamiquement le runtime associé
417 // aux accélérateurs
418 ArcaneMain::_initRuntimes();
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
426{
427 _initStandalone();
428 return {};
429}
430
431/*---------------------------------------------------------------------------*/
432/*---------------------------------------------------------------------------*/
433
434StandaloneSubDomain ArcaneLauncher::
435createStandaloneSubDomain(const String& case_file_name, Span<const std::byte> file_content)
436{
437 _initStandalone();
438 StandaloneSubDomain s;
439 s._initUniqueInstance(case_file_name, file_content);
440 return s;
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
446void ArcaneLauncher::
447_notifyRemoveStandaloneSubDomain()
448{
449}
450
451/*---------------------------------------------------------------------------*/
452/*---------------------------------------------------------------------------*/
453
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
464printHelp()
465{
466 if (applicationInfo().commandLineArguments().needHelp()) {
467 GeneralHelp::printHelp();
468 return true;
469 }
470 return false;
471}
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
476} // End namespace Arcane
477
478/*---------------------------------------------------------------------------*/
479/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classes, Types et macros pour gérer la concurrence.
Informations pour construire une instance de IApplication.
String configFileName() const
Nom du fichier de configuration du code.
void setConfigFileName(const String &name)
Positionne le fichier de configuration du code.
Informations sur une application.
const CommandLineArguments & commandLineArguments() const
Arguments de la ligne de commande.
int execute() override
Exécute l'opération du fonctor.
void setSubDomain(ISubDomain *sd) override
Positionne le sous-domaine associé. Cette méthode doit être appelée avant execute().
static StandaloneAcceleratorMng createStandaloneAcceleratorMng()
Créé une implémentation autonome pour gérer les accélérateurs.
static int run()
Point d'entrée de l'exécutable dans Arcane.
static String getExeDirectory()
Nom complet du répertoire où se trouve l'exécutable.
static DotNetRuntimeInitialisationInfo & dotNetRuntimeInitialisationInfo()
Informations pour l'initialisation du runtime '.Net'.
static bool needHelp()
Demande d'aide avec l'option "--help" ou "-h".
static void init(const CommandLineArguments &args)
Positionne les informations à partir des arguments de la ligne de commande et initialise le lanceur.
static ApplicationBuildInfo & applicationBuildInfo()
Informations sur les paramêtre d'exécutions de l'application.
static StandaloneSubDomain createStandaloneSubDomain(const String &case_file_name, Span< const std::byte > file_content={})
Créé une implémentation autonome pour gérer un sous-domaine.
static bool isInitialized()
Indique si init() a déjà été appelé.
static bool printHelp()
Affichage de l'aide générique Arcane.
static ApplicationInfo & applicationInfo()
Informations sur l'application.
static AcceleratorRuntimeInitialisationInfo & acceleratorRuntimeInitialisationInfo()
Informations pour l'initialisation des accélerateurs.
static int runDirect(std::function< int(IDirectExecutionContext *)> func)
static void setDefaultMainFactory(IMainFactory *mf)
Positionne la fabrique par défaut pour créer les différents gestionnaires.
const ParameterList & parameters() const
Liste des paramètres.
bool needHelp() const
Méthode permettant de savoir si l'utilisateur a demandé de l'aide dans la ligne de commande.
String getParameter(const String &param_name) const
Récupère le paramètre de nom param_name.
void executeFunctor() override
Exécute la méthode associé
ISubDomain * createSequentialSubDomain(const String &case_file_name) override
Créé un sous-domaine en séquentiel avec le fichier de jeu de données ayant pour nom case_file_name.
ISubDomain * createSequentialSubDomain() override
Créé un sous-domaine en séquentiel sans jeu de données.
Contexte d'exécution directe.
Contexte d'exécution directe avec création d'un sous-domaine.
Informations pour l'initialisation du runtime '.Net'.
Classe de base d'une exception.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:77
void parse(Span< const Byte > bytes, Int16 flags=ParseNoFlags)
Lit le fichier au format UTF-8.
JSONValue child(StringView name) const
Valeur fille de nom name. Retourne une valeur nulle si non trouvé.
Options d'exécution d'une boucle parallèle en multi-thread.
Vue d'un tableau d'éléments de type T.
Definition Span.h:633
Implémentation autonome de 'IAcceleratorMng.h'.
Vue sur une chaîne de caractères UTF-8.
Definition StringView.h:47
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "").
Definition String.cc:316
static void setDefaultParallelLoopOptions(const ParallelLoopOptions &v)
Positionne les valeurs par défaut d'exécution d'une boucle parallèle.
Vecteur 1D de données avec sémantique par valeur (style STL).
String getFileDirName(const String &file_name)
Retourne le nom du répertoire d'un fichier.
bool isFileReadable(const String &file_name)
Vérifie que le fichier file_name est accessible et lisible.
String getExeFullPath()
Retourne le nom complet avec le chemin de l'exécutable.
bool readAllFile(StringView filename, bool is_binary, ByteArray &out_bytes)
Lit le contenu d'un fichier et le conserve dans out_bytes.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --