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