Arcane  4.2.1.0
Developer documentation
Loading...
Searching...
No Matches
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/* Array type data. */
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 // Nothing to do because \a sdata points directly to 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 for magic number and 1 for the size
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); // must resize using 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); // must resize using 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 : Cannot deserialize using operation in ReadAdd mode");
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 // Checks values
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 : bad sizes 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 // Checks values
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 : bad sizes 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: bad magic number for serialisation expected={0} current={1}",
351 SERIALIZE_MAGIC_NUMBER, saved_magic_number);
352
353 if (saved_nb_value != nb_value)
354 ARCANE_FATAL("Internal errror: bad size for serialisation expected={0} found={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 : Cannot deserialize with ReadAdd mode");
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, "Can not cast 'IData' to '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, "Can not cast 'IData' to '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 for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Memory and allocator management functions.
Memory allocator with specific memory alignment.
Array data of type T.
Definition ArrayData.h:50
eDataType dataType() const override
Data type.
Definition ArrayData.h:71
ArrayShape shape() const override
Array shape for a 1D or 2D data item.
Definition ArrayData.h:105
UniqueArray< DataType > m_value
Data.
Definition ArrayData.h:147
void add(ConstReferenceType val)
Adds element val to the end of the array.
const T * data() const
Access to the root of the array without any protection.
Information on data allocation.
Information for calculating data hash.
Type information for a data container.
Interface of an operation on a data.
Interface of a data item.
Definition IData.h:34
virtual void updateHash(Span< const std::byte > input)=0
Adds the array input to the calculated hash.
Interface of a hashing algorithm.
virtual void computeHash64(Span< const Byte > input, ByteArray &output)
Calculates the hash value for the array input.
Interface of a serialized data.
virtual eDataType baseDataType() const =0
Data type.
virtual ArrayShape shape() const =0
Shape of the array associated with the data.
virtual Int64 memorySize() const =0
Indicates the number of bytes that must be allocated to store or read the data.
virtual void setWritableBytes(Span< Byte > bytes)=0
Positions the serialized values.
virtual Int64 nbElement() const =0
Number of elements.
virtual Int64 getInt64()=0
Retrieve a size.
virtual eReadMode readMode() const =0
Read mode.
virtual void putSpan(Span< const Real > values)
Add the array values.
virtual eMode mode() const =0
Current operating mode.
@ ReadReplace
Replace current elements with those read.
@ ReadAdd
Add those read to the current elements.
virtual void getSpan(Span< Real > values)
Retrieve the array values.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Reserves memory for n values of dt.
virtual void putInt64(Int64 value)=0
Add the integer value.
Reference to an instance.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:325
View of an array of elements of type T.
Definition Span.h:633
1D data vector with value semantics (STL style).
-- 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)
Creates serialized data.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
Array< Byte > ByteArray
Dynamic one-dimensional array of characters.
Definition UtilsTypes.h:115
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:476
eBasicDataType
Type of a basic data item.
bool arcaneIsDebug()
True if the ARCANE_DEBUG macro is defined.
Definition Misc.cc:76
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of non-modifiable bytes.
Definition Span.h:1030
unsigned char Byte
Type of a byte.
Definition BaseTypes.h:42
eDataType
Data type.
Definition DataTypes.h:41
void sampleSpan(Span< const DataType > values, Span< const Int64 > indexes, Span< DataType > result)
Extracts a sub-array from a list of indices.
Definition Span.h:1002