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