Arcane  v4.1.2.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-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ArcaneLauncher.cc (C) 2000-2025 */
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/IDirectSubDomainExecuteFunctor.h"
40
41#include <iomanip>
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46namespace Arcane
47{
48
49namespace
50{
51bool global_has_init_done = false;
52bool _checkInitCalled()
53{
54 if (!global_has_init_done){
55 std::cerr << "ArcaneLauncher::init() has to be called before";
56 return true;
57 }
58 return false;
59}
60
61}
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66class DirectExecutionContextImpl
68{
69 public:
70 explicit DirectExecutionContextImpl(ArcaneSimpleExecutor* simple_exec)
71 : m_simple_exec(simple_exec) {}
72
73 public:
78 ISubDomain* createSequentialSubDomain(const String& case_file_name) override
79 {
80 return m_simple_exec->createSubDomain(case_file_name);
81 }
82 ISubDomain* subDomain() const { return nullptr; }
83 private:
84 ArcaneSimpleExecutor* m_simple_exec;
85};
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
89
90void
91_checkReadConfigFile(StringView config_file_name)
92{
93 // TODO: en parallèle, ne faire la lecture que par un seul PE.
94 if (config_file_name.empty())
95 return;
96 std::cout << "TRY_READING_CONFIG " << config_file_name << "\n";
97 if (!platform::isFileReadable(config_file_name))
98 return;
100 bool is_bad = platform::readAllFile(config_file_name,false,bytes);
101 if (is_bad)
102 return;
104 app_info.setRuntimeConfigFileContent(bytes);
105 JSONDocument jdoc;
106 jdoc.parse(bytes);
107 JSONValue config = jdoc.root().child("configuration");
108 if (config.null())
109 return;
110 std::cout << "READING CONFIG\n";
111 properties::readFromJSON<ApplicationInfo,ApplicationInfoProperties>(config,app_info);
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
118run()
119{
120 return ArcaneMain::run();
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
128{
129 return ArcaneMain::defaultApplicationInfo();
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
137{
138 return ArcaneMain::defaultDotNetRuntimeInitialisationInfo();
139}
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
146{
147 return ArcaneMain::defaultAcceleratorRuntimeInitialisationInfo();
148}
149
150/*---------------------------------------------------------------------------*/
151/*---------------------------------------------------------------------------*/
152
155{
156 return ArcaneMain::defaultApplicationBuildInfo();
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
164{
165 String exe_full_path = platform::getExeFullPath();
166 String exe_dir = platform::getFileDirName(exe_full_path);
167 return exe_dir;
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173class DirectCodeFunctor
174: public IFunctor
175{
176 public:
177 typedef std::function<int(IDirectExecutionContext*)> OldFunctorType;
178 typedef std::function<int(DirectExecutionContext&)> FunctorType;
179 public:
180 DirectCodeFunctor(ArcaneSimpleExecutor* x,FunctorType* ft)
181 : m_simple_executor(x), m_functor(ft){}
182 DirectCodeFunctor(ArcaneSimpleExecutor* x,OldFunctorType* ft)
183 : m_simple_executor(x), m_old_functor(ft){}
184 void executeFunctor() override
185 {
186 DirectExecutionContextImpl direct_context_impl(m_simple_executor);
187 if (m_functor){
188 DirectExecutionContext direct_context(&direct_context_impl);
189 m_return_value = (*m_functor)(direct_context);
190 }
191 else if (m_old_functor)
192 m_return_value = (*m_old_functor)(&direct_context_impl);
193 }
194 int returnValue() const { return m_return_value; }
195 public:
196 ArcaneSimpleExecutor* m_simple_executor = nullptr;
197 OldFunctorType* m_old_functor = nullptr;
198 FunctorType* m_functor = nullptr;
199 int m_return_value = 0;
200};
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204// Obsolète
206runDirect(std::function<int(IDirectExecutionContext* c)> func)
207{
208 if (_checkInitCalled())
209 return (-1);
210 int final_return = 0;
211 {
212 ArcaneSimpleExecutor simple_exec;
213 int r = simple_exec.initialize();
214 if (r!=0)
215 return r;
216 // Encapsule le code dans un functor qui va gérer les
217 // exceptions. Sans cela, en cas d'exception et si le code
218 // appelant ne fait rien on aura un appel à std::terminate
219 DirectCodeFunctor direct_functor(&simple_exec,&func);
220 simple_exec.runCode(&direct_functor);
221 final_return = direct_functor.returnValue();
222 }
223 return final_return;
224}
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
230run(std::function<int(DirectExecutionContext&)> func)
231{
232 if (_checkInitCalled())
233 return (-1);
234
235 int final_return = 0;
236 {
237 ArcaneSimpleExecutor simple_exec;
238 int r = simple_exec.initialize();
239 if (r!=0)
240 return r;
241 // Encapsule le code dans un functor qui va gérer les
242 // exceptions. Sans cela, en cas d'exception et si le code
243 // appelant ne fait rien on aura un appel à std::terminate
244 DirectCodeFunctor direct_functor(&simple_exec,&func);
245 simple_exec.runCode(&direct_functor);
246 final_return = direct_functor.returnValue();
247 }
248 return final_return;
249}
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253
254class ArcaneLauncherDirectExecuteFunctor
256{
257 public:
258 ArcaneLauncherDirectExecuteFunctor(std::function<int(DirectSubDomainExecutionContext&)> func)
259 : m_function(func){}
260 public:
261 int execute() override
262 {
263 if (!m_sub_domain)
264 ARCANE_FATAL("Can not execute 'IDirectSubDomainExecuteFunctor' without sub domain");
265 DirectSubDomainExecutionContext direct_context(m_sub_domain);
266 return m_function(direct_context);
267 }
268 void setSubDomain(ISubDomain* sd) override { m_sub_domain = sd; }
269 private:
270 std::function<int(DirectSubDomainExecutionContext&)> m_function;
271 public:
272 ISubDomain* m_sub_domain = nullptr;
273};
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
279run(std::function<int(DirectSubDomainExecutionContext&)> func)
280{
281 if (_checkInitCalled())
282 return (-1);
283
284 ArcaneLauncherDirectExecuteFunctor direct_exec(func);
285 // En exécution directe, par défaut il n'y a pas de fichier de configuration
286 // du code. Si l'utilisateur n'a pas positionné de fichier de configuration,
287 // alors on le positionne à la chaîne nulle.
289 // Le défaut est la chaîne vide. La chaîne nulle indique explicitement qu'on
290 // ne souhaite pas de fichier de configuration
291 if (config_file.empty())
293 int r = ArcaneMain::_internalRun(&direct_exec);
294 return r;
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300namespace
301{
302class MyVisitor
303: public properties::IPropertyVisitor
304{
305 public:
306 void visit(const properties::IPropertySetting* s) override
307 {
308 if (!s->commandLineArgument().null()){
309 std::cout << "ARG:" << std::setw(30) << s->commandLineArgument()
310 << " " << s->description() << "\n";
311 }
312 }
313};
314
315void
316_listPropertySettings()
317{
318 using namespace Arcane::properties;
319 MyVisitor my_visitor;
320 visitAllRegisteredProperties(&my_visitor);
321}
322}
323
325init(const CommandLineArguments& args)
326{
327 try{
328 if (global_has_init_done)
329 ARCANE_FATAL("ArcaneLauncher::init() has already been called");
330 global_has_init_done = true;
331 auto& application_info = applicationInfo();
332 application_info.setCommandLineArguments(args);
333 bool do_list = false;
334 if (do_list)
335 _listPropertySettings();
337 String runtime_config_file_name = cargs.getParameter("RuntimeConfigFile");
338 if (!runtime_config_file_name.empty())
339 _checkReadConfigFile(runtime_config_file_name);
340 properties::readFromParameterList<ApplicationInfo,ApplicationInfoProperties>(args.parameters(),application_info);
342 properties::readFromParameterList< DotNetRuntimeInitialisationInfo, DotNetRuntimeInitialisationInfoProperties>(args.parameters(),dotnet_info);
344 properties::readFromParameterList<AcceleratorRuntimeInitialisationInfo, Accelerator::AcceleratorRuntimeInitialisationInfoProperties>(args.parameters(), accelerator_info);
345 ParallelLoopOptions loop_options;
346 properties::readFromParameterList<ParallelLoopOptions,ParallelLoopOptionsProperties>(args.parameters(),loop_options);
348 }
349 catch(const Exception& ex){
350 cerr << ex << '\n';
351 cerr << "** (ArcaneLauncher) Can't continue with the execution.\n";
352 throw;
353 }
354}
355
356/*---------------------------------------------------------------------------*/
357/*---------------------------------------------------------------------------*/
358
361{
362 return global_has_init_done;
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
370{
371 ArcaneMain::setDefaultMainFactory(mf);
372}
373
374/*---------------------------------------------------------------------------*/
375/*---------------------------------------------------------------------------*/
376
377void ArcaneLauncher::
378_initStandalone()
379{
380 if (!global_has_init_done)
381 ARCANE_FATAL("ArcaneLauncher::init() has to be called before");
382 // Cela est nécessaire pour éventuellement charger dynamiquement le runtime
383 // associé aux accélérateurs
384 ArcaneMain::_initRuntimes();
385}
386
387/*---------------------------------------------------------------------------*/
388/*---------------------------------------------------------------------------*/
389
392{
393 _initStandalone();
394 return {};
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400StandaloneSubDomain ArcaneLauncher::
401createStandaloneSubDomain(const String& case_file_name)
402{
403 _initStandalone();
404 StandaloneSubDomain s;
405 s._initUniqueInstance(case_file_name);
406 return s;
407}
408
409/*---------------------------------------------------------------------------*/
410/*---------------------------------------------------------------------------*/
411
412void ArcaneLauncher::
413_notifyRemoveStandaloneSubDomain()
414{
415}
416
417/*---------------------------------------------------------------------------*/
418/*---------------------------------------------------------------------------*/
419
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
430printHelp()
431{
432 if (applicationInfo().commandLineArguments().needHelp()) {
433 GeneralHelp::printHelp();
434 return true;
435 }
436 return false;
437}
438
439/*---------------------------------------------------------------------------*/
440/*---------------------------------------------------------------------------*/
441
442} // End namespace Arcane
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
#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)
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.
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 -*-