TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
TRUSTArray.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 TRUSTArray_TPP_included
17#define TRUSTArray_TPP_included
18
19#include <string.h>
20#include <algorithm>
21#include <TRUSTTravPool.h>
22
23
24/*! Destroy array, potentially making block available again if this was a Trav
25 */
26template <typename _TYPE_, typename _SIZE_>
28{
29 detach_array(); // release all resources properly (esp. Trav!!)
30}
31
32/**
33 * Change the size of the array.
34 *
35 * This updates the underlying std::vector size.
36 *
37 * Conditions:
38 * - if the size changes, type must not be a derived class of TRUSTArray.
39 * - the array can not be resized if data is shared (ref_array)
40 * - the array can not be resized if it is a 'ref_data'.
41 */
42template <typename _TYPE_, typename _SIZE_>
43inline void TRUSTArray<_TYPE_, _SIZE_>::resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt)
44{
45 // Si le tableau change de taille, il doit etre du type TRUSTArray
46 assert( ( mem_ == nullptr || (int)mem_->size() == new_size ) ||
47 std::string(typeid(*this).name()).find("TRUSTArray") != std::string::npos );
48 // ref_arrays can not be resized, except if they keep the same size
49 assert( size_array() == new_size || ref_count() <= 1 );
50 // ref_data can not be resized:
51 assert( span_.empty() || mem_ != nullptr );
52 resize_array_(new_size, opt);
53}
54
55/** Methode virtuelle (dans Array_base) identique a resize_array(), permet de traiter
56 * de facon generique les ArrOf, Vect et Tab. Si l'objet est de type TRUSTArray, appel a resize_array(n)
57 *
58 * Prerequis: le tableau doit etre "resizable" (voir resize_array()). S'il est d'un type derive (Vect ou Tab),
59 * il ne doit pas avoir de descripteur parallele si la taille est effectivement modifiee.
60 */
61template <typename _TYPE_, typename _SIZE_>
62inline void TRUSTArray<_TYPE_, _SIZE_>::resize_tab(_SIZE_ n, RESIZE_OPTIONS opt)
63{
64 resize_array(n, opt);
65}
66
67// Change le mode d'allocation memoire lors des resize (voir VTRUSTdata et TRUST_ptr_trav)
68// Exemple pour creer un tableau avec allocation temporaire:
69// DoubleTab tab; // Creation d'un tableau vide
70// tab.set_mem_storage(TEMP_STORAGE); // Changement de mode d'allocation
71// tab.resize(n); // Allocation memoire
72template <typename _TYPE_, typename _SIZE_>
73inline void TRUSTArray<_TYPE_, _SIZE_>::set_mem_storage(const STORAGE storage)
74{
75 storage_type_ = storage;
76}
77
78
79/** Make the array point to the memory zone indicated by data_. The array is detached from its current underlying
80 * data ('mem_' is released).
81 *
82 * Warning: virtual method. In derived classes this method initializes the structures to create a sequential array.
83 * To create a ref on a parallel array, see DoubleVect::ref()
84 */
85template <typename _TYPE_, typename _SIZE_>
86inline void TRUSTArray<_TYPE_, _SIZE_>::ref_data(_TYPE_* ptr, _SIZE_ size)
87{
88 assert(ptr != 0 || size == 0);
89 assert(size >= 0);
90 assert(storage_type_ != STORAGE::TEMP_STORAGE); // Not a Trav!
91 detach_array(); // ToDo OpenMP revenir en arriere sur TRUSTArray.h
92 span_ = Span_(ptr, size);
93 // By default, the memory is allocated only on the host:
94 data_location_ = std::make_shared<DataLocation>(DataLocation::HostOnly);
95}
96
97/** Make the current array point to the data of another existing array. Ownership of the data is hence shared.
98 *
99 * The current array is first detached (see detach_array()), and then attached to the provided data (see attach_array())
100 * Wanring: virtual -> in derived classes this method initializes structures to create a sequential array.
101 */
102template <typename _TYPE_, typename _SIZE_>
103inline void TRUSTArray<_TYPE_, _SIZE_>::ref_array(TRUSTArray& m, _SIZE_ start, _SIZE_ size)
104{
105 assert(&m != this);
106 assert(storage_type_ != STORAGE::TEMP_STORAGE); // Not a Trav!
107 detach_array();
108 attach_array(m, start, size);
109}
110
111/** Copy the data from another array, potentially resizing.
112 * The storage type is not copied.
113 */
114template <typename _TYPE_, typename _SIZE_>
117 if (&m != this)
118 {
119 const _SIZE_ new_size = m.size_array();
120 // On utilise la methode resize_array() qui teste le type derive de l'objet (resize interdit sur un type derive)
121 resize_array(new_size, RESIZE_OPTIONS::NOCOPY_NOINIT);
122 inject_array(m);
123 }
124 return *this;
125}
126
127/** operateur [] retourne le ieme element du tableau
128* Parametre: _SIZE_ i
129* Signification: indice dans l'intervalle 0 <= i < size_array()
130* Exception: assert si i n'est pas dans l'intervalle
131*/
132template<typename _TYPE_, typename _SIZE_>
134{
135#ifdef TRUST_USE_GPU
136 this->ensureDataOnHost();
137#endif
138 assert(i >= 0 && i < size_array());
139 return span_[i];
140}
141
142template<typename _TYPE_, typename _SIZE_>
143inline const _TYPE_& TRUSTArray<_TYPE_, _SIZE_>::operator[](_SIZE_ i) const
144{
145#ifdef TRUST_USE_GPU
146 this->ensureDataOnHost();
147#endif
148 assert(i >= 0 && i < size_array());
149 // [ABN] We can not perform this check here, since we might be *setting* the value from an un-initialized state.
150 // And an uninitialized state might well be completly off the bounds!
151 // assert(span_[i] > -DMAXFLOAT && span_[i] < DMAXFLOAT);
152 return span_[i];
153}
154
155/** Returns a pointer on the first element of the array. nullptr will be returned if array is detached.
156 * Careful, address might change after a resize_array(), ref_data(), etc.
157 */
158template <typename _TYPE_, typename _SIZE_>
160{
162 return span_.data();
163}
164
165template <typename _TYPE_, typename _SIZE_>
166inline const _TYPE_* TRUSTArray<_TYPE_, _SIZE_>::addr() const
167{
169 return span_.data();
171
172template <typename _TYPE_, typename _SIZE_>
174{
175 return span_.data();
176}
178template <typename _TYPE_, typename _SIZE_>
179inline const _TYPE_ *TRUSTArray<_TYPE_, _SIZE_>::data() const
180{
181 return span_.data();
182}
183
184/** Returns the size of the array.
185 */
186template <typename _TYPE_, typename _SIZE_>
188{
189 return (_SIZE_)span_.size();
190}
191
192/** Returns the number of shared owners of the data underlying the array. If -1 detached array.
193 * This is simply the ref count of the shared pointer 'mem_'
194 */
195template <typename _TYPE_, typename _SIZE_>
197{
198 return mem_ ? (int)mem_.use_count() : -1;
199}
200
201#ifdef TRUST_GTEST
202template <typename _TYPE_, typename _SIZE_>
203inline int TRUSTArray<_TYPE_, _SIZE_>::nb_dim() const
204{
205 return this->nb_dim_;
206}
207#endif
208
209/** Ajoute une case en fin de tableau et y stocke la "valeur"
210 * Precondition:
211 * Le tableau ne doit pas etre "ref_data",
212 * et il ne doit pas y avoir plus d'une reference a la zone de memoire pointee (meme precondition que resize_array())
213 * Le tableau doit etre de type TRUSTArray (pas un type derive)
214 */
215template <typename _TYPE_, typename _SIZE_>
217{
218 this->ensureDataOnHost();
219 // Call the official resize, with all its checks and management of Trav:
220 const _SIZE_ sz = size_array();
221 resize_array_(sz+1, RESIZE_OPTIONS::NOCOPY_NOINIT);
222 operator[](sz) = valeur;
223}
224
225/** Tri des valeurs du tableau dans l'ordre croissant.
226 */
227template <typename _TYPE_, typename _SIZE_>
229{
231 std::sort(span_.begin(), span_.end());
232}
234/** Attach the array to (part of) an existing block of data stored in another array.
235 * The data is then shared between that other array and this.
236 *
237 * If size < 0, we take the data from the specified start till the end of the block.
238 * Array must be detached first before invoking this method.
239 * It is forbidden to attach to a ref_data.
240 */
241template <typename _TYPE_, typename _SIZE_>
242inline void TRUSTArray<_TYPE_, _SIZE_>::attach_array(const TRUSTArray& m, _SIZE_ start, _SIZE_ size)
243{
244 // Array must be detached
245 assert(span_.empty() && mem_ == nullptr);
246 // we might attach to an already detached array ... make sure that start and size are coherent
247 assert(m.mem_ != nullptr || (start == 0 && size <= 0));
248 // we don't attach to ourself:
249 assert(&m != this);
250 // we don't attach to a ref_data:
251 assert(! (m.mem_ == nullptr && !m.span_.empty()) );
252
253 if (size < 0)
254 size = m.size_array() - start;
255
256 assert(start >= 0 && size >=0 && start + size <= m.size_array());
257
258 // shared_ptr copy! One more owner for the underlying data - note we migth copy nullptr here ...
259 mem_ = m.mem_;
260
261 // Copy (shared) data location from m - locations will be synchronized automatically between ref arrays
262 data_location_ = m.data_location_;
263
264 // Copy storage type! A Tab might become a Trav ... (but not the other way around, see ref_*() methods and asserts)
265 storage_type_ = m.storage_type_;
266
267 // stupid enough, but we might have ref'ed a detached array ...
268 if (mem_ != nullptr)
269 span_ = Span_((_TYPE_ *)(m.span_.begin()+start), size);
270 else
271 span_ = Span_();
272}
273
274/** Bring the current array in a detached state, i.e. both 'mem_' and 'span_' are cleared, whatever the current state.
275*/
276template <typename _TYPE_, typename _SIZE_>
278{
279 if (mem_ != nullptr && ref_count() == 1)
280 {
281 if (storage_type_ == STORAGE::TEMP_STORAGE)
282 // Give it back to the pool of free blocks - this means a shared_ptr copy, memory will be preserved
284 else if (isAllocatedOnDevice(*this))
285 deleteOnDevice(*this); // Delete block memory on GPU
286 }
287
288 mem_ = nullptr;
289 span_ = Span_();
290 data_location_ = nullptr;
291
292 return true;
293}
294
295//From TRUSTArray.h, now also here, overidden in TRUSTTab
296template<typename _TYPE_, typename _SIZE_>
298{
299 assert(i == 0); //If Array, we never want size of index i>0
300 return size_array();
301}
302
303#endif /* TRUSTArray_TPP_included */
void attach_array(const TRUSTArray &a, _SIZE_ start=0, _SIZE_ size=-1)
void resize_array_(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
virtual void ref_array(TRUSTArray &, _SIZE_ start=0, _SIZE_ sz=-1)
_TYPE_ * addr()
virtual ~TRUSTArray()
TRUSTArray & inject_array(const TRUSTArray &source, _SIZE_ nb_elements=-1, _SIZE_ first_element_dest=0, _SIZE_ first_element_source=0)
int ref_count() const
_TYPE_ * data()
virtual void resize_tab(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void set_mem_storage(const STORAGE storage)
tcb::span< _TYPE_ > Span_
Definition TRUSTArray.h:102
bool detach_array()
_TYPE_ & operator[](_SIZE_ i)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void ordonne_array()
virtual _SIZE_ dimension_tot(int) const
TRUSTArray & operator=(const TRUSTArray &)
friend class TRUSTArray
Definition TRUSTArray.h:108
virtual void ref_data(_TYPE_ *ptr, _SIZE_ size)
static void ReleaseBlock(block_ptr_t)