Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ArcaneSession.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/* ArcaneSession.cc (C) 2000-2020 */
9/* */
10/* Default implementation of a 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/core/IParallelMng.h"
22#include "arcane/core/IParallelSuperMng.h"
23#include "arcane/core/IParallelReplication.h"
24#include "arcane/core/Directory.h"
25#include "arcane/core/IXmlDocumentHolder.h"
26#include "arcane/core/ISubDomain.h"
27#include "arcane/core/ITimeLoopMng.h"
28#include "arcane/core/IApplication.h"
29#include "arcane/core/IRessourceMng.h"
30#include "arcane/core/XmlNode.h"
31#include "arcane/core/CommonVariables.h"
32#include "arcane/core/IIOMng.h"
33#include "arcane/core/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{
68
69 // If a value is specified in applicationBuildInfo(), use it.
70 // Otherwise, the output directory is the case name in the current directory.
71 String output_dir_name = application()->applicationBuildInfo().outputDirectory();
72 if (output_dir_name.empty()) {
73 // Determines and creates the directory for exports and listing
75 output_dir_name = output_base_dir.file(m_case_name);
76 }
77 m_output_directory = Directory(output_dir_name);
78 m_listing_directory = Directory(m_output_directory, "listing");
79
80 IParallelSuperMng* sm = application()->parallelSuperMng();
81 bool is_master_io = sm->isMasterIO();
82
83 info() << "Output directory is <" << output_dir_name << ">";
84 if (is_master_io) {
85 m_output_directory.createDirectory();
86 m_listing_directory.createDirectory();
87 }
88 // To ensure that the entire output directory is visible to everyone
89 sm->barrier();
90}
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
95void ArcaneSession::
96_initSubDomain(ISubDomain* sd)
97{
98 sd->setCaseName(m_case_name);
99
100 sd->setExportDirectory(m_output_directory);
101 sd->setStorageDirectory(m_output_directory);
102 sd->setListingDirectory(m_listing_directory);
103
104 setLogAndErrorFiles(sd);
105}
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
135 if (nb_sub_domain > (NB_FILE_PER_SUBDIR)) {
136 nb_sub_dir = nb_sub_domain / NB_FILE_PER_SUBDIR;
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 // Waits for the master process to create all directories.
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 // In case of replication, adds the replica number to the end of the files
159 // (except for replica 0 to remain compatible with the name without replication)
160 String file_suffix = String::fromNumber(sid);
161 if (replication->hasReplication()) {
162 Int32 replication_rank = replication->replicationRank();
163 if (replication_rank > 0)
164 file_suffix = file_suffix + String("_r") + replication_rank;
165 }
166
167 {
168 StringBuilder fn("errors.");
169 fn += file_suffix;
170 String file(my_directory.file(fn));
171 info() << "Error output file '" << 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));
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
206 // Saves the case information
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 // The subdomain must be correct.
215 // This is sometimes not the case if this method is called after an exception
216 // thrown during subdomain initialization
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 // Saves the case configuration information.
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/*---------------------------------------------------------------------------*/
Common variables of a case.
Real globalCPUTime() const
CPU time used (in seconds).
Real globalDeltaT() const
Current Delta T.
Real globalTime() const
Current time.
Int32 globalIteration() const
Current iteration number.
Real globalFinalTime() const
Final time of the simulation.
Class managing a directory.
Definition Directory.h:36
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Definition Directory.cc:120
bool createDirectory() const override
Creates the directory.
Definition Directory.cc:102
Application interface.
virtual ITraceMng * traceMng() const =0
Trace manager.
Interface of the parallelism manager for a subdomain.
virtual IParallelReplication * replication() const =0
Replication information.
virtual bool isMasterIO() const =0
true if the instance is a master I/O manager.
virtual void barrier()=0
Performs a barrier.
Brief information on parallel subdomain replication.
virtual bool hasReplication() const =0
Indicates if replication is active.
virtual Int32 replicationRank() const =0
Rank in the replication (from 0 to nbReplication()-1).
virtual Int32 nbReplication() const =0
Number of replications.
Abstract class of the parallelism supervisor.
virtual bool isMasterIO() const =0
Returns true if the instance is a master I/O manager.
virtual Int32 commRank() const =0
Returns the process number (between 0 and nbProcess()-1).
virtual void barrier()=0
Parallelism manager for all allocated resources.
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual Int32 subDomainId() const =0
Subdomain ID associated with this manager.
virtual const CommonVariables & commonVariables() const =0
Information on standard variables.
virtual void setStorageDirectory(const IDirectory &dir)=0
Sets the output path for exports requiring archiving.
virtual void setListingDirectory(const IDirectory &dir)=0
Sets the output path for listing info.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual ITimeLoopMng * timeLoopMng()=0
Returns the time loop manager.
virtual void setExportDirectory(const IDirectory &dir)=0
Sets the output path for exports (protections and restarts).
virtual Int32 nbSubDomain() const =0
Total number of subdomains.
virtual void setCaseName(const String &name)=0
Sets the case name.
virtual bool isInitialized() const =0
Indicates if the session has been initialized.
virtual IParallelMng * allReplicaParallelMng() const =0
Returns the parallelism manager for all replicas.
Interface for the time loop manager.
virtual bool finalTimeReached() const =0
Returns true if the final time has been reached.
virtual void setErrorFileName(const String &file_name)=0
Sets the error file name to file_name.
virtual void setLogFileName(const String &file_name)=0
Sets the log file name to file_name.
virtual TraceMessage info()=0
Stream for an information message.
Session.
Definition Session.h:40
virtual void build()
Constructs the instance members. The instance is not usable until this method has been called....
Definition Session.cc:115
virtual IApplication * application() const
Application.
Definition Session.cc:198
Unicode character string constructor.
bool empty() const
True if the string is empty (null or "").
Definition String.cc:317
TraceMessage info() const
Flow for an information message.
Element of a DOM tree.
Definition XmlNode.h:406
Node of a DOM tree.
Definition XmlNode.h:51
XmlNode documentElement() const
Returns the document element.
Definition XmlNode.cc:565
XmlNode child(const String &name) const
Child node of this node with name name.
Definition XmlNode.cc:73
void clear()
Deletes all child nodes.
Definition XmlNode.cc:302
bool removeFile(const String &file_name)
Delete the file file_name.
String getCurrentDateTime()
Current date and time in ISO 8601 format.
String getHostName()
Name of the machine running the process.
String getCurrentDirectory()
Current directory path.
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
Collection< ISubDomain * > SubDomainCollection
Collection of subdomains.
std::int32_t Int32
Signed integer type of 32 bits.