TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
TRUSTTab.tpp
1/****************************************************************************
2* Copyright (c) 2025, 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#ifndef TRUSTTab_TPP_included
17#define TRUSTTab_TPP_included
18
19#include <TRUSTTab.h>
20
21// TODO : FIXME : delete
22template<typename _TYPE_, typename _SIZE_>
24{
25 assert(this->nb_dim_ == 1 || (this->nb_dim_ == 2 && dimensions_[1] == 1));
26 assert(i >= 0 && i < dimension_tot_0_);
28}
29
30// TODO : FIXME : delete
31template<typename _TYPE_, typename _SIZE_>
32inline const _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator[](_SIZE_ i) const
33{
34 assert(this->nb_dim_ == 1 || (this->nb_dim_ == 2 && dimensions_[1] == 1));
35 assert(i >= 0 && i < dimension_tot_0_);
37}
38
39template<typename _TYPE_, typename _SIZE_>
41{
42 assert(this->nb_dim_ == 1 || (this->nb_dim_ == 2 && dimensions_[1] == 1));
43 assert(i >= 0 && i < dimension_tot_0_);
45}
46
47template<typename _TYPE_, typename _SIZE_>
48inline const _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i) const
49{
50 assert(this->nb_dim_ == 1 || (this->nb_dim_ == 2 && dimensions_[1] == 1));
51 assert(i >= 0 && i < dimension_tot_0_);
53}
54
55#pragma GCC diagnostic push
56#pragma GCC diagnostic ignored "-Wstrict-overflow"
57template<typename _TYPE_, typename _SIZE_>
58inline _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i1, int i2)
59{
60 assert(this->nb_dim_ == 2);
61 assert(i1 >= 0 && i1 < dimension_tot_0_);
62 assert(i2 >= 0 && i2 < dimensions_[1]);
63 return TRUSTVect<_TYPE_,_SIZE_>::operator[](i1*dimensions_[1]+i2);
64}
65
66template<typename _TYPE_, typename _SIZE_>
67inline const _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i1, int i2) const
68{
69 assert(this->nb_dim_ == 2);
70 assert(i1 >= 0 && i1 < dimension_tot_0_);
71 assert(i2 >= 0 && i2 < dimensions_[1]);
72 return TRUSTVect<_TYPE_,_SIZE_>::operator[](i1*dimensions_[1]+i2);
73}
74
75template<typename _TYPE_, typename _SIZE_>
76inline _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i1, int i2, int i3)
77{
78 assert(this->nb_dim_ == 3);
79 assert(i1 >= 0 && i1 < dimension_tot_0_);
80 assert(i2 >= 0 && i2 < dimensions_[1]);
81 assert(i3 >= 0 && i3 < dimensions_[2]);
82 return TRUSTVect<_TYPE_,_SIZE_>::operator[]((i1*dimensions_[1]+i2)*dimensions_[2]+i3);
83}
84
85template<typename _TYPE_, typename _SIZE_>
86inline const _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i1, int i2, int i3) const
87{
88 assert(this->nb_dim_ == 3);
89 assert(i1 >= 0 && i1 < dimension_tot_0_);
90 assert(i2 >= 0 && i2 < dimensions_[1]);
91 assert(i3 >= 0 && i3 < dimensions_[2]);
92 return TRUSTVect<_TYPE_,_SIZE_>::operator[]((i1*dimensions_[1]+i2)*dimensions_[2]+i3);
93}
94
95template<typename _TYPE_, typename _SIZE_>
96inline _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i1, int i2, int i3, int i4)
97{
98 assert(this->nb_dim_ == 4);
99 assert(i1 >= 0 && i1 < dimension_tot_0_);
100 assert(i2 >= 0 && i2 < dimensions_[1]);
101 assert(i3 >= 0 && i3 < dimensions_[2]);
102 assert(i4 >= 0 && i4 < dimensions_[3]);
103 return TRUSTVect<_TYPE_,_SIZE_>::operator[](((i1*dimensions_[1]+i2)*dimensions_[2]+i3)*dimensions_[3]+i4);
104}
105
106template<typename _TYPE_, typename _SIZE_>
107inline const _TYPE_& TRUSTTab<_TYPE_,_SIZE_>::operator()(_SIZE_ i1, int i2, int i3, int i4) const
108{
109 assert(this->nb_dim_ == 4);
110 assert(i1 >= 0 && i1 < dimension_tot_0_);
111 assert(i2 >= 0 && i2 < dimensions_[1]);
112 assert(i3 >= 0 && i3 < dimensions_[2]);
113 assert(i4 >= 0 && i4 < dimensions_[3]);
114 return TRUSTVect<_TYPE_,_SIZE_>::operator[](((i1*dimensions_[1]+i2)*dimensions_[2]+i3)*dimensions_[3]+i4);
115}
116#pragma GCC diagnostic pop
117
118/*! Returns one of the "real" dimensions of the multi-dimensionnal array, as defined by:
119 * dimension(0) = size_reelle() / line_size(), or 0 if line_size()==0
120 * and, for i >= 1 : dimension(i) is equal to dimension_tot(i)
121 * If TRUSTVect<_TYPE_,_SIZE_>::size_reelle_ok() returns 0, it is invalid to ask for dimension(0). You can only ask for dimension_tot(0) (see TRUSTVect<_TYPE_,_SIZE_>::size_reelle_ok())
122 *
123 * In 64 bits, dimensions higher than 1 can always safely be casted down to an int, only the first dimension might be big.
124 * To help with this, the _RET_TYPE_ parameter can be used. One can write:
125 * int d1 = toto.dimension<int>(1);
126 * which is cleaner than doing a wild cast like
127 * int d1 = (int)toto.dimension(1);
128 * and it will also check for potential overflow (with an assert).
129 * This type of pattern is used in the 64b part of the code (before Scatter) when retreiving higher dimensions of arrays.
130 * See arch.h.in for more explanations on 64b.
131 */
132template<typename _TYPE_, typename _SIZE_>
133inline _SIZE_ TRUSTTab<_TYPE_,_SIZE_>::dimension(int i) const
134{
135 assert(i >= 0 && i < this->nb_dim_);
136 // Si dimension_[0] == -1, c'est que c'est un vecteur distribue et que l'attribut size() est invalide. Il faut alors utiliser dimension_tot pour ce tableau.
137 assert(dimensions_[i] >= 0);
138 assert(i == 0 || dimensions_[i] < std::numeric_limits<int>::max());
139 return dimensions_[i];
140}
141
142/*! In 64 bits, dimensions higher than 1 can always safely be casted down to an int, only the first dimension might be big.
143* To help with this, this method can be used. One can write:
144* int d1 = toto.dimension_int(1);
145* which is cleaner than doing a wild cast like
146* int d1 = (int)toto.dimension(1);
147* and it will also check for potential overflow (with an assert).
148* This type of pattern is used in the 64b part of the code (before Scatter) when retrieving higher dimensions of arrays.
149* See arch.h.in for more explanations on 64b.
150*/
151template<typename _TYPE_, typename _SIZE_>
153{
154 assert(i > 0);
155 return static_cast<int>(dimension(i)); // overflow check down above
156}
157
158// Returns the total dimensions of the multi-dimensionnal array, including virtual items (used in parallel distributed arrays)
159template<typename _TYPE_, typename _SIZE_>
161{
162 assert(i >= 0 && i < this->nb_dim_);
163 return (i == 0) ? dimension_tot_0_ : dimensions_[i];
164}
165
166/*!
167 * See doc in TRUSTArray. This one also deals with multi-dim.
168 */
169template<typename _TYPE_, typename _SIZE_>
171{
172 // Manage multi-dim structure - I could not copy members directly because TRUSTTab<tid,tid>
173 // can't see internals of TRUSTTab<int,int> and I could not get the 'friend' clause to work there ...
174 ArrOfInt sizes;
175 sizes.resize_array(this->nb_dim_);
176 for (int i = 0; i < this->nb_dim_; i++)
177 {
178 assert(dimensions_[i] < std::numeric_limits<int>::max());
179 sizes[i] = (int)dimensions_[i];
180 }
181 out.resize(sizes);
182
183 // Do the job as if a vect:
185}
186
187template<typename _TYPE_, typename _SIZE_>
190 out.nb_dim_ = this->nb_dim_;
191 out.dimension_tot_0_ = dimension_tot_0_;
192 for(int d=0; d<out.nb_dim_; d++)
193 out.dimensions_[d] = dimensions_[d];
195}
197template<typename _TYPE_, typename _SIZE_>
199{
200 out.nb_dim_ = this->nb_dim_;
201 if(dimension_tot_0_ > std::numeric_limits<int>::max() || dimensions_[0] > std::numeric_limits<int>::max())
202 Process::exit("TRUSTTab<_TYPE_,_SIZE_>::ref_as_small() - initial array is too big to be referenced as 32b-long array!");
203 out.dimension_tot_0_ = static_cast<int>(dimension_tot_0_);
204 for(int d=0; d<out.nb_dim_; d++)
205 out.dimensions_[d] = static_cast<int>(dimensions_[d]);
207}
208
210// Adds 1 to dimension_tot(0) and puts a in the added line.
211// Precondition: line_size() must be equal to 1 and the array must be resizable.
212template<typename _TYPE_, typename _SIZE_>
214{
215 this->ensureDataOnHost();
216 assert( (TRUSTVect<_TYPE_,_SIZE_>::line_size() == 1) );
218 const _SIZE_ n = dimension_tot_0_;
219 dimensions_[0] = ++dimension_tot_0_;
220 TRUSTVect<_TYPE_,_SIZE_>::resize_vect_(n+1, RESIZE_OPTIONS::COPY_NOINIT);
221 _TYPE_ * ptr = TRUSTVect<_TYPE_,_SIZE_>::addr() + n;
222 ptr[0] = a;
225// Adds 1 to dimension_tot(0) and puts a and b in the added line.
226// Precondition: line_size() must be equal to 2 and the array must be resizable.
227template<typename _TYPE_, typename _SIZE_>
228inline void TRUSTTab<_TYPE_,_SIZE_>::append_line(_TYPE_ a, _TYPE_ b)
229{
230 this->ensureDataOnHost();
231 assert( (TRUSTVect<_TYPE_,_SIZE_>::line_size() == 2) );
233 const _SIZE_ n = dimension_tot_0_ * 2;
234 dimensions_[0] = ++dimension_tot_0_;
235 TRUSTVect<_TYPE_,_SIZE_>::resize_vect_(n+2, RESIZE_OPTIONS::COPY_NOINIT);
236 _TYPE_ * ptr = TRUSTVect<_TYPE_,_SIZE_>::addr() + n;
237 ptr[0] = a;
238 ptr[1] = b;
241// Like append_line(i,j), but for arrays with line_size()==3
242template<typename _TYPE_, typename _SIZE_>
243inline void TRUSTTab<_TYPE_,_SIZE_>::append_line(_TYPE_ a, _TYPE_ b, _TYPE_ c)
248 const _SIZE_ n = dimension_tot_0_ * 3;
249 dimensions_[0] = ++dimension_tot_0_;
250 TRUSTVect<_TYPE_,_SIZE_>::resize_vect_(n+3, RESIZE_OPTIONS::COPY_NOINIT);
251 _TYPE_ * ptr = TRUSTVect<_TYPE_,_SIZE_>::addr() + n;
252 ptr[0] = a;
253 ptr[1] = b;
254 ptr[2] = c;
255}
256
257// Like append_line(i,j), but for arrays with line_size()==4
258template<typename _TYPE_, typename _SIZE_>
259inline void TRUSTTab<_TYPE_,_SIZE_>::append_line(_TYPE_ a, _TYPE_ b, _TYPE_ c, _TYPE_ d)
260{
261 this->ensureDataOnHost();
262 assert( (TRUSTVect<_TYPE_,_SIZE_>::line_size() == 4) );
264 const _SIZE_ n = dimension_tot_0_ * 4;
265 dimensions_[0] = ++dimension_tot_0_;
266 TRUSTVect<_TYPE_,_SIZE_>::resize_vect_(n+4, RESIZE_OPTIONS::COPY_NOINIT);
267 _TYPE_ * ptr = TRUSTVect<_TYPE_,_SIZE_>::addr() + n;
268 ptr[0] = a;
269 ptr[1] = b;
270 ptr[2] = c;
271 ptr[3] = d;
272}
273
274// fait pointer le tableau sur le vecteur v et en associant la meme structure parallele.
275// Attention, si line_size du vecteur v est different de 1, on cree un tableau bidimensionnel (on peut avoir un vecteur
276// de ce type si on copie un Tab dans un Vect puis on prend une ref sur ce Vect).
277// Precondition: le vecteur v doit vraiment etre de type Vect ! (sinon utiliser DoubleTab::ref(const DoubleTab &)
278template<typename _TYPE_, typename _SIZE_>
280{
281 assert(std::string(typeid(v).name()).find("TRUSTVect") != std::string::npos);
283 const int l = v.line_size();
284 // Attention: En prenant la ref, on est oblige de conserver l'attribut line_size du Vect (sinon echange_espace_virtuel ne fonctionnera pas car
285 // on n'aura pas le bon facteur multiplicatif des items geometriques). Si on voulait creer un tableau monodimensionnel avec line_size > 1,
286 // le tableau devient invalide car on n'a plus line_size = produit des dimensions > 1.
287 // On peut le faire a condition de laisser tomber le md_vector_ en faisant tab.ref_array(v) au lieu de tab.ref(v)
288 if (l == 1) this->nb_dim_ = 1;
289 else
290 {
291 this->nb_dim_ = 2;
292 dimensions_[1] = l;
293 }
294
295 if (v.size_reelle_ok())
296 {
297 _SIZE_ sz = v.size_reelle();
298 dimensions_[0] = sz / l;
299 }
300 else dimensions_[0] = -1;
301
302 dimension_tot_0_ = TRUSTVect<_TYPE_,_SIZE_>::size_array() / l;
303 assert(verifie_LINE_SIZE());
304}
305
306// fait pointer le tableau sur le tableau t en recuperant la structure parallele. Attention, on fige le tableau qui ne pourra plus etre resize
307template<typename _TYPE_, typename _SIZE_>
309{
311 this->nb_dim_ = src.nb_dim_;
312 for (int i = 0; i < MAXDIM_TAB; i++) dimensions_[i] = src.dimensions_[i];
313 dimension_tot_0_ = src.dimension_tot_0_;
314 assert(verifie_LINE_SIZE());
315}
316
317// identique a DoubleVect::ref_data()
318template<typename _TYPE_, typename _SIZE_>
319inline void TRUSTTab<_TYPE_,_SIZE_>::ref_data(_TYPE_* ptr, _SIZE_ new_size)
320{
322 if (new_size<0) new_size=-new_size;
324 this->nb_dim_ = 1;
325 dimensions_[0] = dimension_tot_0_ = new_size;
326 assert(verifie_LINE_SIZE());
327}
328
329// identique a TRUSTVect::ref_array() (cree un tableau monodimensionnel sans structure parallele)
330// Attention, le tableau source et destination sont figes (resize interdit)
331template<typename _TYPE_, typename _SIZE_>
332inline void TRUSTTab<_TYPE_,_SIZE_>::ref_array(TRUSTArray<_TYPE_,_SIZE_>& src, _SIZE_ start, _SIZE_ sz)
333{
336 this->nb_dim_ = 1;
337 dimensions_[0] = dimension_tot_0_ = TRUSTVect<_TYPE_,_SIZE_>::size_array(); // pas sz qui peut valoir -1
338 assert(verifie_LINE_SIZE());
339}
340
341// fait pointer le tableau sur une sous-partie du tableau t definie par la valeur du premier indice et ne nombre de "lignes" du tableau
342// a recuperer (une ligne = toutes les valeurs tab(i,j,k,...) pour un i donne). Le nombre de dimensions du tableau est le meme que pour t,
343// les dimension(i) pour i>=1 sont les memes et dimension(0) = nb_lines.
344template<typename _TYPE_, typename _SIZE_>
345inline void TRUSTTab<_TYPE_,_SIZE_>::ref_tab(TRUSTTab& t, _SIZE_ start_line, _SIZE_ nb_lines)
346{
347 if (nb_lines < 0) nb_lines = t.dimension_tot_0_ - start_line;
348 assert(start_line >= 0 && nb_lines >= 0 && start_line + nb_lines <= t.dimension_tot_0_);
349 const int l_size = t.line_size();
350 TRUSTVect<_TYPE_,_SIZE_>::ref_array(t, start_line * l_size, nb_lines * l_size);
353 this->nb_dim_ = t.nb_dim_;
354 dimension_tot_0_ = nb_lines;
355 dimensions_[0] = nb_lines;
356 for (int i = 1; i < MAXDIM_TAB; i++) dimensions_[i] = t.dimensions_[i];
357 assert(verifie_LINE_SIZE());
358}
359
360// met le tableau dans l'etat obtenu par le constructeur par defaut
361template<typename _TYPE_, typename _SIZE_>
363{
364 this->nb_dim_ = 1;
365 dimensions_[0] = 0;
366 dimension_tot_0_ = 0;
368 assert(verifie_LINE_SIZE());
369}
370
371// methode virtuelle qui force le tableau a changer de taille. Change aussi this->nb_dim_ a 1. Equivalent a TRUSTTab::resize(n, opt)
372template<typename _TYPE_, typename _SIZE_>
373inline void TRUSTTab<_TYPE_,_SIZE_>::resize_tab(_SIZE_ n, RESIZE_OPTIONS opt)
374{
375 resize(n, opt);
376 assert(verifie_LINE_SIZE());
377}
378
379// redimensionne les dimensions d'un tableau tout en gardant le meme espace memoire.
380template<typename _TYPE_, typename _SIZE_>
381inline void TRUSTTab<_TYPE_,_SIZE_>::reshape(_SIZE_ n1, int n2)
382{
384 assert(n1 >= 0 && n2 >= 0);
385 assert( (TRUSTVect<_TYPE_,_SIZE_>::size_array() == n1*n2) );
386
388
389 init_dimensions(dimensions_);
390
391 dimensions_[0] = dimension_tot_0_ = n1;
392 dimensions_[1] = n2;
393
394 this->nb_dim_ = 2;
395
396 assert(verifie_LINE_SIZE());
397}
398
399template<typename _TYPE_, typename _SIZE_>
400inline void TRUSTTab<_TYPE_,_SIZE_>::reshape(_SIZE_ n1, int n2, int n3)
401{
403 assert(n1 >= 0 && n2 >= 0 && n3 >= 0);
404 assert( (TRUSTVect<_TYPE_,_SIZE_>::size_array() == n1*n2*n3) );
405
407
408 init_dimensions(dimensions_);
409
410 dimensions_[0] = dimension_tot_0_ = n1;
411 dimensions_[1] = n2;
412 dimensions_[2] = n3;
413
414 this->nb_dim_ = 3;
415
416 assert(verifie_LINE_SIZE());
417}
418
419template<typename _TYPE_, typename _SIZE_>
420inline void TRUSTTab<_TYPE_,_SIZE_>::reshape(_SIZE_ n1, int n2, int n3, int n4)
421{
423 assert(n1 >= 0 && n2 >= 0 && n3 >= 0 && n4 >= 0);
424 assert( (TRUSTVect<_TYPE_,_SIZE_>::size_array() == n1*n2*n3*n4) );
425
427
428 init_dimensions(dimensions_);
429
430 dimensions_[0] = dimension_tot_0_ = n1;
431 dimensions_[1] = n2;
432 dimensions_[2] = n3;
433 dimensions_[3] = n4;
434
435 this->nb_dim_ = 4;
436
437 assert(verifie_LINE_SIZE());
438}
439
440template<typename _TYPE_, typename _SIZE_>
442{
443 // Non-destructive reinterpretation of a scalar tab so downstream code always sees (n,1)
444 if (this->nb_dim_ == 2 && dimensions_[1] == 1) return;
445
446 assert(this->nb_dim_ == 1);
448
449 this->nb_dim_ = 2;
450 dimensions_[1] = 1;
451
452 assert(verifie_LINE_SIZE());
453}
454
455
456// change la dimension[0] du tableau en conservant les autres.
457// Precondition: le tableau ne doit pas avoir de structure parallele
458template<typename _TYPE_, typename _SIZE_>
459inline void TRUSTTab<_TYPE_,_SIZE_>::resize_dim0(_SIZE_ n, RESIZE_OPTIONS opt)
460{
461 assert(n >= 0);
464 dimensions_[0] = dimension_tot_0_ = n;
465 assert(verifie_LINE_SIZE());
466}
467
468template<typename _TYPE_, typename _SIZE_>
469inline void TRUSTTab<_TYPE_,_SIZE_>::resize(_SIZE_ n, RESIZE_OPTIONS opt)
470{
471 assert(n >= 0);
474 this->nb_dim_ = 1;
475 dimensions_[0] = dimension_tot_0_ = n;
476 assert(verifie_LINE_SIZE());
477}
478
479template<typename _TYPE_, typename _SIZE_>
480inline void TRUSTTab<_TYPE_,_SIZE_>::resize(_SIZE_ n, int n2, RESIZE_OPTIONS opt)
481{
482 assert(n >= 0 && n2 >= 0);
484 _SIZE_ new_size = n * n2;
485
486 if (std::is_same<_TYPE_,int>::value && new_size < 0)
487 {
488 Cerr << "n1*n2 > 2^31. Error! Contact TRUST support, integer 32 bits limit exceeded with n1=" << n << " and n2=" << n2 << finl;
490 }
491
493 this->nb_dim_ = 2;
494 dimensions_[0] = dimension_tot_0_ = n;
495 dimensions_[1] = n2;
496 assert(verifie_LINE_SIZE());
497}
498
499template<typename _TYPE_, typename _SIZE_>
500inline void TRUSTTab<_TYPE_,_SIZE_>::resize(_SIZE_ n, int n2, int n3, RESIZE_OPTIONS opt)
501{
502 assert(n >= 0 && n2 >= 0 && n3 >= 0);
504 _SIZE_ new_size = n * n2 * n3;
505
506 if (std::is_same<_TYPE_,int>::value && new_size < 0)
507 {
508 Cerr << "n1*n2*n3 > 2^31. Error! Contact TRUST support, integer 32 bits limit exceeded with n1=" << n << " and n2=" << n2 << " and n3=" << n3 << finl;
510 }
511
513 this->nb_dim_ = 3;
514 dimensions_[0] = dimension_tot_0_ = n;
515 dimensions_[1] = n2;
516 dimensions_[2] = n3;
517 assert(verifie_LINE_SIZE());
518}
519
520template<typename _TYPE_, typename _SIZE_>
521inline void TRUSTTab<_TYPE_,_SIZE_>::resize(_SIZE_ n, int n2, int n3, int n4, RESIZE_OPTIONS opt)
522{
523 assert(n >= 0 && n2 >= 0 && n3 >= 0 && n4 >= 0);
525 _SIZE_ new_size = n * n2 * n3 * n4;
526
527 if (std::is_same<_TYPE_,int>::value && new_size<0)
528 {
529 Cerr << "n1*n2*n3*n4 > 2^31. Error! Contact TRUST support, integer 32 bits limit exceeded with n1=" << n << " and n2=" << n2 << " and n3=" << n3 << " and n4=" << n4 << finl;
531 }
532
534 this->nb_dim_ = 4;
535 dimensions_[0] = dimension_tot_0_ = n;
536 dimensions_[1] = n2;
537 dimensions_[2] = n3;
538 dimensions_[3] = n4;
539 assert(verifie_LINE_SIZE());
540}
541
542// redimensionne le tableau (this->nb_dim_ sera egal a tailles.size_array() et dimension(i) a tailles[i].
543// Precondition: identiques a TRUSTVect::resize_vect_()
544template<typename _TYPE_, typename _SIZE_>
545inline void TRUSTTab<_TYPE_,_SIZE_>::resize(const TRUSTArray<_SIZE_, int>& tailles, RESIZE_OPTIONS opt)
546{
547 this->nb_dim_ = tailles.size_array();
548 if (this->nb_dim_ <= 0 || this->nb_dim_ > MAXDIM_TAB)
549 {
550 Cerr << "Internal error in TRUSTTab::resize(const ArrOfInt & tailles, ...) \n" << " wrong dimensions number " << this->nb_dim_ << finl;
552 }
553 int l_size = 1;
554 for (int i = 0; i < this->nb_dim_; i++)
555 {
556 const _SIZE_ n = tailles[i];
557 dimensions_[i] = n;
558 if (i > 0)
559 l_size *= (int)n; // Assume higher dim (>=1) are always small
560 if (n < 0)
561 {
562 Cerr << "Internal error in TRUSTTab::resize(const ArrOfInt & tailles, ...) \n";
563#ifndef LATATOOLS
564 Cerr << " wrong dimensions: " << tailles << finl;
565#endif
567 }
568 }
569 dimension_tot_0_ = dimensions_[0];
571 TRUSTVect<_TYPE_,_SIZE_>::resize_vect_(dimensions_[0] * l_size, opt);
572 assert(verifie_LINE_SIZE());
573}
574
575// copie la structure et les valeurs du tableau src
576// Restrictions et preconditions identiques a TRUSTVect::operator=(const TRUSTVect & v)
577template<typename _TYPE_, typename _SIZE_>
579{
580 copy(src);
581 return *this;
582}
583
584// copie la structure et les valeurs de src. Attention: appel invalide si src est un type derive de Vect
585// (sinon quoi faire, un tableau unidimensionnel, ou une copie de la structure ?)
586template<typename _TYPE_, typename _SIZE_>
588{
589 assert(std::string(typeid(src).name()).find("TRUSTVect") != std::string::npos);
591
592 // Idem que dans ref(TRUSTVect<_TYPE_,_SIZE_>) pour le nombre de dimensions du tableau cree
593 const int l = src.line_size();
594 if (l == 1) this->nb_dim_ = 1;
595 else
596 {
597 this->nb_dim_ = 2;
598 dimensions_[1] = l;
599 }
600
601 if (src.size_reelle_ok())
602 {
603 _SIZE_ sz = src.size_reelle();
604 dimensions_[0] = sz / l;
605 assert(sz % l == 0);
606 }
607 else dimensions_[0] = -1;
608
609 dimension_tot_0_ = TRUSTVect<_TYPE_,_SIZE_>::size_array() / l;
610 assert(verifie_LINE_SIZE());
611 return *this;
612}
613
614template<typename _TYPE_, typename _SIZE_>
620
621template<typename _TYPE_, typename _SIZE_>
622inline void TRUSTTab<_TYPE_,_SIZE_>::copy(const TRUSTTab& src, RESIZE_OPTIONS opt)
623{
624 if (&src != this)
625 {
627 this->nb_dim_ = src.nb_dim_;
628 for (int i = 0; i < MAXDIM_TAB; i++) dimensions_[i] = src.dimensions_[i];
629 dimension_tot_0_ = src.dimension_tot_0_;
630 assert(verifie_LINE_SIZE());
631 }
632}
633
634template<typename _TYPE_, typename _SIZE_>
636{
637 assert(indice.size_array() == this->nb_dim_);
638 verifie_MAXDIM_TAB();
639 switch(this->nb_dim_)
640 {
641 case 1:
642 return operator()(indice[0]);
643 case 2:
644 return operator()(indice[0], indice[1]);
645 case 3:
646 return operator()(indice[0], indice[1], indice[2]);
647 default:
648 return operator()(indice[0], indice[1], indice[2], indice[3]);
649 }
650}
651
652template<typename _TYPE_, typename _SIZE_>
654{
655 assert(indice.size_array() == this->nb_dim_);
656 verifie_MAXDIM_TAB();
657 switch(this->nb_dim_)
658 {
659 case 1:
660 return operator()(indice[0]);
661 case 2:
662 return operator()(indice[0], indice[1]);
663 case 3:
664 return operator()(indice[0], indice[1], indice[2]);
665 default:
666 return operator()(indice[0], indice[1], indice[2], indice[3]);
667 }
668}
669
670// associe le md_vector au vecteur (voir TRUSTVect::set_md_vector()) dimension(0) sera initialise a md_vector...get_nb_items_reels().
671// Precondition: en plus des preconditions de TRUSTVect::set_md_vector(), dimension_tot(0) doit etre egal a get_nb_items_tot() du md_vector.
672template<typename _TYPE_, typename _SIZE_>
674{
675#ifndef LATATOOLS
676 _SIZE_ dim0 = dimension_tot_0_;
677 if (md_vector.non_nul())
678 // renvoie -1 si l'appel est invalide ou si le MD_Vector est mix (cf doc MD_Vector_base):
679 dim0 = md_vector->get_nb_items_reels();
680 dimensions_[0] = dim0;
681 assert(verifie_LINE_SIZE());
682 // a appeler meme pour un md_vector nul (pour remettre size_reelle_):
684#endif
685}
686
687template<typename _TYPE_, typename _SIZE_>
689{
690#ifndef LATATOOLS
691 os << this->nb_dim_ << finl;
692 if (this->nb_dim_ > 0) os.put(dimensions_, this->nb_dim_, this->nb_dim_);
694 for (int i = 0; i < this->nb_dim_; i++) tmp[i] = dimension_tot(i);
695 os << tmp;
697#endif
698}
699
700template<typename _TYPE_, typename _SIZE_>
702{
703 TRUSTTab<_TYPE_,_SIZE_>::lit(is, 0 /* Do not resize&read the array */);
704}
705
706// lecture d'un tableau pour reprise de calcul. On lit les valeurs "raw".
707// Attention, si le tableau n'est pas vide, il doit deja avoir la bonne taille et la bonne structure, sinon erreur !
708// Parameter resize_and_read if the array is sized AND read (by default, yes)
709template<typename _TYPE_, typename _SIZE_>
710inline void TRUSTTab<_TYPE_,_SIZE_>::lit(Entree& is, bool resize_and_read)
711{
712#ifndef LATATOOLS
713 TRUSTArray<_SIZE_,int> tmp; // the dim array wich is read
714 is >> tmp;
715 bool ok = (tmp.size_array() == this->nb_dim_);
716
717 if (ok)
718 {
719 if (TRUSTVect<_TYPE_,_SIZE_>::size_reelle_ok() && dimension(0) != tmp[0]) ok = 0;
720 for (int i = 1; i < this->nb_dim_; i++)
721 if (dimension(i) != tmp[i]) ok = 0;
722 }
723 is >> tmp;
724 if (ok && tmp.size_array() != this->nb_dim_) ok = 0;
725 if (ok)
726 for (int i = 0; i < this->nb_dim_; i++)
727 if (dimension_tot(i) != tmp[i]) ok = 0;
728
729 // Autorisation ancien format des champs scalaire 183:
730 if (tmp.size_array()==1 && this->nb_dim_==2 && dimension(1)==1 && dimension_tot(0) == tmp[0]) ok = 1;
731
732 if (resize_and_read)
733 {
735 resize(tmp, RESIZE_OPTIONS::NOCOPY_NOINIT);
736 else if (!ok)
737 {
738 // Si on cherche a relire un tableau de taille inconnue, le tableau doit etre reset() a l'entree. On n'aura pas la structure parallele du tableau !
739 Cerr << finl;
740 Cerr << "Error in DoubleTab::lit: array has wrong dimensions" << finl;
741 if (Process::is_parallel() && dimension(0) != tmp[0]) // Add message to detect different partitionning
742 {
743 Cerr << "We try to read an array with " << dimension(0) << " items whereas we are waiting for a size of " << tmp[0] << "!" << finl;
744 Cerr << "Probably a different partitionning from your previous calculation..." << finl;
745 Cerr << "Change your current partitionning to match the previous calculation or try .xyz restart protocol." << finl;
746 }
748 }
749 }
750 TRUSTVect<_TYPE_,_SIZE_>::lit(is,resize_and_read);
751#endif
752}
753
754// ------------------------------------------------------
755// Juste pour double/float
756
757// Quelqu'un veut-il expliquer ce que fait cette methode ?
758template<typename _TYPE_, typename _SIZE_>
759template <typename _T_>
761{
762 this->ensureDataOnHost();
765 // Tableaux vus comme des tableaux unidimensionnels (pour ne pas avoir a gerer nb_dim)
766 const TRUSTVect<_T_,_SIZE_>& vx = x, &vy = y;
767 TRUSTVect<_T_,_SIZE_>& v = *this;
768
769 const int line_size_x = vx.line_size(), line_size_y = vy.line_size(), line_size_xy = v.line_size();
770 assert(line_size_xy == line_size_x * line_size_y);
771 // Pour ne pas diviser par line_size()
772 assert(vx.size_totale() * line_size_xy == v.size_totale() * line_size_x);
773 assert(vy.size_totale() * line_size_xy == v.size_totale() * line_size_y);
774
775 // Logic similar to what is done in TRUSTVect_Tools.cpp, with ::determine_blocks()
776 Block_Iter<_SIZE_> bloc_itr; // By default, nothing in the iterator
777 int nblocs_left = 0;
778 if (v.get_md_vector().non_nul() && v.get_md_vector()->use_blocks())
779 {
780 const ArrOfInt& items_blocs = v.get_md_vector()->get_blocs_items_to_compute();
781 assert(items_blocs.size_array() % 2 == 0);
782 nblocs_left = items_blocs.size_array() >> 1;
783 bloc_itr = Block_Iter<_SIZE_>(items_blocs);
784 }
785 else
786 {
787 if (v.size_totale() > 0)
788 {
789 nblocs_left = 1;
790 bloc_itr = Block_Iter<_SIZE_>(0, v.size_totale() / v.line_size()); // iterator on a single (big) block
791 }
792 }
793
794 for (; nblocs_left; nblocs_left--)
795 {
796 const _SIZE_ debut = (*(bloc_itr++)), fin = (*(bloc_itr++));
797 _SIZE_ v_index = debut * line_size_xy;
798 for (_SIZE_ i = debut; i < fin; i++)
799 for (_SIZE_ j = 0; j < line_size_x; j++)
800 {
801 _T_ xval = vx[i * line_size_x + j];
802 for (_SIZE_ k = 0; k < line_size_y; k++)
803 {
804 _T_ yval = vy[i * line_size_y + k];
805 v[v_index] += alpha * xval * yval;
806 v_index++;
807 }
808 }
809 }
810}
811
812// Resolution du systeme Ax=b
813template<typename _TYPE_, typename _SIZE_>
814template <typename _T_>
816{
818 solution.ensureDataOnHost();
819 _SIZE_ n = b.size_array();
820 TRUSTArray<int,_SIZE_> index(n);
821 TRUSTTab<_T_,_SIZE_> lu_dec(n,n);
822 bool cvg = (*this).decomp_LU(n,index,lu_dec);
823
824 if(cvg) lu_dec.resoud_LU(n,index,b,solution);
825
826 return cvg;
827}
828
829// Decomposition d'une matrice en L.U: methode de Crout (diagonale de L =1)
830// Retour: matrice A_ = assemblage (L-diagonale)+U
831template<typename _TYPE_, typename _SIZE_>
832template <typename _T_>
834{
836 _SIZE_ i, j, k, imax = -1, cvg = 1;
837 _T_ big, dum, sum, temp;
838 matLU = (*this);
839
840 //Recupere le coeff max d'une ligne, stocke dans vv
841 for (i=0 ; i<n ; i++)
842 {
843 big = 0;
844 for (j=0 ; j<n ; j++)
845 if ((temp = std::fabs(matLU(i,j))) > big) big = temp;
846
847 if (big == 0)
848 {
849 Cerr <<"Singular matrix in LU decomposition"<<finl;
850 cvg = 0;
852 }
853 vv[i] = 1./big;
854 }
855
856 //calcul de la matrice matLU
857 for (j=0 ; j<n ; j++)
858 {
859 for (i=0 ; i<j ; i++)
860 {
861 sum = matLU(i,j);
862 for (k=0 ; k<i ; k++) sum -= matLU(i,k) * matLU(k,j);
863 matLU(i,j) = sum;
864 }
865
866 big = 0;
867 for (i=j ; i<n ; i++)
868 {
869 sum = matLU(i,j);
870 for (k=0 ; k<j ; k++) sum -= matLU(i,k) * matLU(k,j);
871 matLU(i,j) = sum;
872 if ((dum = vv[i]*std::fabs(sum)) >= big)
873 {
874 big = dum;
875 imax = i;
876 }
877 }
878
879 if (j != imax)
880 {
881 for (k=0 ; k<n ; k++)
882 {
883 dum = matLU(imax,k);
884 matLU(imax,k) = matLU(j,k);
885 matLU(j,k) = dum;
886 }
887 vv[imax] = vv[j];
888 }
889
890 index[j] = imax;
891 dum = 1./matLU(j,j);
892 for (i=j+1 ; i<n ; i++) matLU(i,j) *= dum;
893 }
894 return cvg;
895}
896
897// Resolution du systeme A_x=b : A_ contenant le decompostion LU de A (stockee dans une seule matrice)
898template<typename _TYPE_, typename _SIZE_>
899template <typename _T_>
901{
902 _SIZE_ i,ii=-1,ip,j;
903 _T_ sum;
904 solution = b;
905 for (i=0 ; i<n ; i++)
906 {
907 ip = index[i];
908 sum = solution[ip];
909 solution[ip] = solution[i];
910 if (ii!=-1)
911 for (j=ii ; j<i ; j++) sum -= (*this)(i,j)*solution[j];
912 else if (sum) ii =i;
913
914 solution[i] = sum;
915 }
916
917 for (i=n-1 ; i>=0 ; i--)
918 {
919 sum = solution[i];
920 for (j=i+1 ; j<n ; j++) sum -= (*this)(i,j)*solution[j];
921 solution[i] = sum/(*this)(i,i);
922 }
923}
924
925// Fonction utilisee pour le calcul du du/u (pour convergence implicite)
926// renvoie le max de abs(du(i)/u(i)). utilisation max_ = (u(n+1)-u(n)).max_du_u(u(n))
927template<typename _TYPE_, typename _SIZE_>
928template <typename _T_>
930{
933 const _T_ *du_ptr = TRUSTVect<_TYPE_,_SIZE_>::addr();
934 const _T_ *u_ptr = u.addr();
935 const _T_ epsilon = 1.e-8;
936 _T_ res = 0.;
937 for (_SIZE_ n = TRUSTVect<_TYPE_,_SIZE_>::size_array(); n; n--)
938 {
939 _T_ a = std::fabs(*du_ptr), b = std::fabs(*u_ptr), c = a / (b + epsilon);
940 if (b > 1.e-2 && c > res) res = c;
941 du_ptr++;
942 u_ptr++;
943 }
944 return res;
945}
946
947#endif /* TRUSTTab_TPP_included */
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual bool use_blocks() const =0
virtual int get_nb_items_reels() const
virtual const ArrOfInt & get_blocs_items_to_compute() const =0
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
int non_nul() const
Definition MD_Vector.h:56
static int dimension
Definition Objet_U.h:99
static bool is_parallel()
Definition Process.cpp:110
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 int put(const unsigned *ob, std::streamsize n, std::streamsize nb_colonnes=1)
Definition Sortie.cpp:101
_SIZE_ size_array() const
_TYPE_ * addr()
_TYPE_ & operator[](_SIZE_ i)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
friend class TRUSTArray
Definition TRUSTArray.h:108
void jump(Entree &) override
Definition TRUSTTab.tpp:701
void ref_as_big(TRUSTTab< _TYPE_, trustIdType > &out) const
Definition TRUSTTab.tpp:188
virtual void ref(const TRUSTTab &)
Definition TRUSTTab.tpp:308
void set_md_vector(const MD_Vector &) override
Definition TRUSTTab.tpp:673
void resoud_LU(_SIZE_, TRUSTArray< int, _SIZE_ > &, const TRUSTArray< _T_, _SIZE_ > &, TRUSTArray< _T_, _SIZE_ > &)
Definition TRUSTTab.tpp:900
int dimension_int(int d) const
Definition TRUSTTab.tpp:152
void ref_array(TRUSTArray< _TYPE_, _SIZE_ > &, _SIZE_ start=0, _SIZE_ sz=-1) override
Definition TRUSTTab.tpp:332
void ref_data(_TYPE_ *ptr, _SIZE_ size) override
Definition TRUSTTab.tpp:319
void promote_scalar_to_dim2()
Definition TRUSTTab.tpp:441
void lit(Entree &, bool resize_and_read=true) override
Definition TRUSTTab.tpp:710
void ref_as_small(TRUSTTab< _TYPE_, int > &out) const
Definition TRUSTTab.tpp:198
void reshape(_SIZE_ n1, int n2)
Definition TRUSTTab.tpp:381
friend class TRUSTTab
Definition TRUSTTab.h:112
void reset() override
Definition TRUSTTab.tpp:362
_TYPE_ & operator[](_SIZE_ i)
Definition TRUSTTab.tpp:23
_TYPE_ & operator()(const TRUSTArray< _SIZE_, int > &indice)
Definition TRUSTTab.tpp:635
virtual void ref_tab(TRUSTTab &, _SIZE_ start_line=0, _SIZE_ nb_lines=-1)
Definition TRUSTTab.tpp:345
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
void ecrit(Sortie &) const override
Definition TRUSTTab.tpp:688
bool decomp_LU(_SIZE_, TRUSTArray< int, _SIZE_ > &, TRUSTTab< _T_, _SIZE_ > &)
Definition TRUSTTab.tpp:833
void ajoute_produit_tensoriel(_T_ alpha, const TRUSTTab< _T_, _SIZE_ > &, const TRUSTTab< _T_, _SIZE_ > &)
Definition TRUSTTab.tpp:760
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
void resize_dim0(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:459
_T_ max_du_u(const TRUSTTab< _T_, _SIZE_ > &)
Definition TRUSTTab.tpp:929
bool inverse_LU(const TRUSTArray< _T_, _SIZE_ > &, TRUSTArray< _T_, _SIZE_ > &)
Definition TRUSTTab.tpp:815
void copy(const TRUSTTab &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:622
void from_tid_to_int(TRUSTTab< int, int > &out) const
Definition TRUSTTab.tpp:170
void append_line(_TYPE_)
Definition TRUSTTab.tpp:213
void resize_tab(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) override
Definition TRUSTTab.tpp:373
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
TRUSTTab & operator=(const TRUSTTab &)
Definition TRUSTTab.tpp:578
void ref_as_small(TRUSTVect< _TYPE_, int > &out) const
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61
int line_size() const
Definition TRUSTVect.tpp:67
TRUSTVect & operator=(const TRUSTVect &)
virtual void lit(Entree &, bool resize_and_read=1)
void ref_as_big(TRUSTVect< _TYPE_, trustIdType > &out) const
void copy_(const TRUSTVect &v, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
virtual void set_md_vector(const MD_Vector &)
_SIZE_ size_reelle() const
Definition TRUSTVect.tpp:27
_SIZE_ size_reelle_ok() const
Definition TRUSTVect.tpp:38
void from_tid_to_int(TRUSTVect< int, int > &out) const
void ref_array(TRUSTArray< _TYPE_, _SIZE_ > &, _SIZE_ start=0, _SIZE_ sz=-1) override
void resize_vect_(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
virtual void ecrit(Sortie &) const
void reset() override
met l'objet dans l'etat obtenu par le constructeur par defaut.
Definition TRUSTVect.h:189
void set_line_size_(int n)
Definition TRUSTVect.tpp:78
void ref_data(_TYPE_ *ptr, _SIZE_ new_size) override
friend class TRUSTVect
Definition TRUSTVect.h:78
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
virtual void ref(const TRUSTVect &)