Arcane  4.1.12.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 "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();
72}
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))
82{
83 _setShape();
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89template <typename DataType> ArrayDataT<DataType>::
90~ArrayDataT()
91{
92 delete m_internal;
93}
94
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 // Nothing to do because \a sdata points directly to 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 for magic number and 1 for the size
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 // Checks values
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 // Checks values
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 m_value.changeAllocator(alloc_info);
498 m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint());
499}
500
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504} // namespace Arcane
505
506/*---------------------------------------------------------------------------*/
507/*---------------------------------------------------------------------------*/
#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:327
View of an array of elements of type T.
Definition Span.h:635
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:121
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
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:1032
unsigned char Byte
Type of a byte.
Definition BaseTypes.h:43
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:1004