Arcane  4.2.1.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
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() doit être appelé avant";
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: en parallèle, un seul PE doit effectuer la lecture.
101 if (config_file_name.empty())
102 return;
103 std::cout << "TENTATIVE DE LECTURE DE LA CONFIGURATION " << 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 << "LECTURE DE LA CONFIGURATION\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
135{
136 return ArcaneMain::defaultApplicationInfo();
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
144{
145 return ArcaneMain::defaultDotNetRuntimeInitialisationInfo();
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
153{
154 return ArcaneMain::defaultAcceleratorRuntimeInitialisationInfo();
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
162{
163 return ArcaneMain::defaultApplicationBuildInfo();
164}
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// Obsolète
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 // Encapsule le code dans un functor qui va gérer les
233 // exceptions. Sans cela, en cas d'exception et si le code
234 // appelant ne fait rien on aura un appel à 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 // Encapsule le code dans un functor qui va gérer les
258 // exceptions. Sans cela, en cas d'exception et si le code
259 // appelant ne fait rien on aura un appel à 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("Impossible d'exécuter 'IDirectSubDomainExecuteFunctor' sans sous-domaine");
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 // En exécution directe, par défaut il n'y a pas de fichier de configuration
310 // du code. Si l'utilisateur n'a pas positionné de fichier de configuration,
311 // alors on le positionne à la chaîne nulle.
313 // Le défaut est la chaîne vide. La chaîne nulle indique explicitement qu'on
314 // ne souhaite pas de fichier de configuration
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
327 : public properties::IPropertyVisitor
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() a déjà été appelé");
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) Impossible de continuer l'exécution.\n";
377 throw;
378 }
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
386{
387 return global_has_init_done;
388}
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
395{
396 ArcaneMain::setDefaultMainFactory(mf);
397}
398
399/*---------------------------------------------------------------------------*/
400/*---------------------------------------------------------------------------*/
401
402void ArcaneLauncher::
403_initStandalone()
404{
405 if (!global_has_init_done)
406 ARCANE_FATAL("ArcaneLauncher::init() doit être appelé avant");
407 // Ceci est nécessaire pour potentiellement charger dynamiquement le runtime associé
408 // aux accélérateurs
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, Span<const std::byte> file_content)
427{
428 _initStandalone();
429 StandaloneSubDomain s;
430 s._initUniqueInstance(case_file_name, file_content);
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 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:74
void parse(Span< const Byte > bytes)
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 --