Arcane  v3.16.0.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/Property.h"
21#include "arcane/utils/FatalErrorException.h"
22#include "arcane/utils/JSONPropertyReader.h"
23#include "arcane/utils/ParameterListPropertyReader.h"
24#include "arcane/utils/PlatformUtils.h"
25#include "arcane/utils/JSONReader.h"
26#include "arcane/utils/Exception.h"
27#include "arcane/utils/ParameterList.h"
28#include "arcane/utils/Ref.h"
30#include "arcane/utils/internal/ParallelLoopOptionsProperties.h"
31#include "arcane/utils/internal/ApplicationInfoProperties.h"
32
33#include "arcane/impl/ArcaneMain.h"
34#include "arcane/impl/ArcaneSimpleExecutor.h"
35
36#include "arcane/IDirectSubDomainExecuteFunctor.h"
37
38#include <iomanip>
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43namespace Arcane
44{
45
46namespace
47{
48bool global_has_init_done = false;
49bool _checkInitCalled()
50{
51 if (!global_has_init_done){
52 std::cerr << "ArcaneLauncher::init() has to be called before";
53 return true;
54 }
55 return false;
56}
57bool global_has_standalone_sub_domain = false;
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63class DirectExecutionContextImpl
65{
66 public:
67 explicit DirectExecutionContextImpl(ArcaneSimpleExecutor* simple_exec)
68 : m_simple_exec(simple_exec) {}
69
70 public:
75 ISubDomain* createSequentialSubDomain(const String& case_file_name) override
76 {
77 return m_simple_exec->createSubDomain(case_file_name);
78 }
79 ISubDomain* subDomain() const { return nullptr; }
80 private:
81 ArcaneSimpleExecutor* m_simple_exec;
82};
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87void
88_checkReadConfigFile(StringView config_file_name)
89{
90 // TODO: en parallèle, ne faire la lecture que par un seul PE.
91 if (config_file_name.empty())
92 return;
93 std::cout << "TRY_READING_CONFIG " << config_file_name << "\n";
94 if (!platform::isFileReadable(config_file_name))
95 return;
97 bool is_bad = platform::readAllFile(config_file_name,false,bytes);
98 if (is_bad)
99 return;
101 app_info.setRuntimeConfigFileContent(bytes);
102 JSONDocument jdoc;
103 jdoc.parse(bytes);
104 JSONValue config = jdoc.root().child("configuration");
105 if (config.null())
106 return;
107 std::cout << "READING CONFIG\n";
108 properties::readFromJSON<ApplicationInfo,ApplicationInfoProperties>(config,app_info);
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
115run()
116{
117 return ArcaneMain::run();
118}
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122
125{
126 return ArcaneMain::defaultApplicationInfo();
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
134{
135 return ArcaneMain::defaultDotNetRuntimeInitialisationInfo();
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
143{
144 return ArcaneMain::defaultAcceleratorRuntimeInitialisationInfo();
145}
146
147/*---------------------------------------------------------------------------*/
148/*---------------------------------------------------------------------------*/
149
152{
153 return ArcaneMain::defaultApplicationBuildInfo();
154}
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
161{
162 String exe_full_path = platform::getExeFullPath();
163 String exe_dir = platform::getFileDirName(exe_full_path);
164 return exe_dir;
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170class DirectCodeFunctor
171: public IFunctor
172{
173 public:
174 typedef std::function<int(IDirectExecutionContext*)> OldFunctorType;
175 typedef std::function<int(DirectExecutionContext&)> FunctorType;
176 public:
177 DirectCodeFunctor(ArcaneSimpleExecutor* x,FunctorType* ft)
178 : m_simple_executor(x), m_functor(ft){}
179 DirectCodeFunctor(ArcaneSimpleExecutor* x,OldFunctorType* ft)
180 : m_simple_executor(x), m_old_functor(ft){}
181 void executeFunctor() override
182 {
183 DirectExecutionContextImpl direct_context_impl(m_simple_executor);
184 if (m_functor){
185 DirectExecutionContext direct_context(&direct_context_impl);
186 m_return_value = (*m_functor)(direct_context);
187 }
188 else if (m_old_functor)
189 m_return_value = (*m_old_functor)(&direct_context_impl);
190 }
191 int returnValue() const { return m_return_value; }
192 public:
193 ArcaneSimpleExecutor* m_simple_executor = nullptr;
194 OldFunctorType* m_old_functor = nullptr;
195 FunctorType* m_functor = nullptr;
196 int m_return_value = 0;
197};
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201// Obsolète
203runDirect(std::function<int(IDirectExecutionContext* c)> func)
204{
205 if (_checkInitCalled())
206 return (-1);
207 int final_return = 0;
208 {
209 ArcaneSimpleExecutor simple_exec;
210 int r = simple_exec.initialize();
211 if (r!=0)
212 return r;
213 // Encapsule le code dans un functor qui va gérer les
214 // exceptions. Sans cela, en cas d'exception et si le code
215 // appelant ne fait rien on aura un appel à std::terminate
216 DirectCodeFunctor direct_functor(&simple_exec,&func);
217 simple_exec.runCode(&direct_functor);
218 final_return = direct_functor.returnValue();
219 }
220 return final_return;
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
227run(std::function<int(DirectExecutionContext&)> func)
228{
229 if (_checkInitCalled())
230 return (-1);
231
232 int final_return = 0;
233 {
234 ArcaneSimpleExecutor simple_exec;
235 int r = simple_exec.initialize();
236 if (r!=0)
237 return r;
238 // Encapsule le code dans un functor qui va gérer les
239 // exceptions. Sans cela, en cas d'exception et si le code
240 // appelant ne fait rien on aura un appel à std::terminate
241 DirectCodeFunctor direct_functor(&simple_exec,&func);
242 simple_exec.runCode(&direct_functor);
243 final_return = direct_functor.returnValue();
244 }
245 return final_return;
246}
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251class ArcaneLauncherDirectExecuteFunctor
253{
254 public:
255 ArcaneLauncherDirectExecuteFunctor(std::function<int(DirectSubDomainExecutionContext&)> func)
256 : m_function(func){}
257 public:
258 int execute() override
259 {
260 if (!m_sub_domain)
261 ARCANE_FATAL("Can not execute 'IDirectSubDomainExecuteFunctor' without sub domain");
262 DirectSubDomainExecutionContext direct_context(m_sub_domain);
263 return m_function(direct_context);
264 }
265 void setSubDomain(ISubDomain* sd) override { m_sub_domain = sd; }
266 private:
267 std::function<int(DirectSubDomainExecutionContext&)> m_function;
268 public:
269 ISubDomain* m_sub_domain = nullptr;
270};
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
276run(std::function<int(DirectSubDomainExecutionContext&)> func)
277{
278 if (_checkInitCalled())
279 return (-1);
280
281 ArcaneLauncherDirectExecuteFunctor direct_exec(func);
282 // En exécution directe, par défaut il n'y a pas de fichier de configuration
283 // du code. Si l'utilisateur n'a pas positionné de fichier de configuration,
284 // alors on le positionne à la chaîne nulle.
286 // Le défaut est la chaîne vide. La chaîne nulle indique explicitement qu'on
287 // ne souhaite pas de fichier de configuration
288 if (config_file.empty())
290 int r = ArcaneMain::_internalRun(&direct_exec);
291 return r;
292}
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297namespace
298{
299class MyVisitor
301{
302 public:
303 void visit(const properties::IPropertySetting* s) override
304 {
305 if (!s->commandLineArgument().null()){
306 std::cout << "ARG:" << std::setw(30) << s->commandLineArgument()
307 << " " << s->description() << "\n";
308 }
309 }
310};
311
312void
313_listPropertySettings()
314{
315 using namespace Arcane::properties;
316 MyVisitor my_visitor;
317 visitAllRegisteredProperties(&my_visitor);
318}
319}
320
322init(const CommandLineArguments& args)
323{
324 try{
325 if (global_has_init_done)
326 ARCANE_FATAL("ArcaneLauncher::init() has already been called");
327 global_has_init_done = true;
328 auto& application_info = applicationInfo();
329 application_info.setCommandLineArguments(args);
330 bool do_list = false;
331 if (do_list)
332 _listPropertySettings();
334 String runtime_config_file_name = cargs.getParameter("RuntimeConfigFile");
335 if (!runtime_config_file_name.empty())
336 _checkReadConfigFile(runtime_config_file_name);
337 properties::readFromParameterList<ApplicationInfo,ApplicationInfoProperties>(args.parameters(),application_info);
339 properties::readFromParameterList(args.parameters(),dotnet_info);
341 properties::readFromParameterList(args.parameters(),accelerator_info);
342 ParallelLoopOptions loop_options;
343 properties::readFromParameterList<ParallelLoopOptions,ParallelLoopOptionsProperties>(args.parameters(),loop_options);
345 }
346 catch(const Exception& ex){
347 cerr << ex << '\n';
348 cerr << "** (ArcaneLauncher) Can't continue with the execution.\n";
349 throw;
350 }
351}
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
355
358{
359 return global_has_init_done;
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
367{
368 ArcaneMain::setDefaultMainFactory(mf);
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
374void ArcaneLauncher::
375_initStandalone()
376{
377 if (!global_has_init_done)
378 ARCANE_FATAL("ArcaneLauncher::init() has to be called before");
379 // Cela est nécessaire pour éventuellement charger dynamiquement le runtime
380 // associé aux accélérateurs
381 ArcaneMain::_initRuntimes();
382}
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
389{
390 _initStandalone();
391 return {};
392}
393
394/*---------------------------------------------------------------------------*/
395/*---------------------------------------------------------------------------*/
396
397StandaloneSubDomain ArcaneLauncher::
398createStandaloneSubDomain(const String& case_file_name)
399{
400 if (global_has_standalone_sub_domain)
401 ARCANE_FATAL("ArcaneLauncher::createStandaloneSubDomain() should only be called once");
402 _initStandalone();
403 StandaloneSubDomain s;
404 s._initUniqueInstance(case_file_name);
405 global_has_standalone_sub_domain = true;
406 return s;
407}
408
409/*---------------------------------------------------------------------------*/
410/*---------------------------------------------------------------------------*/
411
412void ArcaneLauncher::
413_notifyRemoveStandaloneSubDomain()
414{
415 global_has_standalone_sub_domain = false;
416}
417
418/*---------------------------------------------------------------------------*/
419/*---------------------------------------------------------------------------*/
420
426
427/*---------------------------------------------------------------------------*/
428/*---------------------------------------------------------------------------*/
429
431printHelp()
432{
433 if (applicationInfo().commandLineArguments().needHelp()) {
434 GeneralHelp::printHelp();
435 return true;
436 }
437 return false;
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
443} // End namespace Arcane
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
#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.
Arguments de la ligne de commande.
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 null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:315
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).
Interface d'un paramètre de propriété.
Definition Property.h:115
virtual String description() const =0
Description de la propriété
virtual String commandLineArgument() const =0
Nom de l'argument de la ligne de commande (nul si aucun)
Interface d'un visiteur sur une propriété.
Definition Property.h:180
ARCCORE_BASE_EXPORT bool isFileReadable(const String &file_name)
Vérifie que le fichier file_name est accessible et lisible.
ARCCORE_BASE_EXPORT String getFileDirName(const String &file_name)
Retourne le nom du répertoire d'un fichier.
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 -*-