TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
EcrFicPartage.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <EcrFicPartage.h>
17#include <PE_Groups.h>
18#include <Comm_Group.h>
19#include <communications.h>
20#include <Perf_counters.h>
21
22Implemente_instanciable_sans_constructeur_ni_destructeur(EcrFicPartage,"EcrFicPartage",SFichier);
24Sortie& EcrFicPartage::printOn(Sortie& s) const { throw; }
25
27{
28 obuffer_ptr_ = new OBuffer;
29 set_bin(false);
30}
31
32/*! @brief Ouvre le fichier avec les parametres mode et prot donnes Ces parametres sont les parametres de la methode open standard
33 *
34 */
35EcrFicPartage::EcrFicPartage(const char* name,IOS_OPEN_MODE mode)
36{
37 obuffer_ptr_ = new OBuffer;
38 set_bin(false);
39 obuffer_ptr_->set_64b(this->is_64b());
40
41 ouvrir(name, mode);
42}
43
44inline OBuffer& EcrFicPartage::get_obuffer()
45{
46 assert(obuffer_ptr_);
47 return *obuffer_ptr_;
48}
49
50/*! @brief Ouvre le fichier avec les parametres mode et prot donnes Ces parametres sont les parametres de la methode open standard
51 *
52 */
53int EcrFicPartage::ouvrir(const char* name,IOS_OPEN_MODE mode)
54{
55 // Verification sanitaire : tous les processeurs sont la ?
56 barrier();
57
58 int ok = 1;
59 if(je_suis_maitre())
60 {
61#ifdef FILESYSTEM_NON_GLOBAL
62 nom_fic_ = pwd();
63 nom_fic_ += "/";
64 nom_fic_ += name;
65#else
66 nom_fic_ = name;
67#endif
68 // Seul le maitre ouvre le fichier
69 ok = SFichier::ouvrir((const char *)nom_fic_, mode);
70 }
71 syncfile();
72
73 // Modif B.Math. 22/09/2004: tous les processeurs passent par le buffer,
74 // y compris le maitre.
75 get_obuffer().new_buffer();
76 return ok;
77}
78
79
80/*! @brief ferme le fichier
81 *
82 */
84{
85 close();
86 delete obuffer_ptr_;
87 obuffer_ptr_ = 0;
88}
89
91{
92 // Verification sanitaire : tout le monde est la ?
93 barrier();
94 const int buflen = get_obuffer().len();
95 if(buflen > 0)
96 {
97 Cerr << "***** WARNING : EcrFicPartage::close() ******* "<<nom_fic_
98 << "\non PE " << me() << " the buffer is not empty\n"
99 << " (Missing syncfile) : one makes a last syncfile" << finl;
100 Cerr<<get_obuffer().str()<<finl;
101 }
102#ifndef NDEBUG
103 // Y a-t-il un processeur sur lequel il reste des donnees
104 const trustIdType maxbuflen = mp_sum(buflen);
105 if (maxbuflen > 0)
106 syncfile();
107#endif
108 if(je_suis_maitre())
110#ifndef NDEBUG
111 if (maxbuflen > 0)
112 {
113 Cerr<<"It missed a syncfile somewhere"<<finl;
114 Cerr<<"Indeed, maxbuflen =" << maxbuflen << finl;
115 Cerr<<"GF prefers to stop the calculation to correct "<<finl;
116 exit();
117 }
118#endif
119}
120/*! @brief Permet au processus appelant de bloquer en attente de la ressource commune a tous les processus qui est le fichier partage.
121 *
122 * Si le processus appelant cette methode n'est pas le premier, il atend du processus precedent l'endroit ou il doit se positionner dans le fichier pour effectuer sa prochaine ecriture.
123 * Cette methode est systematiquement appelee avant toute nouvelle ecriture dans le fichier.
124 *
125 * @return (Sortie&) *this
126 */
128{
129 return *this;
130}
131
132
133/*! @brief Permet de debloquer la ressource critique pour leprocessus suivant.
134 *
135 * Le processus appelant, sauf si c'est le premier processus du groupe, envoie
136 * sa position courante au precessus suivant dans le groupe. Cette methode est
137 * a appeler apres chaque ecriture dans le fichier.
138 *
139 * @return (Sortie&) *this
140 */
142{
143 return *this;
144}
145
146/*! @brief Provoque l'ecriture sur disque des donnees accumulees sur les differents processeurs depuis le dernier appel a syncfile().
147 *
148 * Les donnees sont ecrites dans l'ordre croissant des processeurs.
149 * Cette fonction doit etre appelee le meme nombre de fois sur tous les processeurs !
150 *
151 * Exemple:
152 * processeur 0: processeur 1:
153 * file << "pe0 : 1" << finl; file << "pe1 : 1" << finl;
154 * file << "pe0 : 2" << finl; file << "pe1 : 2" << finl;
155 * file.syncfile(); file.syncfile();
156 * file << "pe0 : 3" << finl; file << "pe1 : 3" << finl;
157 * file << "pe0 : 4" << finl;
158 * file.syncfile(); file.syncfile();
159 * file << "pe0 : end" << finl; // le processeur 1 n'ecrit pas de donnees
160 * file.syncfile(); file.syncfile();
161 *
162 * Contenu du fichier :
163 * pe0 : 1
164 * pe0 : 2
165 * pe1 : 1
166 * pe1 : 2
167 * pe0 : 3
168 * pe0 : 4
169 * pe1 : 3
170 * pe0 : end
171 *
172 */
174{
175 // En mode ascii, les donnees sont converties en ascii lors de l'ecriture dans
176 // le buffer. Une deuxieme conversion a lieu lors de l'ecriture sur disque
177 // (selon le systeme d'exploitation, '\n' est code differemment par exemple)
178 // Donc, en ascii, on utilisera
179 // file << buffer;
180 // et en binaire
181 // file.write(buffer, size);
182 // Or file << buffer determine la longueur du buffer en cherchant de caractere '\0'
183 // Par consequent, en ascii, il faut que le buffer finisse par un caractere '\0'
184 // que l'on ajoute ici:
185
186 if (! bin_)
187 {
188 get_obuffer().put_null_char();
189 }
190
191 const Comm_Group& group = PE_Groups::current_group();
192 if(je_suis_maitre())
193 {
194 int p;
195 const int nb_proc = nproc();
196 for(p=0; p<nb_proc; p++)
197 {
198 const char * buffer_data = 0;
199 char * allocated_buffer = 0;
200 int buf_size;
201
202 // On recupere les donnees du processeur p, soit directement (p==me()),
203 // soit par communication :
204 if (p == me())
205 {
206 // Ecriture de mes propres donnees : je les prends dans le buffer.
207 // Ce pointeur peut etre nul:
208 buffer_data = get_obuffer().str();
209 buf_size = get_obuffer().len();
210 }
211 else
212 {
213 // Ecriture des donnees d'un autre processeur, je les recupere.
214 int dummy = 0;
215 envoyer(dummy, p, 100); // Faire coucou au processeur p pour qu'il envoie ses donnees
216 recevoir(buf_size, p, 100);
217 if (buf_size > 0)
218 {
219 buffer_data = allocated_buffer = new char[buf_size];
220 group.recv(p, allocated_buffer, buf_size, 100);
221 }
222 }
223 // Ecriture dans le fichier disque
224 if (buf_size > 0)
225 {
226 assert(buffer_data);
227 ostream& os = get_ostream();
228 if (bin_)
229 {
230 // Ecriture binaire sans conversion :
231 statistics().begin_count(STD_COUNTERS::IO_EcrireFicPartageBin,statistics().get_last_opened_counter_level()+1);
232 os.write(buffer_data, buf_size);
233 statistics().end_count(STD_COUNTERS::IO_EcrireFicPartageBin,1,buf_size);
234 }
235 else
236 {
237 // On verifie que le buffer finit bien par un caractere 0 :
238 assert(buffer_data[buf_size-1] == 0);
239 // Ecriture de buffer_data comme une chaine
240 // (conversion des \n sur certains systemes, etc...)
241 os << buffer_data;
242 }
243 }
244 if (allocated_buffer)
245 delete[] allocated_buffer;
246 }
247 // Force a tout ecrire sur le disque tout de suite:
248 // (appel a la fonction flush de bas niveau, pas celle de trio).
249 get_ostream().flush();
250 }
251 else
252 {
253 // Envoi du buffer au processeur maitre:
254 // On attend qu'il demande les donnees pour ne pas engorger le reseau :
255 // (sinon tous les processeurs envoient simultanement leurs donnees)
256 int dummy;
257 recevoir(dummy, 0, 100);
258 int buf_size = get_obuffer().len();
259 envoyer(buf_size, 0, 100);
260 // Si la taille est non nulle, on envoie le buffer :
261 if (buf_size > 0)
262 {
263 const char * buffer_data = get_obuffer().str();
264 group.send(0, buffer_data, buf_size, 100);
265 }
266 }
267
268 // On vide le buffer :
269 get_obuffer().new_buffer();
270 return *this;
271}
272
273void EcrFicPartage::precision(int i) { get_obuffer().precision(i); }
274
275int EcrFicPartage::get_precision() { return get_obuffer().get_precision(); }
276
278{
279 get_obuffer() << ob;
280 return *this;
281}
282
283Sortie& EcrFicPartage::operator <<(const std::string& str) { return operator_template<std::string>(str);}
284Sortie& EcrFicPartage::operator <<(const Separateur& s) { return operator_template<Separateur>(s);}
285Sortie& EcrFicPartage::operator <<(const Objet_U& ob) { return operator_template<Objet_U>(ob);}
286Sortie& EcrFicPartage::operator <<(const int ob) { return operator_template<int>(ob);}
287Sortie& EcrFicPartage::operator <<(const unsigned ob) { return operator_template<unsigned>(ob);}
288Sortie& EcrFicPartage::operator <<(const float ob) { return operator_template<float>(ob);}
289Sortie& EcrFicPartage::operator <<(const double ob) { return operator_template<double>(ob);}
290Sortie& EcrFicPartage::operator <<(const long ob) { return operator_template<long>(ob);}
291Sortie& EcrFicPartage::operator <<(const long long ob) { return operator_template<long long>(ob);}
292Sortie& EcrFicPartage::operator <<(const unsigned long ob) { return operator_template<unsigned long>(ob);}
293
294
295int EcrFicPartage::put(const unsigned* ob, std::streamsize n, std::streamsize pas) { return put_template<unsigned>(ob,n,pas); }
296int EcrFicPartage::put(const int* ob, std::streamsize n, std::streamsize pas) { return put_template<int>(ob,n,pas); }
297int EcrFicPartage::put(const long* ob, std::streamsize n, std::streamsize pas) { return put_template<long>(ob,n,pas); }
298int EcrFicPartage::put(const long long* ob, std::streamsize n, std::streamsize pas) { return put_template<long long>(ob,n,pas); }
299int EcrFicPartage::put(const float* ob, std::streamsize n, std::streamsize pas) { return put_template<float>(ob,n,pas); }
300int EcrFicPartage::put(const double* ob, std::streamsize n, std::streamsize pas) { return put_template<double>(ob,n,pas); }
301
302
304{
306 get_obuffer().set_bin(bin_);
307}
308
310{
311 SFichier::set_64b(is64);
312 get_obuffer().set_64b(is64);
313}
314
315Sortie& EcrFicPartage::flush() { return (*this); }
virtual void set_bin(bool bin)
Definition AbstractIO.h:39
bool bin_
Is this a binary flux?
Definition AbstractIO.h:50
bool is_64b() const
Definition AbstractIO.h:37
virtual void set_64b(bool is_64b)
Definition AbstractIO.h:38
: Cette classe decrit un groupe de processeurs sur lesquels
Definition Comm_Group.h:40
virtual void send(int pe, const void *buffer, int size, int tag) const =0
virtual void recv(int pe, void *buffer, int size, int tag) const =0
int put(const unsigned *ob, std::streamsize n, std::streamsize pas) override
int get_precision() override
~EcrFicPartage() override
ferme le fichier
Sortie & unlockfile() override
Permet de debloquer la ressource critique pour leprocessus suivant.
Sortie & lockfile() override
Permet au processus appelant de bloquer en attente de la ressource commune a tous les processus qui e...
Sortie & flush() override
void set_bin(bool bin) override
Sortie & operator<<(const char *ob) override
Ecriture d'une chaine de caracteres.
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out) override
Ouvre le fichier avec les parametres mode et prot donnes Ces parametres sont les parametres de la met...
Sortie & syncfile() override
Provoque l'ecriture sur disque des donnees accumulees sur les differents processeurs depuis le dernie...
void precision(int) override
void set_64b(bool is64) override
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
friend class Sortie
Definition Objet_U.h:75
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static const Comm_Group & current_group()
renvoie une reference au groupe de processeurs actif courant
Definition PE_Groups.h:65
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
Definition Process.cpp:136
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
SFichier(const char *name, IOS_OPEN_MODE mode=ios::out)
Definition SFichier.h:30
Separateur pour les fichiers.
Definition Separateur.h:30
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Classe de base des flux de sortie.
Definition Sortie.h:52
ostream & get_ostream()
Definition Sortie.h:64