Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcaneSession.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* ArcaneSession.cc (C) 2000-2020 */
9/* */
10/* Implémentation par défaut d'une Session. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/ArcaneSession.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/Collection.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/StringBuilder.h"
20
21#include "arcane/IParallelMng.h"
22#include "arcane/IParallelSuperMng.h"
23#include "arcane/IParallelReplication.h"
24#include "arcane/Directory.h"
25#include "arcane/IXmlDocumentHolder.h"
26#include "arcane/ISubDomain.h"
27#include "arcane/ITimeLoopMng.h"
28#include "arcane/IApplication.h"
29#include "arcane/IRessourceMng.h"
30#include "arcane/XmlNode.h"
31#include "arcane/CommonVariables.h"
32#include "arcane/IIOMng.h"
33#include "arcane/ApplicationBuildInfo.h"
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane
39{
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44ArcaneSession::
45ArcaneSession(IApplication* application)
46: Session(application)
47, m_result_doc(0)
48, m_case_name("output")
49{
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55ArcaneSession::
56~ArcaneSession()
57{
58 delete m_result_doc;
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64void ArcaneSession::
65build()
66{
67 Session::build();
68
69 // Si une valeur est spécifiée dans applicationBuildInfo(), l'utilise.
70 // Sinon, le répertoire de sortie est le nom du cas dans le répertoire
71 // courant.
72 String output_dir_name = application()->applicationBuildInfo().outputDirectory();
73 if (output_dir_name.empty()){
74 // Détermine et créé le répertoire pour les exportations et le listing
75 Directory output_base_dir(platform::getCurrentDirectory());
76 output_dir_name = output_base_dir.file(m_case_name);
77 }
78 m_output_directory = Directory(output_dir_name);
79 m_listing_directory = Directory(m_output_directory,"listing");
80
81 IParallelSuperMng* sm = application()->parallelSuperMng();
82 bool is_master_io = sm->isMasterIO();
83
84 info() << "Output directory is <" << output_dir_name << ">";
85 if (is_master_io){
86 m_output_directory.createDirectory();
87 m_listing_directory.createDirectory();
88 }
89 // Pour être sur que tout le répertoire de sortie est visible par tout le monde
90 sm->barrier();
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96void ArcaneSession::
97_initSubDomain(ISubDomain* sd)
98{
99 sd->setCaseName(m_case_name);
100
101 sd->setExportDirectory(m_output_directory);
102 sd->setStorageDirectory(m_output_directory);
103 sd->setListingDirectory(m_listing_directory);
104
105 setLogAndErrorFiles(sd);
106}
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
115void ArcaneSession::
116setLogAndErrorFiles(ISubDomain* sd)
117{
118 bool is_log_disabled = false;
119 if (!platform::getEnvironmentVariable("ARCANE_DISABLE_LOG").null()){
120 is_log_disabled = true;
121 }
122 ITraceMng* tm = sd->traceMng();
123
124 IParallelMng* pm = sd->parallelMng();
125 IParallelReplication* replication = pm->replication();
126 IParallelMng* all_replica_pm = sd->allReplicaParallelMng();
127 bool is_master_io = all_replica_pm->isMasterIO();
128
129 Int32 sid = sd->subDomainId();
130 Int32 nb_sub_domain = sd->nbSubDomain() * replication->nbReplication();
131
132 Int32 nb_sub_dir = 1;
133 Int32 NB_FILE_PER_SUBDIR = 256;
134
137 // if (nb_sub_dir<1) nb_sub_dir = 1; // DEAD CODE
138 }
139
140 if (is_master_io){
141 m_listing_directory.createDirectory();
142 if (nb_sub_dir!=1){
143 for( Integer i=0; i<nb_sub_dir; ++i ){
144 Directory sub_dir = Directory(m_listing_directory,String::fromNumber(i));
145 sub_dir.createDirectory();
146 }
147 }
148 }
149
150 // Attend que le proc maitre ait crée tous les repertoires.
151 Directory my_directory = m_listing_directory;
152 if (nb_sub_dir!=1){
153 all_replica_pm->barrier();
154 Int32 global_sid = sid + (sd->nbSubDomain() * replication->replicationRank());
155 my_directory = Directory(m_listing_directory,String::fromNumber(global_sid/NB_FILE_PER_SUBDIR));
156 }
157
158 // En cas de réplication, ajoute le numéro du replica à la fin des fichiers
159 // (sauf pour le replica 0 pour rester compatible avec le nom sans réplication)
160 String file_suffix = String::fromNumber(sid);
161 if (replication->hasReplication()){
162 Int32 replication_rank = replication->replicationRank();
163 if (replication_rank>0)
165 }
166
167 {
168 StringBuilder fn("errors.");
169 fn += file_suffix;
170 String file(my_directory.file(fn));
171 info() << "Error output file '" << file << "'";
172 platform::removeFile(file);
173 tm->setErrorFileName(file);
174 }
175
176 if (is_log_disabled){
177 tm->setLogFileName(String());
178 tm->info() << "Logs are disabled because environment variable ARCANE_DISABLE_LOG is set";
179 }
180 else{
181 StringBuilder fn("logs.");
182 fn += file_suffix;
183 String file(my_directory.file(fn));
184 platform::removeFile(file);
185 tm->setLogFileName(file);
186 }
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192void ArcaneSession::
193_writeExecInfoFile(int ret_val)
194{
195 IParallelSuperMng* psm = _application()->parallelSuperMng();
196 if (psm->commRank()!=0)
197 return;
198
199 _checkExecInfoFile();
200
201 XmlNode result_root = m_result_doc->documentNode().documentElement();
202 XmlNode execution = result_root.child("execution");
203 execution.clear();
204
205 String datetime(platform::getCurrentDateTime());
206 // Sauve les informations du cas
207 {
208 execution.createAndAppendElement("return-value",String::fromNumber(ret_val));
209 execution.createAndAppendElement("finish-date",datetime);
210 execution.createAndAppendElement("date",platform::getCurrentDateTime());
211 SubDomainCollection sub_domains(subDomains());
212 if (!sub_domains.empty()){
213 ISubDomain* sd = sub_domains.front();
214 // Il faut que le sous-domaine soit correct.
215 // Ce n'est des fois pas le cas si cette méthode est appelée suite
216 // à une exception lancée lors de l'initialisation du sous-domaine
217 if (sd->isInitialized()){
218 ITimeLoopMng* tm = sd->timeLoopMng();
219 const CommonVariables& v = sd->commonVariables();
220 execution.createAndAppendElement("current-iteration",String::fromNumber(v.globalIteration()));
221 execution.createAndAppendElement("current-time",String::fromNumber(v.globalTime()));
222 execution.createAndAppendElement("end-time",String::fromNumber(v.globalFinalTime()));
223 execution.createAndAppendElement("deltat",String::fromNumber(v.globalDeltaT()));
224 execution.createAndAppendElement("cpu-time",String::fromNumber(v.globalCPUTime()));
225 const char* is_finished_str = tm->finalTimeReached() ? "1" : "0";
226 execution.createAndAppendElement("is-finished",is_finished_str);
227 }
228 }
229 }
230 String file(m_listing_directory.file("coderesult.xml"));
231 logdate() << "Info output in 'coderesult.xml'";
232 IIOMng* io_mng = _application()->ioMng();
233 io_mng->writeXmlFile(m_result_doc,file);
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239void ArcaneSession::
240writeExecInfoFile()
241{
242 _writeExecInfoFile(-1);
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
248void ArcaneSession::
249_checkExecInfoFile()
250{
251 if (m_result_doc)
252 return;
253
254 m_result_doc = _application()->ressourceMng()->createXmlDocument();
255 XmlNode doc = m_result_doc->documentNode();
256 XmlElement root(doc,"arcane-result");
257
258 // Sauve les informations de configuration du cas.
259 XmlElement config(root,"config");
260 XmlElement execution(root,"execution");
261
262 config.createAndAppendElement("case-name",m_case_name);
263 config.createAndAppendElement("host",platform::getHostName());
264 config.createAndAppendElement("pid",String::fromNumber(platform::getProcessId()));
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270void ArcaneSession::
271endSession(int ret_val)
272{
273 _writeExecInfoFile(ret_val);
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
279void ArcaneSession::
280setCaseName(String casename)
281{
282 m_case_name = casename;
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288} // End namespace Arcane
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
Variables communes d'un cas.
Real globalCPUTime() const
Temps CPU utilisé (en seconde)
Real globalDeltaT() const
Delta T courant.
Real globalTime() const
Temps courant.
Int32 globalIteration() const
Numéro de l'itération courante.
Real globalFinalTime() const
Temps final de la simulation.
Classe gérant un répertoire.
Definition Directory.h:33
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual IParallelReplication * replication() const =0
Informations sur la réplication.
Informations sur la réplication des sous-domaines en parallèle.
virtual bool hasReplication() const =0
Indique si la réplication est active.
virtual Int32 replicationRank() const =0
Rang dans la réplication (de 0 à nbReplication()-1)
virtual Int32 nbReplication() const =0
Nombre de réplication.
Classe abstraite du superviseur de parallélisme.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Interface du gestionnaire de la boucle en temps.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Elément d'un arbre DOM.
Definition XmlNode.h:396
Noeud d'un arbre DOM.
Definition XmlNode.h:51
Interface du gestionnaire de traces.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-