TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Memoire.cpp
1/****************************************************************************
2* Copyright (c) 2024, 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 <TRUSTVect.h>
17#include <Memoire.h>
18#include <Nom.h>
19
20static int compteur=0;
21Memoire* Memoire::_instance = 0;
22int Memoire::prems=0;
23int Memoire::step=4096;
24//struct mallinfo minfo;
25static int max_sz_mem=0;
26static int min_sz_mem=0;
27
28/*! @brief Retourne un pointeur sur l'instance de la memoire Cree un nouvel objet memoire si aucune instance n'a deja ete creee
29 *
30 * @return (Memoire*) pointeur sur l'instance de la memoire
31 */
33{
34 if (_instance == 0) _instance = new Memoire;
35
36 return *_instance;
37}
38
39/*! @brief Constructeur Initialize une zone de travail pour les Objet_U, les "double" et les "int"
40 *
41 */
43 size(step), data(new Memoire_ptr[step])
44{
45 for(int i=prems; i<size; i++)
46 data[i].next=i+1;
47}
48
49/*! @brief Ajoute un Objet_U dans la Memoire de TRUST
50 *
51 * @param (Objet_U* obj) pointeur sur l'Objet_U a ajouter
52 * @return (int) le numero affecte a l'objet dans la memoire
53 */
55{
56 assert(_instance != 0);
57 compteur++;
58 if(prems<size)
59 {
60 const int num=prems;
61 assert(data[num].libre());
62 data[num].set(obj);
63 prems=data[num].next;
64 data[num].next = -1;
65 assert(prems>=0);
66 // minfo = mallinfo();
67 // int sz_mem = minfo.arena;
68 // if(sz_mem > max_sz_mem) max_sz_mem = sz_mem;
69 return num;
70 }
71 int old_size=size;
72 int i;
73 size*=2;
74 // Cerr<<"size "<<size<<" "<<size/step<<finl;
75 Memoire_ptr* newdata=new Memoire_ptr[size];
76 if(!newdata)
77 {
78 Cerr << "Not enough memory " << finl;
80 }
81 Memoire_ptr newptr(obj);
82 for(i=0; i<old_size; i++)
83 {
84 newdata[i]=data[i];
85 data[i].set(0);
86 }
87 newdata[old_size]=newptr;
88 for(i=old_size; i<size; i++)
89 newdata[i].next=i+1;
90 if(data)
91 delete[] data;
92 data=newdata;
93 prems=old_size+1;
94 // minfo = mallinfo();
95 // int sz_mem = minfo.arena;
96 // if(sz_mem > max_sz_mem) max_sz_mem = sz_mem;
97 return old_size;
98}
99
100/*! @brief Suppression de la memoire de l'Objet_U de numero num L'Objet_U n'est pas supprime, seul son pointeur dans la memoire l'est.
101 *
102 * @param (int num) le numero de l'Objet_U a supprimer
103 * @return (int) code de retour, retourne toujours 1
104 */
105int Memoire::suppr(int num)
106{
107 // Cerr << "Suppression de " << num << finl;
108 assert(!data[num].libre());
109 data[num].next=prems;
110 prems=num;
111 data[num].set(0);
112 compteur--;
113#ifndef _COMPILE_AVEC_PGCC
114 if((size>4*compteur)&&(size>step))
115 //if((size-compteur)>step)
116 {
117 compacte(); // Plantage obscur avec le compilateur NVidia a la fin du calcul
118 }
119#endif
120 /*
121 static int deb=0;
122 if (compteur >500) deb=1;
123 if ((deb)&&(compteur<3))
124 {
125 Cerr<<"here "<<compteur<<finl;
126
127 int i;
128 for(i=0; i<size; i++)
129 if(! data[i].libre())
130 {
131 Cerr << finl;
132 Cerr << i << " ";
133 const Objet_U& obj=objet_u(i);
134 Cerr << " :: ";
135 Cerr << "TYPE :" << obj.le_type()<<finl;
136 if(sub_type(Nom,obj)) Cerr << " NAME : " << obj.le_nom() <<finl;
137
138 }
139 }
140 */
141
142 //GF quand on n'a plus d'objet_u on detruit tout
143
144 if (compteur==0)
145 {
146 //Cerr<<"delete data"<<finl;
147 if (data)
148 {
149 delete[] data;
150 data=0;
151 delete _instance;
152 _instance=0;
153
154 }
155 }
156 return 1;
157}
158
159
160/*! @brief Retourne le rang dans la memoire de l'objet de type et de nom indiques
161 *
162 * @param (const Nom& type) le type de l'objet
163 * @param (const Nom& nom) le nom de l'objet
164 * @return (int) le rang de l'objet s'il est trouve dans la memoire, -1 sinon
165 */
166int Memoire::rang(const Nom& type, const Nom& nom) const
167{
168 Memoire_ptr* x=data;
169 for(int i=0; i<size; i++)
170 {
171 if( !( x->libre() ) )
172 if ( ((x->obj()).que_suis_je()==type) &&
173 ((x->obj()).le_nom()==nom) )
174 return i;
175 x++;
176 }
177 return -1;
178}
179
180
181/*! @brief Retourne le rang dans la memoire de l'objet de nom indique
182 *
183 * @param (const Nom& nom) le nom de l'objet
184 * @return (int) le rang de l'objet s'il est trouve dans la memoire, -1 sinon
185 */
186int Memoire::rang(const Nom& nom) const
187{
188 Memoire_ptr* x=data;
189 for(int i=0; i<size; i++)
190 if( !( x->libre() ) )
191 {
192 if (((x->obj()).le_nom())==nom)
193 return i;
194 x++;
195 }
196 return -1;
197}
198
199
200/*! @brief Retoune une reference sur l'Objet_U de rang num dans la memoire
201 *
202 * @param (int num) le rang de l'objet dans la memoire
203 * @return (Objet_U&) reference sur l'Objet_U trouve
204 * @throws Sort en erreur si la memoire comporte une erreur a la case de rang num
205 */
207{
208 assert(num >=0);
209 assert(num < size);
210 assert(!data[num].libre());
211 Objet_U& objet = data[num].obj();
212 const int num_obj = objet.numero();
213 if (num_obj != num)
214 {
215 Cerr << "Error in Objet_U & Memoire::objet_u(int num) " << finl;
216 Cerr << " num = " << num << finl;
217 std::cerr << " data[num].o_ptr = " << &objet << std::endl;
218 Cerr << " data[num].o_ptr->numero() = " << num_obj << finl;
219 assert(0);
221 }
222 return objet;
223}
224
225
226/*! @brief Retoune une reference constante sur l'Objet_U de rang num dans la memoire
227 *
228 * @param (int num) le rang de l'objet dans la memoire
229 * @return (const Objet_U&) reference sur l'Objet_U trouve
230 * @throws Sort en erreur si la memoire comporte une erreur a la case de rang num
231 */
232const Objet_U& Memoire::objet_u(int num) const
233{
234 assert(num >=0);
235 assert(num < size);
236 assert(!data[num].libre());
237 Objet_U& objet = data[num].obj();
238 const int num_obj = objet.numero();
239 if (num_obj != num)
240 {
241 Cerr << "Error in const Objet_U & Memoire::objet_u(int num) " << finl;
242 Cerr << " num = " << num << finl;
243 std::cerr << " data[num].o_ptr = " << &objet << std::endl;
244 Cerr << " data[num].o_ptr->numero() = " << num_obj << finl;
245 assert(0);
247 }
248 return objet;
249}
250
251
252/*! @brief Retoune un pointeur sur l'Objet_U de rang num dans la memoire
253 *
254 * @param (int num) le rang de l'objet dans la memoire
255 * @return (Objet_U&) reference sur l'Objet_U trouve
256 * @throws Sort en erreur si la memoire comporte une erreur a la case de rang num
257 */
259{
260 assert(num >=0);
261 assert(num < size);
262 assert(!data[num].libre());
263 Objet_U& objet = data[num].obj();
264 const int num_obj = objet.numero();
265 if (num_obj != num)
266 {
267 Cerr << "Error in Objet_U * Memoire::objet_u(int num) " << finl;
268 Cerr << " num = " << num << finl;
269 std::cerr << " data[num].o_ptr = " << &objet << std::endl;
270 Cerr << " data[num].o_ptr->numero() = " << num_obj << finl;
271 assert(0);
273 }
274 return &objet;
275}
276
277
278/*! @brief Retoune un pointeur constant sur l'Objet_U de rang num dans la memoire
279 *
280 * @param (int num) le rang de l'objet dans la memoire
281 * @return (Objet_U&) reference sur l'Objet_U trouve
282 * @throws Sort en erreur si la memoire comporte une erreur a la case de rang num
283 */
284const Objet_U* Memoire::objet_u_ptr(int num)const
285{
286 assert(num >=0);
287 assert(num < size);
288 assert(!data[num].libre());
289 Objet_U& objet = data[num].obj();
290 const int num_obj = objet.numero();
291 if (num_obj != num)
292 {
293 Cerr << "Error in const Objet_U * Memoire::objet_u(int num) " << finl;
294 Cerr << " num = " << num << finl;
295 std::cerr << " data[num].o_ptr = " << &objet << std::endl;
296 Cerr << " data[num].o_ptr->numero() = " << num_obj << finl;
297 assert(0);
299 }
300 return &objet;
301}
302
303/*! @brief Compacte la memoire Ce compactage est effectue automatiquement lorsqu'il devient necessaire
304 *
305 */
307{
308 int i, compte=0;
309 int* newnum=new int[size];
310 if(!newnum)
311 {
312 Cerr << "Not enough memory " << finl;
314 }
315 for(i=0; i<size; i++)
316 if(data[i].libre())
317 newnum[i]=-1;
318 else
319 newnum[i]=compte++;
320 for(i=0; i<size; i++)
321 if(newnum[i]>-1)
322 {
323 objet_u(i).change_num(newnum);
324 }
325 Memoire_ptr* newdata=new Memoire_ptr[compte];
326 if(!newdata)
327 {
328 Cerr << "Not enough memory " << finl;
330 }
331 for(i=0; i< size; i++)
332 if(newnum[i]>-1)
333 newdata[newnum[i]]=data[i];
334 delete[] data;
335 delete[] newnum;
336 data=newdata;
337 size=prems=compte;
338 for(i=0; i<size; i++)
339 data[i].next=i+1;
340 verifie();
341}
342
343/*! @brief Imprime un etat sur la memoire sur la sortie des erreurs
344 *
345 * @return (int) code de retour; retourne toujours 1
346 */
348{
349 assert(prems <=size);
350 int i, tmp=0;
351 for(i=0; i<size; i++)
352 if(! data[i].libre()) tmp++;
353 Cerr << "\n There are " << size << " memory squares";
354 Cerr << "\n of which " << tmp << " ==(const char*)" << compteur << " are used" << finl;
355 for(i=0; i<size; i++)
356 {
357 Cerr << i << " :: " << flush;
358 if(! (data[i].libre()) )
359 {
360 const Objet_U& obj=data[i].obj();
361 if (obj.numero() != i)
362 Cerr << "error";
363 else
364 {
365 Cerr << "TYPE :" << obj.le_type()<< flush;
366 if (sub_type(Objet_U_ptr, obj))
367 {
368 const Objet_U_ptr& x=ref_cast(Objet_U_ptr, obj);
369 Cerr << " key: " << x << flush;
370 }
371 else
372 Cerr << " NAME : " << obj.le_nom() << flush;
373 Cerr << " address : " << (long)(&(obj))<< flush;
374 Cerr << " SIZE : " << (int)(obj.taille_memoire())<< " octets "<< flush;
375 }
376 }
377 else
378 Cerr << "free ";
379 Cerr << finl;
380 }
381 return 1;
382}
383
384/*! @brief Verifie le contenu de toutes les cases de la memoire
385 *
386 * @return (int) code de retour; retourne toujours 1
387 */
389{
390 assert(prems <=size);
391 for(int i=0; i<size; i++)
392 {
393 if(! (data[i].libre()) )
394 {
395 if ((data[i].obj()).numero() != i)
396 {
397 Cerr << "ERROR at the square " << i << finl;
398 imprime();
400 }
401 }
402 }
403 return 1;
404}
405
406/*! @brief Operateur d'affichage d'un etat de la memoire mem sur le flot de sortie os
407 *
408 * @param (Sortie& os) le flot de sortie a utiliser
409 * @param (const Memoire& mem) la memoire a examiner
410 * @return (Sortie& le flot de sortie modifie)
411 */
412Sortie& operator << (Sortie& os, const Memoire& mem)
413{
414 int i;
415 int total=0;
416 int tmp=0;
417 int tmp1=0;
418 for(i=0; i<mem.size; i++)
419 if(! mem.data[i].libre()) tmp++;
420 os << "\n il y a " << mem.size << " cases memoires";
421 os << "\n dont " << tmp << " ==(const char*)" << compteur << " sont occupees" << finl;
422 for(i=0; i<mem.size; i++)
423 if(! mem.data[i].libre())
424 {
425 os << i << " ";
426 const Objet_U& obj=mem.objet_u(i);
427 os << " :: ";
428 os << "TYPE :" << obj.le_type();
429 if(sub_type(Nom,obj)) os << " NOM : " << obj.le_nom() ;
430 os << " adresse : " << (long)(&(obj));
431
432 const ArrOfInt* intA = dynamic_cast<const ArrOfInt*>(&obj);
433 const ArrOfDouble* intAD = dynamic_cast<const ArrOfDouble*>(&obj);
434 if(intA)
435 {
436 const ArrOfInt& toto = *intA;
437 tmp = obj.taille_memoire() + (int) ((toto.size_array()*sizeof(int))/toto.ref_count());
438 os << " TAILLE ArrOfInt : " << tmp<< " octets ";
439
440 const IntVect* intV = dynamic_cast<const IntVect*>(&obj);
441 if(intV)
442 {
443 const IntVect& titi = *intV;
444 tmp1 = obj.taille_memoire() + (int) ((titi.size()*sizeof(int))/titi.ref_count());
445 os << " dont : " << (tmp-tmp1) << " octets virtuels ";
446 }
447 os << "\n";
448 }
449 else if (intAD)
450 {
451 const ArrOfDouble& toto = *intAD;
452 tmp = obj.taille_memoire() + (int) ((toto.size_array()*sizeof(double))/toto.ref_count());
453 os << " TAILLE ArrOfDouble : " << tmp<< " octets ";
454 /* PL: Plante en P1Bulle donc je commente
455 * const DoubleVect* intVD = dynamic_cast<const DoubleVect*>(&obj);
456 if(intVD){
457 const DoubleVect& titi = *intVD;
458 tmp1 = obj.taille_memoire() + (int) ((titi.size()*sizeof(double))/titi.ref_count());
459 os << " dont : " << (tmp-tmp1) << " octets virtuels ";
460 } */
461 os << "\n";
462 }
463 else
464 {
465 const ArrOfFloat* intAF = dynamic_cast<const ArrOfFloat*>(&obj);
466 if(intAF)
467 {
468 const ArrOfFloat& toto = *intAF;
469 tmp = obj.taille_memoire() + (int) ((toto.size_array()*sizeof(float))/toto.ref_count());
470 os << " TAILLE ArrOfFloat : " << tmp<< " octets ";
471 os << "\n";
472 }
473 else
474 {
475 os << " TAILLE : " << (tmp=obj.taille_memoire())<< " octets \n ";
476 }
477 }
478 total += tmp;
479 os.flush();
480 }
481 os << "Taille memoire max: " << max_sz_mem << finl;
482 os << "Taille memoire min: " << min_sz_mem << finl;
483 os << "Taille memoire occupee en Mo: " << (max_sz_mem-min_sz_mem)/1024/1024 << finl;
484
485 return os << "Occupation taille memoire totale en Mo: " << total/1024/1024 << finl;
486}
487
Pointeur dans la Memoire de TRUST pour un Objet_U.
Definition Memoire_ptr.h:28
void set(Objet_U *ptr)
Affecte un Objet_U a un pointeur memoire.
Definition Memoire_ptr.h:55
Objet_U & obj()
Retourne une reference sur l'Objet_U pointe par le pointeur memoire.
Definition Memoire_ptr.h:64
int libre() const
Indique si le pointeur memoire est libre, c'est-a-dire s'il pointe sur un Objet_U non nul.
Definition Memoire_ptr.h:46
La memoire de Trio-U.
Definition Memoire.h:30
int rang(const Nom &type, const Nom &nom) const
Retourne le rang dans la memoire de l'objet de type et de nom indiques.
Definition Memoire.cpp:166
Objet_U & objet_u(int)
Retoune une reference sur l'Objet_U de rang num dans la memoire.
Definition Memoire.cpp:206
int verifie() const
Verifie le contenu de toutes les cases de la memoire.
Definition Memoire.cpp:388
Objet_U * objet_u_ptr(int)
Retoune un pointeur sur l'Objet_U de rang num dans la memoire.
Definition Memoire.cpp:258
void compacte()
Compacte la memoire Ce compactage est effectue automatiquement lorsqu'il devient necessaire.
Definition Memoire.cpp:306
static Memoire & Instance()
Retourne un pointeur sur l'instance de la memoire Cree un nouvel objet memoire si aucune instance n'a...
Definition Memoire.cpp:32
int suppr(int)
Suppression de la memoire de l'Objet_U de numero num L'Objet_U n'est pas supprime,...
Definition Memoire.cpp:105
Memoire()
Constructeur Initialize une zone de travail pour les Objet_U, les "double" et les "int".
Definition Memoire.cpp:42
int imprime() const
Imprime un etat sur la memoire sur la sortie des erreurs.
Definition Memoire.cpp:347
int add(Objet_U *)
Ajoute un Objet_U dans la Memoire de TRUST.
Definition Memoire.cpp:54
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Pointeur sur un Objet_U.
Definition Objet_U_ptr.h:31
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
virtual unsigned taille_memoire() const =0
int numero() const
Renvoie l'indice de l'objet dans Memoire::data.
Definition Objet_U.cpp:268
virtual int change_num(const int *const)
Change le numero interne de l'Objet_U.
Definition Objet_U.cpp:181
const char * le_type() const
Donne le nom du type de l'Objet_U.
Definition Objet_U.cpp:191
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual Sortie & flush()
Definition Sortie.cpp:138
_SIZE_ size_array() const
int ref_count() const
_SIZE_ size() const
Definition TRUSTVect.tpp:45