Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
Array2Data.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/* Array2Data.inst.h (C) 2000-2026 */
9/* */
10/* Data of type 'Array2'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/Array2Data.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/ArgumentException.h"
24#include "arcane/utils/FatalErrorException.h"
25#include "arcane/utils/ITraceMng.h"
26#include "arcane/utils/CheckedConvert.h"
27#include "arcane/utils/MemoryAllocator.h"
29
30#include "arcane/core/datatype/DataStorageBuildInfo.h"
31#include "arcane/core/datatype/IDataOperation.h"
32
33#include "arcane/core/ISerializer.h"
34
35#include "arcane/impl/SerializedData.h"
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46namespace
47{
48 inline constexpr Int64 SERIALIZE2_MAGIC_NUMBER = 0x12ff7789;
49}
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54template <typename DataType> Array2DataT<DataType>::
56: m_value(AlignedMemoryAllocator::Simd())
57, m_trace(trace)
58, m_internal(new Impl(this))
59{
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65template <typename DataType> Array2DataT<DataType>::
66Array2DataT(const Array2DataT<DataType>& rhs)
67: m_value(AlignedMemoryAllocator::Simd())
68, m_trace(rhs.m_trace)
69, m_internal(new Impl(this))
70, m_allocation_info(rhs.m_allocation_info)
71{
72 m_value = rhs.m_value;
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78template <typename DataType> Array2DataT<DataType>::
79Array2DataT(const DataStorageBuildInfo& dsbi)
80: m_value(dsbi.memoryAllocator())
81, m_trace(dsbi.traceMng())
82, m_internal(new Impl(this))
83{
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89template <typename DataType> Array2DataT<DataType>::
90~Array2DataT()
91{
92 delete m_internal;
93}
94
95/*---------------------------------------------------------------------------*/
96/*---------------------------------------------------------------------------*/
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101template <typename DataType> DataStorageTypeInfo Array2DataT<DataType>::
102staticStorageTypeInfo()
103{
104 typedef DataTypeTraitsT<DataType> TraitsType;
105 eBasicDataType bdt = TraitsType::basicDataType();
106 Int32 nb_basic_type = TraitsType::nbBasicType();
107 Int32 dimension = 2;
108 Int32 multi_tag = 0;
109 return DataStorageTypeInfo(bdt, nb_basic_type, dimension, multi_tag);
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115template <typename DataType> DataStorageTypeInfo Array2DataT<DataType>::
116storageTypeInfo() const
117{
118 return staticStorageTypeInfo();
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
124template <typename DataType> void Array2DataT<DataType>::
125resize(Integer new_size)
126{
127 m_value.resize(new_size);
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133template <typename DataType> Ref<ISerializedData> Array2DataT<DataType>::
134createSerializedDataRef(bool use_basic_type) const
135{
136 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
137
138 Int64 nb_count = 1;
139 eDataType data_type = dataType();
140 Int64 type_size = sizeof(DataType);
141
142 if (use_basic_type) {
145 type_size = sizeof(BasicType);
146 }
147
148 Int64 nb_element = m_value.totalNbElement();
149 Int64 nb_base_element = nb_element * nb_count;
150 Int64 full_size = nb_base_element * type_size;
151 const Byte* bt = reinterpret_cast<const Byte*>(m_value.to1DSpan().data());
152 Span<const Byte> base_values(bt, full_size);
153 UniqueArray<Int64> dimensions;
154 dimensions.resize(2);
155 dimensions[0] = m_value.dim1Size();
156 dimensions[1] = m_value.dim2Size();
157
158 auto sd = arcaneCreateSerializedDataRef(data_type, base_values.size(), 2, nb_element,
159 nb_base_element, false, dimensions, shape());
160 sd->setConstBytes(base_values);
161 return sd;
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
167template <typename DataType> void Array2DataT<DataType>::
168allocateBufferForSerializedData(ISerializedData* sdata)
169{
170 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
171
172 eDataType data_type = sdata->baseDataType();
174
175 if (data_type != dataType() && data_type == base_data_type)
176 ARCANE_FATAL("Bad serialized type");
177 bool is_multi_size = sdata->isMultiSize();
178 if (is_multi_size)
179 ARCANE_FATAL("Can not allocate multi-size array");
180
181 Int64 dim1_size = sdata->extents()[0];
182 Int64 dim2_size = sdata->extents()[1];
183 //m_trace->info() << " ASSIGN DATA dim1=" << dim1_size
184 // << " dim2=" << dim2_size
185 // << " addr=" << m_value.viewAsArray().unguardedBasePointer();
186
187 m_value.resize(dim1_size, dim2_size);
188 m_shape = sdata->shape();
189
190 Byte* byte_data = reinterpret_cast<Byte*>(m_value.to1DSpan().data());
191 Span<Byte> bytes_view(byte_data, sdata->memorySize());
192 sdata->setWritableBytes(bytes_view);
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198template <typename DataType> void Array2DataT<DataType>::
199assignSerializedData(const ISerializedData* sdata)
200{
201 ARCANE_UNUSED(sdata);
202 // Nothing to do because \a sdata points directly to m_value
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208template <typename DataType> void Array2DataT<DataType>::
209serialize(ISerializer* sbuf, IDataOperation* operation)
210{
212 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
214
215 ISerializer::eMode mode = sbuf->mode();
216 if (mode == ISerializer::ModeReserve) {
217 // Reserves memory for
218 // - the number of elements in the first dimension
219 // - the number of elements in the second dimension
220 // - the number of elements of ids.
221 // - the magic number for verification
223 // Reserves memory for the values
224 Int64 total_nb_element = m_value.totalNbElement();
225 sbuf->reserveSpan(data_type, total_nb_element * nb_count);
226 }
227 else if (mode == ISerializer::ModePut) {
228 Int64 count = m_value.dim1Size();
229 Int64 total = m_value.totalNbElement();
230 Int64 n[4];
231 n[0] = count;
232 n[1] = m_value.dim2Size();
233 n[2] = total;
234 n[3] = SERIALIZE2_MAGIC_NUMBER;
235 sbuf->putSpan(Span<const Int64>(n, 4));
236 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data());
237 Span<const BasicType> v(bt, total * nb_count);
238 //m_trace->info() << "PUT array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType);
239 sbuf->putSpan(v);
240 }
241 else if (mode == ISerializer::ModeGet) {
242 Int64 n[4] = { 0, 0, 0, 0 };
243 sbuf->getSpan(Span<Int64>(n, 4));
244 Int64 count = n[0];
245 Int64 dim2_size = n[1];
246 Int64 total = n[2];
247 if (n[3] != SERIALIZE2_MAGIC_NUMBER)
248 ARCANE_FATAL("Bad magic number");
249 switch (sbuf->readMode()) {
251 //m_trace->info() << "READ REPLACE count=" << count << " dim2_size=" << dim2_size;
252 m_value.resize(count, dim2_size);
253 if (operation)
254 throw NotImplementedException(A_FUNCINFO, "serialize(ReadReplace) with IDataOperation");
255 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data());
256 Span<BasicType> v(bt, total * nb_count);
257 sbuf->getSpan(v);
258 } break;
260 Int64 current_size = m_value.dim1Size();
261 Int64 current_total = m_value.totalNbElement();
262 //m_trace->info() << "READ ADD NEW_SIZE=" << current_size << " COUNT=" << count
263 // << " dim2_size=" << dim2_size << " current_dim2_size=" << m_value.dim2Size()
264 // << " current_total=" << current_total << " read_elem=" << (total*nb_count);
265 m_value.resize(current_size + count, dim2_size);
266 if (operation)
267 throw NotImplementedException(A_FUNCINFO, "serialize(ReadAdd) with IDataOperation");
268 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data() + current_total);
269 //m_trace->info() << "GET array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType);
270 Span<BasicType> v(bt, total * nb_count);
271 sbuf->getSpan(v);
272 } break;
273 }
274 }
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
280template <typename DataType> void Array2DataT<DataType>::
281serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation)
282{
284 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
286
287 ISerializer::eMode mode = sbuf->mode();
288 if (mode == ISerializer::ModeReserve) {
289 // Reserves memory for
290 // - the number of elements in the first dimension
291 // - the number of elements in the second dimension
292 // - the number of elements in ids.
293 // - the magic number for verification
295 // Reserves memory for the values
296 Int64 total_nb_value = ((Int64)ids.size()) * ((Int64)m_value.dim2Size());
297 sbuf->reserveSpan(data_type, total_nb_value * nb_count);
298 }
299 else if (mode == ISerializer::ModePut) {
300 Int32 count = ids.size();
301 Int64 dim2_size = m_value.dim2Size();
302 Int64 total_nb_value = count * dim2_size;
303 Int64 total = total_nb_value;
304 Int64 n[4];
305 n[0] = m_value.dim1Size();
306 n[1] = m_value.dim2Size();
307 n[2] = count;
308 n[3] = SERIALIZE2_MAGIC_NUMBER;
309 /*m_trace->info() << "PUT COUNT = " << count << " total=" << total
310 << " dim1 (n[0])=" << n[0]
311 << " dim2 (n[1])=" << n[1]
312 << " count (n[2])=" << n[2]
313 << " magic=" << n[3]
314 << " this=" << this;*/
315 sbuf->putSpan(Span<const Int64>(n, 4));
316 UniqueArray<BasicType> v(total * nb_count);
317 {
318 Integer index = 0;
319 for (Int32 i = 0, is = count; i < is; ++i) {
320 const BasicType* sub_a = reinterpret_cast<const BasicType*>(m_value[ids[i]].data());
321 for (Int64 z = 0, iz = dim2_size * nb_count; z < iz; ++z) {
322 v[index] = sub_a[z];
323 ++index;
324 }
325 }
326 }
327 sbuf->putSpan(v);
328 }
329 else if (mode == ISerializer::ModeGet) {
330 switch (sbuf->readMode()) {
332 Int64 n[4] = { 0, 0, 0, 0 };
333 sbuf->getSpan(Span<Int64>(n, 4));
334 //Integer dim1_size = n[0];
335 Int64 dim2_size = n[1];
336 Int32 count = CheckedConvert::toInt32(n[2]);
337 Int64 total = count * dim2_size;
338 // One dim
339 /*m_trace->info() << "COUNT = " << count << " total=" << total
340 << " dim1 (n[0])=" << n[0]
341 << " dim1 current=" << m_value.dim1Size()
342 << " dim2 (n[1])=" << n[1]
343 << " dim2 current=" << m_value.dim2Size()
344 << " count (n[2])=" << n[2]
345 << " magic=" << n[3]
346 << " this=" << this;*/
347 if (n[3] != SERIALIZE2_MAGIC_NUMBER)
348 ARCANE_FATAL("Bad magic number");
349 Int64 current_dim2_size = m_value.dim2Size();
350 if (dim2_size != current_dim2_size) {
351 if (current_dim2_size != 0 && dim2_size != 0)
352 ARCANE_FATAL("serialized data should have the same dim2Size current={0} found={1}",
353 current_dim2_size, dim2_size);
354 else
355 m_value.resize(m_value.dim1Size(), dim2_size);
356 }
357 Int64 nb_value = count;
358 //Array<BasicType> v(total*nb_count);
359 UniqueArray<BasicType> base_value(total * nb_count);
360
361 sbuf->getSpan(base_value);
362
363 Span<DataType> data_value(reinterpret_cast<DataType*>(base_value.data()), nb_value * dim2_size);
364 UniqueArray<DataType> current_value;
365 Span<DataType> transformed_value;
366
367 // If a transformation is applied, perform the transformation in a
368 // temporary array 'current_value'.
369 if (operation && nb_value != 0) {
370 current_value.resize(data_value.size());
371
372 Int64 index = 0;
373 for (Int32 i = 0, n = count; i < n; ++i) {
374 Span<const DataType> a(m_value[ids[i]]);
375 for (Int64 z = 0, iz = dim2_size; z < iz; ++z) {
376 current_value[index] = a[z];
377 ++index;
378 }
379 }
380
381 transformed_value = current_value.view();
382 operation->applySpan(transformed_value, data_value);
383 }
384 else {
385 transformed_value = data_value;
386 }
387
388 {
389 Int64 index = 0;
390 for (Int32 i = 0, n = count; i < n; ++i) {
391 Span<DataType> a(m_value[ids[i]]);
392 for (Int64 z = 0, iz = dim2_size; z < iz; ++z) {
393 a[z] = transformed_value[index];
394 ++index;
395 }
396 }
397 }
398 } break;
400 throw NotImplementedException(A_FUNCINFO, "option 'ReadAdd'");
401 break;
402 }
403 }
404}
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
409template <typename DataType> void Array2DataT<DataType>::
410fillDefault()
411{
412 m_value.fill(DataType());
413}
414
415/*---------------------------------------------------------------------------*/
416/*---------------------------------------------------------------------------*/
417
418template <typename DataType> void Array2DataT<DataType>::
419setName(const String& name)
420{
421 m_value.setDebugName(name);
422}
423
424/*---------------------------------------------------------------------------*/
425/*---------------------------------------------------------------------------*/
426
427template <typename DataType> void Array2DataT<DataType>::
428computeHash(IHashAlgorithm* algo, ByteArray& output) const
429{
430 //TODO: switch to 64 bits
431 Span<const DataType> values = m_value.to1DSpan();
432
433 // Calculates the hashing function for the values
434 Int64 type_size = sizeof(DataType);
435 Int64 nb_element = values.size();
436 const Byte* ptr = reinterpret_cast<const Byte*>(values.data());
437 Span<const Byte> input(ptr, type_size * nb_element);
438 algo->computeHash64(input, output);
439
440 // Calculates the hashing function for the sizes
441 UniqueArray<Int64> dimensions(2);
442 dimensions[0] = m_value.dim1Size();
443 dimensions[1] = m_value.dim2Size();
444 ptr = reinterpret_cast<const Byte*>(dimensions.data());
445 Int64 array_len = dimensions.size() * sizeof(Int64);
446 input = Span<const Byte>(ptr, array_len);
447 algo->computeHash64(input, output);
448}
449
450/*---------------------------------------------------------------------------*/
451/*---------------------------------------------------------------------------*/
452
453template <typename DataType> void Array2DataT<DataType>::
454computeHash(DataHashInfo& hash_info) const
455{
456 hash_info.setVersion(2);
457 IHashAlgorithmContext* context = hash_info.context();
458
459 // Calculates the hashing function for the sizes
460 Int64 dimensions[2];
461 dimensions[0] = m_value.dim1Size();
462 dimensions[1] = m_value.dim2Size();
463 Span<const Int64> dimension_span(dimensions, 2);
464 context->updateHash(asBytes(dimension_span));
465
466 // Calculates the hashing function for the values
467 context->updateHash(asBytes(m_value.to1DSpan()));
468}
469
470/*---------------------------------------------------------------------------*/
471/*---------------------------------------------------------------------------*/
472
473template <typename DataType> void Array2DataT<DataType>::
474copy(const IData* data)
475{
476 auto* true_data = dynamic_cast<const DataInterfaceType*>(data);
477 if (!true_data)
478 throw ArgumentException(A_FUNCINFO, "Can not cast 'IData' to 'IArray2DataT'");
479 m_value.copy(true_data->view());
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
485template <typename DataType> void Array2DataT<DataType>::
486swapValues(IData* data)
487{
488 auto* true_data = dynamic_cast<ThatClass*>(data);
489 if (!true_data)
490 throw ArgumentException(A_FUNCINFO, "Can not cast 'IData' to 'Array2DataT'");
491 swapValuesDirect(true_data);
492}
493
494/*---------------------------------------------------------------------------*/
495/*---------------------------------------------------------------------------*/
496
497template <typename DataType> void Array2DataT<DataType>::
498swapValuesDirect(ThatClass* true_data)
499{
500 m_value.swap(true_data->m_value);
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
506template <typename DataType> void Array2DataT<DataType>::
507setAllocationInfo(const DataAllocationInfo& v)
508{
509 if (m_allocation_info == v)
510 return;
511 m_allocation_info = v;
512 m_value.setMemoryLocationHint(v.memoryLocationHint());
513}
514
515/*---------------------------------------------------------------------------*/
516/*---------------------------------------------------------------------------*/
517
518template <typename DataType> void Array2DataT<DataType>::
520{
521 m_value.changeAllocator(alloc_info);
522 m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint());
523}
524
525/*---------------------------------------------------------------------------*/
526/*---------------------------------------------------------------------------*/
527
528} // End namespace Arcane
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Memory and allocator management functions.
Integer size() const
Number of elements in the vector.
Memory allocator with specific memory alignment.
Two-dimensional array data of type DataType.
Definition Array2Data.h:50
UniqueArray2< DataType > m_value
Data.
Definition Array2Data.h:147
eDataType dataType() const override
Data type.
Definition Array2Data.h:71
ArrayShape shape() const override
Array shape for a 1D or 2D data item.
Definition Array2Data.h:105
void resize(Int64 s)
Changes the number of elements in the array to s.
const T * data() const
Access to the root of the array without any protection.
ArrayView< T > view() const
Mutable view of this array.
constexpr Integer size() const noexcept
Number of elements in the array.
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
Context for calculating a hash incrementally.
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 Int64ConstArrayView extents() const =0
Array containing the number of elements for each dimension.
virtual bool isMultiSize() const =0
Indicates if it is a multi-size array. (only relevant if nbDimension()>1).
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.
Reference to an instance.
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
Definition Span.h:539
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.
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
std::int32_t Int32
Signed integer type of 32 bits.