Arcane  v3.16.0.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-2024 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-2024 */
9/* */
10/* Donnée du type 'Array'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/ArrayData.h"
15
16#include "arcane/utils/NotSupportedException.h"
17#include "arcane/utils/Real2.h"
18#include "arcane/utils/Real2x2.h"
19#include "arcane/utils/Real3.h"
20#include "arcane/utils/Real3x3.h"
21#include "arcane/utils/IHashAlgorithm.h"
22#include "arcane/utils/NotImplementedException.h"
23#include "arcane/utils/IndexOutOfRangeException.h"
24#include "arcane/utils/ArgumentException.h"
25#include "arcane/utils/FatalErrorException.h"
26#include "arcane/utils/ITraceMng.h"
27#include "arcane/utils/CheckedConvert.h"
28#include "arcane/utils/MemoryAllocator.h"
30
31#include "arcane/core/datatype/DataStorageBuildInfo.h"
32#include "arcane/core/datatype/IDataOperation.h"
33
34#include "arcane/core/ISerializer.h"
35
36#include "arcane/impl/SerializedData.h"
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41namespace Arcane
42{
43namespace
44{
45 inline constexpr Int64 SERIALIZE_MAGIC_NUMBER = 0x456ff989;
46} // namespace
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51template <typename DataType> ArrayDataT<DataType>::
53: m_value(AlignedMemoryAllocator::Simd())
54, m_trace(trace)
55, m_internal(new Impl(this))
56{
57 _setShape();
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63template <typename DataType> ArrayDataT<DataType>::
64ArrayDataT(const ArrayDataT<DataType>& rhs)
65: m_value(AlignedMemoryAllocator::Simd())
66, m_trace(rhs.m_trace)
67, m_internal(new Impl(this))
68, m_shape(rhs.m_shape)
69, m_allocation_info(rhs.m_allocation_info)
70{
71 m_value = rhs.m_value.constSpan();
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77template <typename DataType> ArrayDataT<DataType>::
78ArrayDataT(const DataStorageBuildInfo& dsbi)
79: m_value(dsbi.memoryAllocator())
80, m_trace(dsbi.traceMng())
81, m_internal(new Impl(this))
83 _setShape();
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
89template <typename DataType> ArrayDataT<DataType>::
90~ArrayDataT()
92 delete m_internal;
95/*---------------------------------------------------------------------------*/
96/*---------------------------------------------------------------------------*/
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101template <typename DataType> DataStorageTypeInfo ArrayDataT<DataType>::
102staticStorageTypeInfo()
103{
104 typedef DataTypeTraitsT<DataType> TraitsType;
105 eBasicDataType bdt = TraitsType::basicDataType();
106 Int32 nb_basic_type = TraitsType::nbBasicType();
107 Int32 dimension = 1;
108 Int32 multi_tag = 0;
109 return DataStorageTypeInfo(bdt, nb_basic_type, dimension, multi_tag);
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115template <typename DataType> DataStorageTypeInfo ArrayDataT<DataType>::
116storageTypeInfo() const
117{
118 return staticStorageTypeInfo();
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
124template <typename DataType> Ref<ISerializedData> ArrayDataT<DataType>::
125createSerializedDataRef(bool use_basic_type) const
126{
127 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
128
129 Integer nb_count = 1;
130 eDataType data_type = dataType();
131 Integer type_size = sizeof(DataType);
132
133 if (use_basic_type) {
136 type_size = sizeof(BasicType);
137 }
138
139 Int64 nb_element = m_value.largeSize();
140 Int64 nb_base_element = nb_element * nb_count;
141 Int64 full_size = nb_base_element * type_size;
142 Span<const Byte> base_values(reinterpret_cast<const Byte*>(m_value.data()), full_size);
143 UniqueArray<Int64> extents;
144 extents.add(nb_element);
145 auto sd = arcaneCreateSerializedDataRef(data_type, base_values.size(), 1, nb_element,
146 nb_base_element, false, extents, shape());
147 sd->setConstBytes(base_values);
148 return sd;
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154template <typename DataType> void ArrayDataT<DataType>::
155allocateBufferForSerializedData(ISerializedData* sdata)
156{
157 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
158
159 eDataType data_type = sdata->baseDataType();
161
162 if (data_type != dataType() && data_type == base_data_type)
163 ARCANE_THROW(ArgumentException, "Bad serialized type");
164
165 Int64 nb_element = sdata->nbElement();
166
167 //m_trace->info() << " ASSIGN DATA nb_element=" << nb_element
168 // << " this=" << this;
169 m_value.resize(nb_element);
170 m_shape = sdata->shape();
171 Byte* byte_data = reinterpret_cast<Byte*>(m_value.data());
172 Span<Byte> buffer(byte_data, sdata->memorySize());
173 sdata->setWritableBytes(buffer);
174}
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
179template <typename DataType> void ArrayDataT<DataType>::
180assignSerializedData(const ISerializedData* sdata)
181{
182 ARCANE_UNUSED(sdata);
183 // Rien à faire car \a sdata pointe directement vers m_value
184}
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
189template <typename DataType> void ArrayDataT<DataType>::
190serialize(ISerializer* sbuf, IDataOperation* operation)
191{
193 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
195 bool is_debug = arcaneIsDebug();
196
197 switch (sbuf->mode()) {
198 case ISerializer::ModeReserve: {
199 Int64 nb_value = m_value.largeSize();
200 Int64 total_size = nb_value * nb_count;
201 m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) reserve datatype="
202 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
203 sbuf->reserveInt64(2); // 1 pour magic number et 1 pour la taille
204 sbuf->reserveSpan(data_type, total_size);
205 } break;
207 Int64 nb_value = m_value.largeSize();
208 Int64 total_size = nb_value * nb_count;
209 m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) put datatype="
210 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
211 if (is_debug)
212 for (Int64 i = 0; i < nb_value; ++i)
213 m_trace->debug(Trace::Highest) << "Put i=" << i << " value =" << m_value[i];
214
215 Span<const BasicType> base_value(reinterpret_cast<BasicType*>(m_value.data()), total_size);
216 sbuf->putInt64(SERIALIZE_MAGIC_NUMBER);
217 sbuf->putInt64(nb_value);
218 sbuf->putSpan(base_value);
219 } break;
221 Int64 saved_magic_number = sbuf->getInt64();
222 Int64 nb_value = sbuf->getInt64();
223
224 if (saved_magic_number != SERIALIZE_MAGIC_NUMBER)
225 ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}",
226 SERIALIZE_MAGIC_NUMBER, saved_magic_number);
227
228 Int64 total_size = nb_value * nb_count;
229
230 m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) get mode=" << sbuf->readMode()
231 << " datatype=" << data_type
232 << " ids=" << nb_value << " totalsize=" << total_size;
233 switch (sbuf->readMode()) {
235 m_value.resize(nb_value); // must resize using resizeFromGroup ?
236
237 if (operation) {
238 UniqueArray<BasicType> base_value(total_size);
239 sbuf->getSpan(base_value);
240 Span<const DataType> data_value(reinterpret_cast<DataType*>(base_value.data()), nb_value);
241 operation->applySpan(m_value, data_value);
242 if (is_debug)
243 for (Int64 i = 0; i < nb_value; ++i)
244 m_trace->debug(Trace::Highest) << "Get i=" << i << " value="
245 << data_value[i] << " transformed value=" << m_value[i];
246 }
247 else {
248 Span<BasicType> base_value(reinterpret_cast<BasicType*>(m_value.data()), total_size);
249 sbuf->getSpan(base_value);
250 if (is_debug)
251 for (Int64 i = 0; i < nb_value; ++i)
252 m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i];
253 }
254 } break;
256 Int64 current_size = m_value.largeSize();
257 m_value.resize(current_size + nb_value); // must resize using resizeFromGroup ?
258 Span<BasicType> base_value(reinterpret_cast<BasicType*>(m_value.data() + current_size), total_size);
259 if (operation)
260 ARCANE_THROW(NotImplementedException, "ArrayData::serialize : Cannot deserialize using operation in ReadAdd mode");
261 sbuf->getSpan(base_value);
262 if (is_debug)
263 for (Int64 i = 0; i < nb_value; ++i)
264 m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i];
265 }
266 }
267 break;
268 } break;
269 }
270}
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
275template <typename DataType> void ArrayDataT<DataType>::
276serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation)
277{
278 _serialize(sbuf, ids, operation);
279}
280
281/*---------------------------------------------------------------------------*/
282/*---------------------------------------------------------------------------*/
283
284template <typename DataType> void ArrayDataT<DataType>::
286{
288 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
290 bool is_debug = arcaneIsDebug();
291
292 Int64 nb_value = ids.size();
293 Int64 total_size = nb_value * nb_count;
294
295 switch (sbuf->mode()) {
296 case ISerializer::ModeReserve: {
297 m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) reserve datatype="
298 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
299 sbuf->reserveInt64(2);
300 sbuf->reserveSpan(data_type, total_size);
301 } break;
302 case ISerializer::ModePut: {
303 m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) put datatype="
304 << data_type << " ids=" << nb_value << " totalsize=" << total_size;
305 if (is_debug) {
306 // Vérifie les valeurs
307 for (Integer i = 0, max_value = m_value.size(); i < nb_value; ++i)
308 if (ids[i] > max_value)
309 throw IndexOutOfRangeException(A_FUNCINFO,
310 String::format(" put,serialize : bad sizes i={0} ids[i]={1} nb_value={2} this={3}",
311 i, ids[i], max_value, this),
312 i, 0, max_value);
313 }
314
315 UniqueArray<BasicType> base_value;
316 base_value.reserve(total_size);
317 for (Int64 i = 0; i < nb_value; ++i) {
318#ifdef ARCANE_DEBUG
319 m_trace->debug(Trace::Highest) << "Put i=" << i << " index=" << ids[i] << " value=" << m_value[ids[i]];
320#endif /* ARCANE_DEBUG */
321 ConstArrayView<BasicType> current_value(nb_count, reinterpret_cast<BasicType*>(&m_value[ids[i]]));
322 base_value.addRange(current_value);
323 }
324 sbuf->putInt64(SERIALIZE_MAGIC_NUMBER);
325 sbuf->putInt64(nb_value);
326 sbuf->putSpan(base_value);
327 } break;
328 case ISerializer::ModeGet: {
329 m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) get mode=" << sbuf->readMode()
330 << " datatype=" << data_type
331 << " ids=" << nb_value << " totalsize=" << total_size;
332 if (is_debug) {
333 // Vérifie les valeurs
334 for (Integer i = 0, max_value = m_value.size(); i < nb_value; ++i)
335 if (ids[i] > max_value)
336 throw IndexOutOfRangeException(A_FUNCINFO,
337 String::format(" put,serialize : bad sizes i={0} ids[i]={1} nb_value={2} this={3}",
338 i, ids[i], max_value, this),
339 i, 0, max_value);
340 }
341
342 switch (sbuf->readMode()) {
343 case ISerializer::ReadReplace: {
344 Int64 saved_magic_number = sbuf->getInt64();
345 Int64 saved_nb_value = sbuf->getInt64();
346
347 if (saved_magic_number != SERIALIZE_MAGIC_NUMBER)
348 ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}",
349 SERIALIZE_MAGIC_NUMBER, saved_magic_number);
350
351 if (saved_nb_value != nb_value)
352 ARCANE_FATAL("Internal errror: bad size for serialisation expected={0} found={1}",
353 nb_value, saved_nb_value);
354
355 UniqueArray<BasicType> base_value(total_size);
356 sbuf->getSpan(base_value);
357
358 Span<DataType> data_value(reinterpret_cast<DataType*>(base_value.data()), nb_value);
359 UniqueArray<DataType> current_value;
360 Span<DataType> transformed_value;
361
362 if (operation && nb_value != 0) {
363 current_value.resize(ids.size());
364 Arccore::sampleSpan(m_value.constSpan(), ids, current_value.span());
365 transformed_value = current_value.view();
366 operation->applySpan(transformed_value, data_value);
367 }
368 else {
369 transformed_value = data_value;
370 }
371
372 if (is_debug) {
373 if (operation)
374 for (Int64 i = 0; i < nb_value; ++i)
375 m_trace->debug(Trace::Highest) << "Get i=" << i << " index=" << ids[i]
376 << " value=" << data_value[i] << " transformed value=" << transformed_value[i];
377 else
378 for (Int64 i = 0; i < nb_value; ++i)
379 m_trace->debug(Trace::Highest) << "Get i=" << i << " index=" << ids[i]
380 << " value=" << data_value[i];
381 }
382
383 for (Int64 i = 0; i < nb_value; ++i) {
384 m_value[ids[i]] = transformed_value[i];
385 }
386 } break;
387 case ISerializer::ReadAdd:
388 ARCANE_THROW(NotImplementedException, "ArrayData::serialize : Cannot deserialize with ReadAdd mode");
389 break;
390 }
391 } break;
392 }
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
398template <typename DataType> void ArrayDataT<DataType>::
399fillDefault()
400{
401 m_value.fill(DataType());
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
407template <typename DataType> void ArrayDataT<DataType>::
408setName(const String& name)
409{
410 m_value.setDebugName(name);
411}
412
413/*---------------------------------------------------------------------------*/
414/*---------------------------------------------------------------------------*/
415
416template <typename DataType> void ArrayDataT<DataType>::
417computeHash(IHashAlgorithm* algo, ByteArray& output) const
418{
419 Int64 type_size = sizeof(DataType);
420 Int64 nb_element = m_value.largeSize();
421 const Byte* ptr = reinterpret_cast<const Byte*>(m_value.data());
422 Span<const Byte> input(ptr, type_size * nb_element);
423 algo->computeHash64(input, output);
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429template <typename DataType> void ArrayDataT<DataType>::
430computeHash(DataHashInfo& hash_info) const
431{
432 hash_info.setVersion(2);
433 hash_info.context()->updateHash(asBytes(m_value.span()));
434}
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
439template <typename DataType> void ArrayDataT<DataType>::
440copy(const IData* data)
441{
442 auto* true_data = dynamic_cast<const DataInterfaceType*>(data);
443 if (!true_data)
444 ARCANE_THROW(ArgumentException, "Can not cast 'IData' to 'IArrayDataT'");
445 m_value.copy(true_data->view());
446}
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
450
451template <typename DataType> void ArrayDataT<DataType>::
452swapValues(IData* data)
453{
454 auto* true_data = dynamic_cast<ThatClass*>(data);
455 if (!true_data)
456 ARCANE_THROW(ArgumentException, "Can not cast 'IData' to 'ArrayDataT'");
457 swapValuesDirect(true_data);
458}
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
463template <typename DataType> void ArrayDataT<DataType>::
464swapValuesDirect(ThatClass* true_data)
465{
466 m_value.swap(true_data->m_value);
467}
468
469/*---------------------------------------------------------------------------*/
470/*---------------------------------------------------------------------------*/
471
472template <typename DataType> void ArrayDataT<DataType>::
473_setShape()
474{
475 m_shape.setNbDimension(1);
476 m_shape.setDimension(0, 1);
477}
478
479/*---------------------------------------------------------------------------*/
480/*---------------------------------------------------------------------------*/
481
482template <typename DataType> void ArrayDataT<DataType>::
483setAllocationInfo(const DataAllocationInfo& v)
484{
485 if (m_allocation_info == v)
486 return;
487 m_allocation_info = v;
488 m_value.setMemoryLocationHint(v.memoryLocationHint());
489}
490
491/*---------------------------------------------------------------------------*/
492/*---------------------------------------------------------------------------*/
493
494template <typename DataType> void ArrayDataT<DataType>::
496{
497 UniqueArray<DataType> new_value(alloc_info, m_value.size());
498
499 // Copie \a m_value dans \a new_value
500 // Tant qu'il n'y a pas l'API dans Arccore, il faut faire la copie à la
501 // main pour ne pas avoir de plantage si l'allocateur est uniquement sur
502 // un accélérateur
503 MemoryUtils::copy(new_value.span(), m_value.constSpan());
504
505 std::swap(m_value, new_value);
506 m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint());
507}
508
509/*---------------------------------------------------------------------------*/
510/*---------------------------------------------------------------------------*/
511
512} // namespace Arcane
513
514/*---------------------------------------------------------------------------*/
515/*---------------------------------------------------------------------------*/
#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
Definition ArrayData.h:140
Integer dimension() const override
Definition ArrayData.h:68
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 pour construire une instance de 'IData'.
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.
Options pour configurer les allocations.
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:212
Vue d'un tableau d'éléments de type T.
Definition Span.h:513
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
void copy(MutableMemoryView destination, eMemoryResource destination_mem, ConstMemoryView source, eMemoryResource source_mem, const RunQueue *queue=nullptr)
Copie de source vers destination en utilisant la file queue.
-*- 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:208
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:569
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)
Converti la vue en un tableau d'octets non modifiables.
Definition Span.h:884
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:43
eDataType
Type d'une donnée.
Definition DataTypes.h:39
std::int32_t Int32
Type entier signé sur 32 bits.
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:858