Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArrayData.inst.h
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/* ArrayData.inst.h (C) 2000-2026 */
9/* */
10/* Donnée du type 'Array'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/ArrayData.h"
15
16#include "arccore/common/AlignedMemoryAllocator.h"
17
18#include "arcane/utils/NotSupportedException.h"
19#include "arcane/utils/Real2.h"
20#include "arcane/utils/Real2x2.h"
21#include "arcane/utils/Real3.h"
22#include "arcane/utils/Real3x3.h"
23#include "arcane/utils/IHashAlgorithm.h"
24#include "arcane/utils/NotImplementedException.h"
25#include "arcane/utils/IndexOutOfRangeException.h"
26#include "arcane/utils/ArgumentException.h"
27#include "arcane/utils/FatalErrorException.h"
28#include "arcane/utils/ITraceMng.h"
29#include "arcane/utils/CheckedConvert.h"
30#include "arcane/utils/MemoryAllocator.h"
32
33#include "arcane/core/datatype/DataStorageBuildInfo.h"
34#include "arcane/core/datatype/IDataOperation.h"
35
36#include "arcane/core/ISerializer.h"
37
38#include "arcane/impl/SerializedData.h"
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43namespace Arcane
44{
45namespace
46{
47 inline constexpr Int64 SERIALIZE_MAGIC_NUMBER = 0x456ff989;
48} // namespace
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53template <typename DataType> ArrayDataT<DataType>::
55: m_value(AlignedMemoryAllocator::Simd())
56, m_trace(trace)
57, m_internal(new Impl(this))
58{
59 _setShape();
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65template <typename DataType> ArrayDataT<DataType>::
66ArrayDataT(const ArrayDataT<DataType>& rhs)
67: m_value(AlignedMemoryAllocator::Simd())
68, m_trace(rhs.m_trace)
69, m_internal(new Impl(this))
70, m_shape(rhs.m_shape)
71, m_allocation_info(rhs.m_allocation_info)
72{
73 m_value = rhs.m_value.constSpan();
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79template <typename DataType> ArrayDataT<DataType>::
80ArrayDataT(const DataStorageBuildInfo& dsbi)
81: m_value(dsbi.memoryAllocator())
82, m_trace(dsbi.traceMng())
83, m_internal(new Impl(this))
84{
85 _setShape();
86}
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91template <typename DataType> ArrayDataT<DataType>::
92~ArrayDataT()
93{
94 delete m_internal;
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103template <typename DataType> DataStorageTypeInfo ArrayDataT<DataType>::
104staticStorageTypeInfo()
105{
106 typedef DataTypeTraitsT<DataType> TraitsType;
107 eBasicDataType bdt = TraitsType::basicDataType();
108 Int32 nb_basic_type = TraitsType::nbBasicType();
109 Int32 dimension = 1;
110 Int32 multi_tag = 0;
111 return DataStorageTypeInfo(bdt, nb_basic_type, dimension, multi_tag);
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117template <typename DataType> DataStorageTypeInfo ArrayDataT<DataType>::
118storageTypeInfo() const
119{
120 return staticStorageTypeInfo();
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126template <typename DataType> Ref<ISerializedData> ArrayDataT<DataType>::
127createSerializedDataRef(bool use_basic_type) const
128{
129 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
130
131 Integer nb_count = 1;
132 eDataType data_type = dataType();
133 Integer type_size = sizeof(DataType);
134
135 if (use_basic_type) {
138 type_size = sizeof(BasicType);
139 }
140
141 Int64 nb_element = m_value.largeSize();
142 Int64 nb_base_element = nb_element * nb_count;
143 Int64 full_size = nb_base_element * type_size;
144 Span<const Byte> base_values(reinterpret_cast<const Byte*>(m_value.data()), full_size);
145 UniqueArray<Int64> extents;
146 extents.add(nb_element);
147 auto sd = arcaneCreateSerializedDataRef(data_type, base_values.size(), 1, nb_element,
148 nb_base_element, false, extents, shape());
149 sd->setConstBytes(base_values);
150 return sd;
151}
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156template <typename DataType> void ArrayDataT<DataType>::
157allocateBufferForSerializedData(ISerializedData* sdata)
158{
159 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
160
161 eDataType data_type = sdata->baseDataType();
163
164 if (data_type != dataType() && data_type == base_data_type)
165 ARCANE_THROW(ArgumentException, "Bad serialized type");
166
167 Int64 nb_element = sdata->nbElement();
168
169 //m_trace->info() << " ASSIGN DATA nb_element=" << nb_element
170 // << " this=" << this;
171 m_value.resize(nb_element);
172 m_shape = sdata->shape();
173 Byte* byte_data = reinterpret_cast<Byte*>(m_value.data());
174 Span<Byte> buffer(byte_data, sdata->memorySize());
175 sdata->setWritableBytes(buffer);
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
181template <typename DataType> void ArrayDataT<DataType>::
182assignSerializedData(const ISerializedData* sdata)
183{
184 ARCANE_UNUSED(sdata);
185 // Rien à faire car \a sdata pointe directement vers m_value
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191template <typename DataType> void ArrayDataT<DataType>::
192serialize(ISerializer* sbuf, IDataOperation* operation)
193{
195 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
197 bool is_debug = arcaneIsDebug();
198
199 switch (sbuf->mode()) {
200 case ISerializer::ModeReserve: {
201 Int64 nb_value = m_value.largeSize();
202 Int64 total_size = nb_value * nb_count;
203 m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) reserve datatype="
204 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
205 sbuf->reserveInt64(2); // 1 pour le nombre magique et 1 pour la taille
206 sbuf->reserveSpan(data_type, total_size);
207 } break;
209 Int64 nb_value = m_value.largeSize();
210 Int64 total_size = nb_value * nb_count;
211 m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) put datatype="
212 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
213 if (is_debug)
214 for (Int64 i = 0; i < nb_value; ++i)
215 m_trace->debug(Trace::Highest) << "Put i=" << i << " value =" << m_value[i];
216
217 Span<const BasicType> base_value(reinterpret_cast<BasicType*>(m_value.data()), total_size);
218 sbuf->putInt64(SERIALIZE_MAGIC_NUMBER);
219 sbuf->putInt64(nb_value);
220 sbuf->putSpan(base_value);
221 } break;
223 Int64 saved_magic_number = sbuf->getInt64();
224 Int64 nb_value = sbuf->getInt64();
225
226 if (saved_magic_number != SERIALIZE_MAGIC_NUMBER)
227 ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}",
228 SERIALIZE_MAGIC_NUMBER, saved_magic_number);
229
230 Int64 total_size = nb_value * nb_count;
231
232 m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) get mode=" << sbuf->readMode()
233 << " datatype=" << data_type
234 << " ids=" << nb_value << " totalsize=" << total_size;
235 switch (sbuf->readMode()) {
237 m_value.resize(nb_value); // doit-on redimensionner en utilisant resizeFromGroup ?
238
239 if (operation) {
240 UniqueArray<BasicType> base_value(total_size);
241 sbuf->getSpan(base_value);
242 Span<const DataType> data_value(reinterpret_cast<DataType*>(base_value.data()), nb_value);
243 operation->applySpan(m_value, data_value);
244 if (is_debug)
245 for (Int64 i = 0; i < nb_value; ++i)
246 m_trace->debug(Trace::Highest) << "Get i=" << i << " value="
247 << data_value[i] << " transformed value=" << m_value[i];
248 }
249 else {
250 Span<BasicType> base_value(reinterpret_cast<BasicType*>(m_value.data()), total_size);
251 sbuf->getSpan(base_value);
252 if (is_debug)
253 for (Int64 i = 0; i < nb_value; ++i)
254 m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i];
255 }
256 } break;
258 Int64 current_size = m_value.largeSize();
259 m_value.resize(current_size + nb_value); // doit-on redimensionner en utilisant resizeFromGroup ?
260 Span<BasicType> base_value(reinterpret_cast<BasicType*>(m_value.data() + current_size), total_size);
261 if (operation)
262 ARCANE_THROW(NotImplementedException, "ArrayData::serialize : Impossible de désérialiser en utilisant une opération en mode ReadAdd");
263 sbuf->getSpan(base_value);
264 if (is_debug)
265 for (Int64 i = 0; i < nb_value; ++i)
266 m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i];
267 }
268 }
269 break;
270 } break;
271 }
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
277template <typename DataType> void ArrayDataT<DataType>::
278serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation)
279{
280 _serialize(sbuf, ids, operation);
281}
282
283/*---------------------------------------------------------------------------*/
284/*---------------------------------------------------------------------------*/
285
286template <typename DataType> void ArrayDataT<DataType>::
288{
290 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
292 bool is_debug = arcaneIsDebug();
293
294 Int64 nb_value = ids.size();
295 Int64 total_size = nb_value * nb_count;
296
297 switch (sbuf->mode()) {
298 case ISerializer::ModeReserve: {
299 m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) reserve datatype="
300 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
301 sbuf->reserveInt64(2);
302 sbuf->reserveSpan(data_type, total_size);
303 } break;
304 case ISerializer::ModePut: {
305 m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) put datatype="
306 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
307 if (is_debug) {
308 // Vérifie les valeurs
309 for (Integer i = 0, max_value = m_value.size(); i < nb_value; ++i)
310 if (ids[i] > max_value)
311 throw IndexOutOfRangeException(A_FUNCINFO,
312 String::format(" put,serialize : tailles incorrectes i={0} ids[i]={1} nb_value={2} this={3}",
313 i, ids[i], max_value, this),
314 i, 0, max_value);
315 }
316
317 UniqueArray<BasicType> base_value;
318 base_value.reserve(total_size);
319 for (Int64 i = 0; i < nb_value; ++i) {
320#ifdef ARCANE_DEBUG
321 m_trace->debug(Trace::Highest) << "Put i=" << i << " index=" << ids[i] << " value=" << m_value[ids[i]];
322#endif /* ARCANE_DEBUG */
323 ConstArrayView<BasicType> current_value(nb_count, reinterpret_cast<BasicType*>(&m_value[ids[i]]));
324 base_value.addRange(current_value);
325 }
326 sbuf->putInt64(SERIALIZE_MAGIC_NUMBER);
327 sbuf->putInt64(nb_value);
328 sbuf->putSpan(base_value);
329 } break;
330 case ISerializer::ModeGet: {
331 m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) get mode=" << sbuf->readMode()
332 << " datatype=" << data_type
333 << " ids=" << nb_value << " totalsize=" << total_size;
334 if (is_debug) {
335 // Vérifie les valeurs
336 for (Integer i = 0, max_value = m_value.size(); i < nb_value; ++i)
337 if (ids[i] > max_value)
338 throw IndexOutOfRangeException(A_FUNCINFO,
339 String::format(" put,serialize : tailles incorrectes i={0} ids[i]={1} nb_value={2} this={3}",
340 i, ids[i], max_value, this),
341 i, 0, max_value);
342 }
343
344 switch (sbuf->readMode()) {
345 case ISerializer::ReadReplace: {
346 Int64 saved_magic_number = sbuf->getInt64();
347 Int64 saved_nb_value = sbuf->getInt64();
348
349 if (saved_magic_number != SERIALIZE_MAGIC_NUMBER)
350 ARCANE_FATAL("Internal errror: mauvais nombre magique pour la sérialisation attendu={0} actuel={1}",
351 SERIALIZE_MAGIC_NUMBER, saved_magic_number);
352
353 if (saved_nb_value != nb_value)
354 ARCANE_FATAL("Internal errror: mauvaise taille pour la sérialisation attendue={0} trouvée={1}",
355 nb_value, saved_nb_value);
356
357 UniqueArray<BasicType> base_value(total_size);
358 sbuf->getSpan(base_value);
359
360 Span<DataType> data_value(reinterpret_cast<DataType*>(base_value.data()), nb_value);
361 UniqueArray<DataType> current_value;
362 Span<DataType> transformed_value;
363
364 if (operation && nb_value != 0) {
365 current_value.resize(ids.size());
366 Arccore::sampleSpan(m_value.constSpan(), ids, current_value.span());
367 transformed_value = current_value.view();
368 operation->applySpan(transformed_value, data_value);
369 }
370 else {
371 transformed_value = data_value;
372 }
373
374 if (is_debug) {
375 if (operation)
376 for (Int64 i = 0; i < nb_value; ++i)
377 m_trace->debug(Trace::Highest) << "Get i=" << i << " index=" << ids[i]
378 << " value=" << data_value[i] << " transformed value=" << transformed_value[i];
379 else
380 for (Int64 i = 0; i < nb_value; ++i)
381 m_trace->debug(Trace::Highest) << "Get i=" << i << " index=" << ids[i]
382 << " value=" << data_value[i];
383 }
384
385 for (Int64 i = 0; i < nb_value; ++i) {
386 m_value[ids[i]] = transformed_value[i];
387 }
388 } break;
389 case ISerializer::ReadAdd:
390 ARCANE_THROW(NotImplementedException, "ArrayData::serialize : Impossible de désérialiser avec le mode ReadAdd");
391 break;
392 }
393 } break;
394 }
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400template <typename DataType> void ArrayDataT<DataType>::
401fillDefault()
402{
403 m_value.fill(DataType());
404}
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
409template <typename DataType> void ArrayDataT<DataType>::
410setName(const String& name)
411{
412 m_value.setDebugName(name);
413}
414
415/*---------------------------------------------------------------------------*/
416/*---------------------------------------------------------------------------*/
417
418template <typename DataType> void ArrayDataT<DataType>::
419computeHash(IHashAlgorithm* algo, ByteArray& output) const
420{
421 Int64 type_size = sizeof(DataType);
422 Int64 nb_element = m_value.largeSize();
423 const Byte* ptr = reinterpret_cast<const Byte*>(m_value.data());
424 Span<const Byte> input(ptr, type_size * nb_element);
425 algo->computeHash64(input, output);
426}
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430
431template <typename DataType> void ArrayDataT<DataType>::
432computeHash(DataHashInfo& hash_info) const
433{
434 hash_info.setVersion(2);
435 hash_info.context()->updateHash(asBytes(m_value.span()));
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441template <typename DataType> void ArrayDataT<DataType>::
442copy(const IData* data)
443{
444 auto* true_data = dynamic_cast<const DataInterfaceType*>(data);
445 if (!true_data)
446 ARCANE_THROW(ArgumentException, "Impossible de caster 'IData' en 'IArrayDataT'");
447 m_value.copy(true_data->view());
448}
449
450/*---------------------------------------------------------------------------*/
451/*---------------------------------------------------------------------------*/
452
453template <typename DataType> void ArrayDataT<DataType>::
454swapValues(IData* data)
455{
456 auto* true_data = dynamic_cast<ThatClass*>(data);
457 if (!true_data)
458 ARCANE_THROW(ArgumentException, "Impossible de caster 'IData' en 'ArrayDataT'");
459 swapValuesDirect(true_data);
460}
461
462/*---------------------------------------------------------------------------*/
463/*---------------------------------------------------------------------------*/
464
465template <typename DataType> void ArrayDataT<DataType>::
466swapValuesDirect(ThatClass* true_data)
467{
468 m_value.swap(true_data->m_value);
469}
470
471/*---------------------------------------------------------------------------*/
472/*---------------------------------------------------------------------------*/
473
474template <typename DataType> void ArrayDataT<DataType>::
475_setShape()
476{
477 m_shape.setNbDimension(1);
478 m_shape.setDimension(0, 1);
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
484template <typename DataType> void ArrayDataT<DataType>::
485setAllocationInfo(const DataAllocationInfo& v)
486{
487 if (m_allocation_info == v)
488 return;
489 m_allocation_info = v;
490 m_value.setMemoryLocationHint(v.memoryLocationHint());
491}
492
493/*---------------------------------------------------------------------------*/
494/*---------------------------------------------------------------------------*/
495
496template <typename DataType> void ArrayDataT<DataType>::
498{
499 m_value.changeAllocator(alloc_info);
500 m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint());
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
506} // namespace Arcane
507
508/*---------------------------------------------------------------------------*/
509/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions de gestion mémoire et des allocateurs.
Allocateur mémoire avec alignement mémoire spécifique.
Exception lorsqu'un argument est invalide.
Donnée tableau d'un type T.
Definition ArrayData.h:49
eDataType dataType() const override
Type de la donnée.
Definition ArrayData.h:70
ArrayShape shape() const override
Forme du tableau pour une donnée 1D ou 2D.
Definition ArrayData.h:96
UniqueArray< DataType > m_value
Donnée.
Definition ArrayData.h:140
const T * data() const
Accès à la racine du tableau hors toute protection.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Informations sur l'allocation d'une donnée.
Informations pour le calcul du hash d'une donnée.
Informations de type pour un conteneur de données.
Interface d'une opération sur une donnée.
Interface d'une donnée.
Definition IData.h:33
virtual void updateHash(Span< const std::byte > input)=0
Ajoute le tableau input au hash calculé
Interface d'un algorithme de hashage.
virtual void computeHash64(Span< const Byte > input, ByteArray &output)
Calcule la valeur du hash pour le tableau input.
Interface d'une donnée sérialisée.
virtual eDataType baseDataType() const =0
Type de la donnée.
virtual ArrayShape shape() const =0
Forme du tableau associé aux données.
virtual Int64 memorySize() const =0
Indique le nombre d'octets qu'il faut allouer pour stocker ou lire les données.
virtual void setWritableBytes(Span< Byte > bytes)=0
Positionne les valeurs de sérialisation.
virtual Int64 nbElement() const =0
Nombre d'éléments.
@ ModePut
Le sérialiseur attend des reserve().
virtual Int64 getInt64()=0
Récupère une taille.
virtual eReadMode readMode() const =0
Mode de lecture.
virtual void putSpan(Span< const Real > values)
Ajoute le tableau values.
virtual eMode mode() const =0
Mode de fonctionnement actuel.
@ ReadReplace
Replace les éléments actuels par ceux lus.
@ ReadAdd
Ajoute aux éléments actuels ceux lus.
virtual void getSpan(Span< Real > values)
Récupère le tableau values.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Réserve de la mémoire pour n valeurs de dt.
virtual void putInt64(Int64 value)=0
Ajoute l'entier value.
Interface du gestionnaire de traces.
Exception lorsqu'une fonction n'est pas implémentée.
Référence à une instance.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:325
Vue d'un tableau d'éléments de type T.
Definition Span.h:633
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Ref< ISerializedData > arcaneCreateSerializedDataRef(eDataType data_type, Int64 memory_size, Integer nb_dim, Int64 nb_element, Int64 nb_base_element, bool is_multi_size, Int64ConstArrayView dimensions)
Créé des données sérialisées.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:115
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:480
eBasicDataType
Type d'une donnée de base.
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:80
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Convertit la vue en un tableau d'octets non modifiables.
Definition Span.h:1028
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:42
eDataType
Type d'une donnée.
Definition DataTypes.h:39
void sampleSpan(Span< const DataType > values, Span< const Int64 > indexes, Span< DataType > result)
Extrait un sous-tableau à à partir d'une liste d'index.
Definition Span.h:1000