Arcane  v3.15.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Array2Data.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/* Array2Data.inst.h (C) 2000-2024 */
9/* */
10/* Donnée du 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"
28
29#include "arcane/core/datatype/DataStorageBuildInfo.h"
30#include "arcane/core/datatype/IDataOperation.h"
31
32#include "arcane/core/ISerializer.h"
33
34#include "arcane/impl/SerializedData.h"
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39namespace Arcane
40{
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace
46{
47inline constexpr Int64 SERIALIZE2_MAGIC_NUMBER = 0x12ff7789;
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53template<typename DataType> Array2DataT<DataType>::
54Array2DataT(ITraceMng* trace)
55: m_value(AlignedMemoryAllocator::Simd())
56, m_trace(trace)
57, m_internal(new Impl(this))
58{
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64template<typename DataType> Array2DataT<DataType>::
65Array2DataT(const Array2DataT<DataType>& rhs)
66: m_value(AlignedMemoryAllocator::Simd())
67, m_trace(rhs.m_trace)
68, m_internal(new Impl(this))
69, m_allocation_info(rhs.m_allocation_info)
70{
71 m_value = rhs.m_value;
72}
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77template<typename DataType> Array2DataT<DataType>::
78Array2DataT(const DataStorageBuildInfo& dsbi)
79: m_value(dsbi.memoryAllocator())
80, m_trace(dsbi.traceMng())
81, m_internal(new Impl(this))
82{
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88template<typename DataType> Array2DataT<DataType>::
89~Array2DataT()
90{
91 delete m_internal;
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100template<typename DataType> DataStorageTypeInfo Array2DataT<DataType>::
101staticStorageTypeInfo()
102{
103 typedef DataTypeTraitsT<DataType> TraitsType;
104 eBasicDataType bdt = TraitsType::basicDataType();
105 Int32 nb_basic_type = TraitsType::nbBasicType();
106 Int32 dimension = 2;
107 Int32 multi_tag = 0;
108 return DataStorageTypeInfo(bdt,nb_basic_type,dimension,multi_tag);
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
115storageTypeInfo() const
116{
117 return staticStorageTypeInfo();
118}
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122
123template<typename DataType> void Array2DataT<DataType>::
124resize(Integer new_size)
125{
126 m_value.resize(new_size);
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
134{
135 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
136
137 Int64 nb_count = 1;
138 eDataType data_type = dataType();
139 Int64 type_size = sizeof(DataType);
140
141 if (use_basic_type){
144 type_size = sizeof(BasicType);
145 }
146
147 Int64 nb_element = m_value.totalNbElement();
150 const Byte* bt = reinterpret_cast<const Byte*>(m_value.to1DSpan().data());
152 UniqueArray<Int64> dimensions;
153 dimensions.resize(2);
154 dimensions[0] = m_value.dim1Size();
155 dimensions[1] = m_value.dim2Size();
156
158 nb_base_element,false,dimensions,shape());
159 sd->setConstBytes(base_values);
160 return sd;
161}
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
166template<typename DataType> void Array2DataT<DataType>::
168{
169 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
170
171 eDataType data_type = sdata->baseDataType();
173
174 if (data_type!=dataType() && data_type==base_data_type)
175 ARCANE_FATAL("Bad serialized type");
176 bool is_multi_size = sdata->isMultiSize();
177 if (is_multi_size)
178 ARCANE_FATAL("Can not allocate multi-size array");
179
180 Int64 dim1_size = sdata->extents()[0];
181 Int64 dim2_size = sdata->extents()[1];
182 //m_trace->info() << " ASSIGN DATA dim1=" << dim1_size
183 // << " dim2=" << dim2_size
184 // << " addr=" << m_value.viewAsArray().unguardedBasePointer();
185
186 m_value.resize(dim1_size,dim2_size);
187 m_shape = sdata->shape();
188
189 Byte* byte_data = reinterpret_cast<Byte*>(m_value.to1DSpan().data());
190 Span<Byte> bytes_view(byte_data,sdata->memorySize());
191 sdata->setWritableBytes(bytes_view);
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
197template<typename DataType> void Array2DataT<DataType>::
199{
200 ARCANE_UNUSED(sdata);
201 // Rien à faire car \a sdata pointe directement vers m_value
202}
203
204/*---------------------------------------------------------------------------*/
205/*---------------------------------------------------------------------------*/
206
207template<typename DataType> void Array2DataT<DataType>::
209{
211 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
213
214 ISerializer::eMode mode = sbuf->mode();
215 if (mode==ISerializer::ModeReserve){
216 // Réserve la mémoire pour
217 // - le nombre d'éléments de la première dimension
218 // - le nombre d'éléments de la deuxième dimension
219 // - le nombre d'éléments de ids.
220 // - le nombre magique pour verification
221 sbuf->reserveSpan(eBasicDataType::Int64,4);
222 // Réserve la mémoire pour les valeurs
223 Int64 total_nb_element = m_value.totalNbElement();
225 }
226 else if (mode==ISerializer::ModePut){
227 Int64 count = m_value.dim1Size();
228 Int64 total = m_value.totalNbElement();
229 Int64 n[4];
230 n[0] = count;
231 n[1] = m_value.dim2Size();
232 n[2] = total;
234 sbuf->putSpan(Span<const Int64>(n,4));
235 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data());
237 //m_trace->info() << "PUT array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType);
238 sbuf->putSpan(v);
239 }
240 else if (mode==ISerializer::ModeGet){
241 Int64 n[4] = { 0, 0, 0, 0 };
242 sbuf->getSpan(Span<Int64>(n,4));
243 Int64 count = n[0];
244 Int64 dim2_size = n[1];
245 Int64 total = n[2];
246 if (n[3]!=SERIALIZE2_MAGIC_NUMBER)
247 ARCANE_FATAL("Bad magic number");
248 switch(sbuf->readMode()){
249 case ISerializer::ReadReplace:
250 {
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 }
259 break;
260 case ISerializer::ReadAdd:
261 {
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 }
275 break;
276 }
277 }
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283template<typename DataType> void Array2DataT<DataType>::
285{
287 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
289
290 ISerializer::eMode mode = sbuf->mode();
291 if (mode==ISerializer::ModeReserve){
292 // Réserve la mémoire pour
293 // - le nombre d'éléments de la première dimension
294 // - le nombre d'éléments de la deuxième dimension
295 // - le nombre d'éléments de ids.
296 // - le nombre magique pour verification
297 sbuf->reserveSpan(eBasicDataType::Int64,4);
298 // Réserve la mémoire pour les valeurs
299 Int64 total_nb_value = ((Int64)ids.size()) * ((Int64)m_value.dim2Size());
301
302 }
303 else if (mode==ISerializer::ModePut){
304 Int32 count = ids.size();
305 Int64 dim2_size = m_value.dim2Size();
306 Int64 total_nb_value = count * dim2_size;
307 Int64 total = total_nb_value;
308 Int64 n[4];
309 n[0] = m_value.dim1Size();
310 n[1] = m_value.dim2Size();
311 n[2] = count;
313 /*m_trace->info() << "PUT COUNT = " << count << " total=" << total
314 << " dim1 (n[0])=" << n[0]
315 << " dim2 (n[1])=" << n[1]
316 << " count (n[2])=" << n[2]
317 << " magic=" << n[3]
318 << " this=" << this;*/
319 sbuf->putSpan(Span<const Int64>(n,4));
321 {
322 Integer index = 0;
323 for( Int32 i=0, is=count; i<is; ++i ){
324 const BasicType* sub_a = reinterpret_cast<const BasicType*>(m_value[ids[i]].data());
325 for( Int64 z=0, iz=dim2_size*nb_count; z<iz; ++z ){
326 v[index] = sub_a[z];
327 ++index;
328 }
329 }
330 }
331 sbuf->putSpan(v);
332 }
333 else if (mode==ISerializer::ModeGet){
334 switch(sbuf->readMode()){
335 case ISerializer::ReadReplace:
336 {
337 Int64 n[4] = { 0, 0, 0, 0 };
338 sbuf->getSpan(Span<Int64>(n,4));
339 //Integer dim1_size = n[0];
340 Int64 dim2_size = n[1];
341 Int32 count = CheckedConvert::toInt32(n[2]);
342 Int64 total = count * dim2_size;
343 // One dim
344 /*m_trace->info() << "COUNT = " << count << " total=" << total
345 << " dim1 (n[0])=" << n[0]
346 << " dim1 current=" << m_value.dim1Size()
347 << " dim2 (n[1])=" << n[1]
348 << " dim2 current=" << m_value.dim2Size()
349 << " count (n[2])=" << n[2]
350 << " magic=" << n[3]
351 << " this=" << this;*/
352 if (n[3]!=SERIALIZE2_MAGIC_NUMBER)
353 ARCANE_FATAL("Bad magic number");
354 Int64 current_dim2_size = m_value.dim2Size();
355 if (dim2_size!=current_dim2_size){
356 if (current_dim2_size!=0 && dim2_size!=0)
357 ARCANE_FATAL("serialized data should have the same dim2Size current={0} found={1}",
358 current_dim2_size,dim2_size);
359 else
360 m_value.resize(m_value.dim1Size(),dim2_size);
361 }
362 Int64 nb_value = count;
363 //Array<BasicType> v(total*nb_count);
365
366 sbuf->getSpan(base_value);
367
368 Span<DataType> data_value(reinterpret_cast<DataType*>(base_value.data()),nb_value*dim2_size);
371
372 // Si on applique une transformantion, effectue la transformation dans un
373 // tableau temporaire 'current_value'.
374 if (operation && nb_value!=0) {
375 current_value.resize(data_value.size());
376
377 Int64 index = 0;
378 for( Int32 i=0, n=count; i<n; ++i ){
379 Span<const DataType> a(m_value[ids[i]]);
380 for( Int64 z=0, iz=dim2_size; z<iz; ++z ){
381 current_value[index] = a[z];
382 ++index;
383 }
384 }
385
387 operation->applySpan(transformed_value,data_value);
388 }
389 else {
390 transformed_value = data_value;
391 }
392
393 {
394 Int64 index = 0;
395 for( Int32 i=0, n=count; i<n; ++i ){
396 Span<DataType> a(m_value[ids[i]]);
397 for( Int64 z=0, iz=dim2_size; z<iz; ++z ){
398 a[z] = transformed_value[index];
399 ++index;
400 }
401 }
402 }
403 }
404 break;
405 case ISerializer::ReadAdd:
406 throw NotImplementedException(A_FUNCINFO,"option 'ReadAdd'");
407 break;
408 }
409 }
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
415template<typename DataType> void Array2DataT<DataType>::
417{
418 m_value.fill(DataType());
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
424template<typename DataType> void Array2DataT<DataType>::
425setName(const String& name)
426{
427 m_value.setDebugName(name);
428}
429
430/*---------------------------------------------------------------------------*/
431/*---------------------------------------------------------------------------*/
432
433template<typename DataType> void Array2DataT<DataType>::
435{
436 //TODO: passer en 64 bits
437 Span<const DataType> values = m_value.to1DSpan();
438
439 // Calcule la fonction de hashage pour les valeurs
440 Int64 type_size = sizeof(DataType);
441 Int64 nb_element = values.size();
442 const Byte* ptr = reinterpret_cast<const Byte*>(values.data());
444 algo->computeHash64(input,output);
445
446 // Calcule la fonction de hashage pour les tailles
447 UniqueArray<Int64> dimensions(2);
448 dimensions[0] = m_value.dim1Size();
449 dimensions[1] = m_value.dim2Size();
450 ptr = reinterpret_cast<const Byte*>(dimensions.data());
451 Int64 array_len = dimensions.size() * sizeof(Int64);
453 algo->computeHash64(input,output);
454}
455
456/*---------------------------------------------------------------------------*/
457/*---------------------------------------------------------------------------*/
458
459template<typename DataType> void Array2DataT<DataType>::
461{
462 hash_info.setVersion(2);
463 IHashAlgorithmContext* context = hash_info.context();
464
465 // Calcule la fonction de hashage pour les tailles
466 Int64 dimensions[2];
467 dimensions[0] = m_value.dim1Size();
468 dimensions[1] = m_value.dim2Size();
469 Span<const Int64> dimension_span(dimensions,2);
470 context->updateHash(asBytes(dimension_span));
471
472 // Calcule la fonction de hashage pour les valeurs
473 context->updateHash(asBytes(m_value.to1DSpan()));
474}
475
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478
479template<typename DataType> void Array2DataT<DataType>::
480copy(const IData* data)
481{
482 auto* true_data = dynamic_cast< const DataInterfaceType* >(data);
483 if (!true_data)
484 throw ArgumentException(A_FUNCINFO,"Can not cast 'IData' to 'IArray2DataT'");
485 m_value.copy(true_data->view());
486}
487
488/*---------------------------------------------------------------------------*/
489/*---------------------------------------------------------------------------*/
490
491template<typename DataType> void Array2DataT<DataType>::
492swapValues(IData* data)
493{
494 auto* true_data = dynamic_cast<ThatClass*>(data);
495 if (!true_data)
496 throw ArgumentException(A_FUNCINFO,"Can not cast 'IData' to 'Array2DataT'");
497 swapValuesDirect(true_data);
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503template<typename DataType> void Array2DataT<DataType>::
504swapValuesDirect(ThatClass* true_data)
505{
506 m_value.swap(true_data->m_value);
507}
508
509/*---------------------------------------------------------------------------*/
510/*---------------------------------------------------------------------------*/
511
512template<typename DataType> void Array2DataT<DataType>::
514{
515 if (m_allocation_info==v)
516 return;
517 m_allocation_info = v;
518 m_value.setMemoryLocationHint(v.memoryLocationHint());
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
523
524template<typename DataType> void Array2DataT<DataType>::
526{
527 ARCANE_UNUSED(alloc_info);
528 ARCANE_THROW(NotImplementedException,"changeAllocator for 2D Array");
529}
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
533
534} // End namespace Arcane
535
536/*---------------------------------------------------------------------------*/
537/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Donnée tableau bi-dimensionnel d'un type DataType.
Definition Array2Data.h:49
void resize(Integer new_size) override
Redimensionne la donnée.
Tableau d'items de types quelconques.
Informations sur l'allocation d'une donnée.
Informations pour le calcul du hash d'une donnée.
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
Contexte pour calculer un hash de manière incrémentale.
virtual void updateHash(Span< const std::byte > input)=0
Ajoute le tableau input au hash calculé
Interface d'un algorithme de hashage.
Interface d'une donnée sérialisée.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
Exception lorsqu'un argument est invalide.
Vue constante d'un tableau de type T.
Options pour configurer les allocations.
Exception lorsqu'une fonction n'est pas implémentée.
Chaîne de caractères unicode.
-*- 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.
eDataType
Type d'une donnée.
Definition DataTypes.h:39
eBasicDataType
Type d'une donnée de base.