diff --git a/arcane/src/arcane/core/datatype/DataTypes.h b/arcane/src/arcane/core/datatype/DataTypes.h index 744a067e53..c44159516e 100644 --- a/arcane/src/arcane/core/datatype/DataTypes.h +++ b/arcane/src/arcane/core/datatype/DataTypes.h @@ -197,20 +197,32 @@ enum eTraceType } // End namespace Arcane // Macro pour instantier une classe template pour tous les types numériques -#define ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE(class_name)\ +#define ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE1(class_name)\ template class class_name ;\ template class class_name ;\ template class class_name ;\ template class class_name ;\ -template class class_name ;\ -template class class_name ;\ -template class class_name ;\ -template class class_name ;\ +template class class_name ; + +// Macro pour instantier une classe template pour tous les types numériques +#define ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE2(class_name)\ template class class_name ;\ template class class_name ;\ template class class_name ;\ template class class_name ;\ -template class class_name ; +template class class_name + +// Macro pour instantier une classe template pour tous les types numériques +#define ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE3(class_name)\ +template class class_name ;\ +template class class_name ;\ +template class class_name ; + +// Macro pour instantier une classe template pour tous les types numériques +#define ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE(class_name)\ + ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE1(class_name);\ + ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE2(class_name);\ + ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE3(class_name) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/Array2Data.cc b/arcane/src/arcane/impl/Array2Data.cc index 0dc0ec9f1d..68cfd629fd 100644 --- a/arcane/src/arcane/impl/Array2Data.cc +++ b/arcane/src/arcane/impl/Array2Data.cc @@ -11,39 +11,10 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arccore/base/ReferenceCounterImpl.h" -#include "arccore/base/Ref.h" +#include "arcane/impl/internal/Array2Data.h" -#include "arcane/utils/IDataCompressor.h" -#include "arcane/utils/Array2.h" -#include "arcane/utils/NotSupportedException.h" -#include "arcane/utils/Real2.h" -#include "arcane/utils/Real2x2.h" -#include "arcane/utils/Real3.h" -#include "arcane/utils/Real3x3.h" -#include "arcane/utils/IHashAlgorithm.h" -#include "arcane/utils/NotImplementedException.h" -#include "arcane/utils/ArgumentException.h" -#include "arcane/utils/FatalErrorException.h" -#include "arcane/utils/ITraceMng.h" -#include "arcane/utils/CheckedConvert.h" -#include "arcane/utils/ArrayShape.h" -#include "arcane/utils/MemoryAllocator.h" -#include "arcane/utils/MemoryView.h" +#include "arcane/utils/NumericTypes.h" -#include "arcane/core/datatype/DataAllocationInfo.h" -#include "arcane/core/datatype/DataStorageBuildInfo.h" -#include "arcane/core/datatype/IDataOperation.h" -#include "arcane/core/datatype/DataStorageTypeInfo.h" -#include "arcane/core/datatype/DataTypeTraits.h" - -#include "arcane/core/ISerializer.h" -#include "arcane/core/IData.h" -#include "arcane/core/IDataVisitor.h" - -#include "arcane/core/internal/IDataInternal.h" - -#include "arcane/impl/SerializedData.h" #include "arcane/impl/DataStorageFactory.h" /*---------------------------------------------------------------------------*/ @@ -52,692 +23,6 @@ namespace Arcane { -namespace -{ - const Int64 SERIALIZE2_MAGIC_NUMBER = 0x12ff7789; -} - - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -/*! - * \brief Donnée tableau bi-dimensionnel d'un type \a DataType - */ -template -class Array2DataT -: public ReferenceCounterImpl -, public IArray2DataT -{ - ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(); - class Impl; - friend class Impl; - - public: - - typedef Array2DataT ThatClass; - typedef IArray2DataT DataInterfaceType; - - public: - - explicit Array2DataT(ITraceMng* trace); - explicit Array2DataT(const DataStorageBuildInfo& dsbi); - Array2DataT(const Array2DataT& rhs); - ~Array2DataT() override; - - public: - - Integer dimension() const override { return 2; } - Integer multiTag() const override { return 0; } - eDataType dataType() const override { return DataTypeTraitsT::type(); } - void serialize(ISerializer* sbuf, IDataOperation* operation) override; - void serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation) override; - Array2& value() override { return m_value; } - const Array2& value() const override { return m_value; } - Array2View view() override { return m_value; } - ConstArray2View view() const override { return m_value; } - void resize(Integer new_size) override; - IData* clone() override { return _cloneTrue(); } - IData* cloneEmpty() override { return _cloneTrueEmpty(); }; - Ref cloneRef() override { return makeRef(cloneTrue()); } - Ref cloneEmptyRef() override { return makeRef(cloneTrueEmpty()); } - DataStorageTypeInfo storageTypeInfo() const override; - DataInterfaceType* cloneTrue() override { return _cloneTrue(); } - DataInterfaceType* cloneTrueEmpty() override { return _cloneTrueEmpty(); } - Ref cloneTrueRef() override { auto* d = _cloneTrue(); return makeRef(d); } - Ref cloneTrueEmptyRef() override { auto* d = _cloneTrueEmpty(); return makeRef(d); } - void fillDefault() override; - void setName(const String& name) override; - Ref createSerializedDataRef(bool use_basic_type) const override; - void allocateBufferForSerializedData(ISerializedData* sdata) override; - void assignSerializedData(const ISerializedData* sdata) override; - void copy(const IData* data) override; - void swapValues(IData* data) override; - void computeHash(IHashAlgorithm* algo, ByteArray& output) const override; - void computeHash(DataHashInfo& hash_algo) const; - ArrayShape shape() const override { return m_shape; } - void setShape(const ArrayShape& new_shape) override { m_shape = new_shape; } - void setAllocationInfo(const DataAllocationInfo& v) override; - DataAllocationInfo allocationInfo() const override { return m_allocation_info; } - - void visit(IArray2DataVisitor* visitor) - { - visitor->applyVisitor(this); - } - void visit(IDataVisitor* visitor) override - { - visitor->applyDataVisitor(this); - } - void visitScalar(IScalarDataVisitor*) override - { - ARCANE_THROW(NotSupportedException, "Can not visit scalar data with array2 data"); - } - void visitArray(IArrayDataVisitor*) override - { - ARCANE_THROW(NotSupportedException, "Can not visit array data with array2 data"); - } - void visitArray2(IArray2DataVisitor* visitor) override - { - visitor->applyVisitor(this); - } - - public: - - void swapValuesDirect(ThatClass* true_data); - void changeAllocator(const MemoryAllocationOptions& alloc_info); - - public: - - IArray2DataInternalT* _internal() override { return m_internal; } - IDataInternal* _commonInternal() override { return m_internal; } - - public: - - static DataStorageTypeInfo staticStorageTypeInfo(); - - private: - - UniqueArray2 m_value; //!< Donnée - ITraceMng* m_trace; - IArray2DataInternalT* m_internal; - ArrayShape m_shape; - DataAllocationInfo m_allocation_info; - - private: - - IArray2DataT* _cloneTrue() const { return new ThatClass(*this); } - IArray2DataT* _cloneTrueEmpty() const { return new ThatClass(m_trace); } -}; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template -class Array2DataT::Impl -: public IArray2DataInternalT -, public INumericDataInternal -{ - public: - - explicit Impl(Array2DataT* p) : m_p(p){} - - public: - - void reserve(Integer new_capacity) override { m_p->m_value.reserve(new_capacity); } - void resizeOnlyDim1(Int32 new_dim1_size) override - { - m_p->m_value.resize(new_dim1_size,m_p->m_value.dim2Size()); - } - void resize(Int32 new_dim1_size, Int32 new_dim2_size) override - { - if (new_dim1_size < 0) - ARCANE_FATAL("Bad value '{0}' for dim1_size", new_dim1_size); - if (new_dim2_size < 0) - ARCANE_FATAL("Bad value '{0}' for dim2_size", new_dim2_size); - // Cette méthode est appelée si on modifie la deuxième dimension. - // Dans ce cas cela invalide l'ancienne valeur de shape. - bool need_reshape = false; - if (new_dim2_size != m_p->m_value.dim2Size()) - need_reshape = true; - m_p->m_value.resize(new_dim1_size, new_dim2_size); - if (need_reshape) { - m_p->m_shape.setNbDimension(1); - m_p->m_shape.setDimension(0, new_dim2_size); - } - } - Array2& _internalDeprecatedValue() override { return m_p->m_value; } - void shrink() const override { m_p->m_value.shrink(); } - bool compressAndClear(DataCompressionBuffer& buf) override - { - IDataCompressor* compressor = buf.m_compressor; - if (!compressor) - return false; - Span values = m_p->m_value.to1DSpan(); - Span bytes = asBytes(values); - compressor->compress(bytes,buf.m_buffer); - buf.m_original_dim1_size = m_p->m_value.dim1Size(); - buf.m_original_dim2_size = m_p->m_value.dim2Size(); - m_p->m_value.clear(); - m_p->m_value.shrink(); - return true; - } - bool decompressAndFill(DataCompressionBuffer& buf) override - { - IDataCompressor* compressor = buf.m_compressor; - if (!compressor) - return false; - m_p->m_value.resize(buf.m_original_dim1_size,buf.m_original_dim2_size); - Span values = m_p->m_value.to1DSpan(); - compressor->decompress(buf.m_buffer,asWritableBytes(values)); - return true; - } - - MutableMemoryView memoryView() override - { - Array2View value = m_p->view(); - Int32 dim1_size = value.dim1Size(); - Int32 dim2_size = value.dim2Size(); - DataStorageTypeInfo storage_info = m_p->storageTypeInfo(); - Int32 nb_basic_element = storage_info.nbBasicElement(); - Int32 datatype_size = basicDataTypeSize(storage_info.basicDataType()) * nb_basic_element; - return makeMutableMemoryView(value.data(), datatype_size * dim2_size, dim1_size); - } - Int32 extent0() const override - { - return m_p->view().dim1Size(); - } - INumericDataInternal* numericData() override { return this; } - void changeAllocator(const MemoryAllocationOptions& v) override { m_p->changeAllocator(v); } - void computeHash(DataHashInfo& hash_info) override - { - m_p->computeHash(hash_info); - } - - private: - - Array2DataT* m_p; -}; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template Array2DataT:: -Array2DataT(ITraceMng* trace) -: m_value(AlignedMemoryAllocator::Simd()) -, m_trace(trace) -, m_internal(new Impl(this)) -{ -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template Array2DataT:: -Array2DataT(const Array2DataT& rhs) -: m_value(AlignedMemoryAllocator::Simd()) -, m_trace(rhs.m_trace) -, m_internal(new Impl(this)) -, m_allocation_info(rhs.m_allocation_info) -{ - m_value = rhs.m_value; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template Array2DataT:: -Array2DataT(const DataStorageBuildInfo& dsbi) -: m_value(dsbi.memoryAllocator()) -, m_trace(dsbi.traceMng()) -, m_internal(new Impl(this)) -{ -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template Array2DataT:: -~Array2DataT() -{ - delete m_internal; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template DataStorageTypeInfo Array2DataT:: -staticStorageTypeInfo() -{ - typedef DataTypeTraitsT TraitsType; - eBasicDataType bdt = TraitsType::basicDataType(); - Int32 nb_basic_type = TraitsType::nbBasicType(); - Int32 dimension = 2; - Int32 multi_tag = 0; - return DataStorageTypeInfo(bdt,nb_basic_type,dimension,multi_tag); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template DataStorageTypeInfo Array2DataT:: -storageTypeInfo() const -{ - return staticStorageTypeInfo(); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -resize(Integer new_size) -{ - m_value.resize(new_size); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template Ref Array2DataT:: -createSerializedDataRef(bool use_basic_type) const -{ - typedef typename DataTypeTraitsT::BasicType BasicType; - - Int64 nb_count = 1; - eDataType data_type = dataType(); - Int64 type_size = sizeof(DataType); - - if (use_basic_type){ - nb_count = DataTypeTraitsT::nbBasicType(); - data_type = DataTypeTraitsT::type(); - type_size = sizeof(BasicType); - } - - Int64 nb_element = m_value.totalNbElement(); - Int64 nb_base_element = nb_element * nb_count; - Int64 full_size = nb_base_element * type_size; - const Byte* bt = reinterpret_cast(m_value.to1DSpan().data()); - Span base_values(bt,full_size); - UniqueArray dimensions; - dimensions.resize(2); - dimensions[0] = m_value.dim1Size(); - dimensions[1] = m_value.dim2Size(); - - auto sd = arcaneCreateSerializedDataRef(data_type,base_values.size(),2,nb_element, - nb_base_element,false,dimensions,shape()); - sd->setConstBytes(base_values); - return sd; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -allocateBufferForSerializedData(ISerializedData* sdata) -{ - typedef typename DataTypeTraitsT::BasicType BasicType; - - eDataType data_type = sdata->baseDataType(); - eDataType base_data_type = DataTypeTraitsT::type(); - - if (data_type!=dataType() && data_type==base_data_type) - ARCANE_FATAL("Bad serialized type"); - bool is_multi_size = sdata->isMultiSize(); - if (is_multi_size) - ARCANE_FATAL("Can not allocate multi-size array"); - - Int64 dim1_size = sdata->extents()[0]; - Int64 dim2_size = sdata->extents()[1]; - //m_trace->info() << " ASSIGN DATA dim1=" << dim1_size - // << " dim2=" << dim2_size - // << " addr=" << m_value.viewAsArray().unguardedBasePointer(); - - m_value.resize(dim1_size,dim2_size); - m_shape = sdata->shape(); - - Byte* byte_data = reinterpret_cast(m_value.to1DSpan().data()); - Span bytes_view(byte_data,sdata->memorySize()); - sdata->setWritableBytes(bytes_view); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -assignSerializedData(const ISerializedData* sdata) -{ - ARCANE_UNUSED(sdata); - // Rien à faire car \a sdata pointe directement vers m_value -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -serialize(ISerializer* sbuf,IDataOperation* operation) -{ - Integer nb_count = DataTypeTraitsT::nbBasicType(); - typedef typename DataTypeTraitsT::BasicType BasicType; - eBasicDataType data_type = DataTypeTraitsT::basicDataType(); - - ISerializer::eMode mode = sbuf->mode(); - if (mode==ISerializer::ModeReserve){ - // Réserve la mémoire pour - // - le nombre d'éléments de la première dimension - // - le nombre d'éléments de la deuxième dimension - // - le nombre d'éléments de ids. - // - le nombre magique pour verification - sbuf->reserveSpan(eBasicDataType::Int64,4); - // Réserve la mémoire pour les valeurs - Int64 total_nb_element = m_value.totalNbElement(); - sbuf->reserveSpan(data_type,total_nb_element*nb_count); - } - else if (mode==ISerializer::ModePut){ - Int64 count = m_value.dim1Size(); - Int64 total = m_value.totalNbElement(); - Int64 n[4]; - n[0] = count; - n[1] = m_value.dim2Size(); - n[2] = total; - n[3] = SERIALIZE2_MAGIC_NUMBER; - sbuf->putSpan(Span(n,4)); - BasicType* bt = reinterpret_cast(m_value.to1DSpan().data()); - Span v(bt,total*nb_count); - //m_trace->info() << "PUT array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType); - sbuf->putSpan(v); - } - else if (mode==ISerializer::ModeGet){ - Int64 n[4] = { 0, 0, 0, 0 }; - sbuf->getSpan(Span(n,4)); - Int64 count = n[0]; - Int64 dim2_size = n[1]; - Int64 total = n[2]; - if (n[3]!=SERIALIZE2_MAGIC_NUMBER) - ARCANE_FATAL("Bad magic number"); - switch(sbuf->readMode()){ - case ISerializer::ReadReplace: - { - //m_trace->info() << "READ REPLACE count=" << count << " dim2_size=" << dim2_size; - m_value.resize(count,dim2_size); - if (operation) - throw NotImplementedException(A_FUNCINFO,"serialize(ReadReplace) with IDataOperation"); - BasicType* bt = reinterpret_cast(m_value.to1DSpan().data()); - Span v(bt,total*nb_count); - sbuf->getSpan(v); - } - break; - case ISerializer::ReadAdd: - { - Int64 current_size = m_value.dim1Size(); - Int64 current_total = m_value.totalNbElement(); - //m_trace->info() << "READ ADD NEW_SIZE=" << current_size << " COUNT=" << count - // << " dim2_size=" << dim2_size << " current_dim2_size=" << m_value.dim2Size() - // << " current_total=" << current_total << " read_elem=" << (total*nb_count); - m_value.resize(current_size + count,dim2_size); - if (operation) - throw NotImplementedException(A_FUNCINFO,"serialize(ReadAdd) with IDataOperation"); - BasicType* bt = reinterpret_cast(m_value.to1DSpan().data()+current_total); - //m_trace->info() << "GET array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType); - Span v(bt,total*nb_count); - sbuf->getSpan(v); - } - break; - } - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -serialize(ISerializer* sbuf,Int32ConstArrayView ids,IDataOperation* operation) -{ - Integer nb_count = DataTypeTraitsT::nbBasicType(); - typedef typename DataTypeTraitsT::BasicType BasicType; - eBasicDataType data_type = DataTypeTraitsT::basicDataType(); - - ISerializer::eMode mode = sbuf->mode(); - if (mode==ISerializer::ModeReserve){ - // Réserve la mémoire pour - // - le nombre d'éléments de la première dimension - // - le nombre d'éléments de la deuxième dimension - // - le nombre d'éléments de ids. - // - le nombre magique pour verification - sbuf->reserveSpan(eBasicDataType::Int64,4); - // Réserve la mémoire pour les valeurs - Int64 total_nb_value = ((Int64)ids.size()) * ((Int64)m_value.dim2Size()); - sbuf->reserveSpan(data_type,total_nb_value*nb_count); - - } - else if (mode==ISerializer::ModePut){ - Int32 count = ids.size(); - Int64 dim2_size = m_value.dim2Size(); - Int64 total_nb_value = count * dim2_size; - Int64 total = total_nb_value; - Int64 n[4]; - n[0] = m_value.dim1Size(); - n[1] = m_value.dim2Size(); - n[2] = count; - n[3] = SERIALIZE2_MAGIC_NUMBER; - /*m_trace->info() << "PUT COUNT = " << count << " total=" << total - << " dim1 (n[0])=" << n[0] - << " dim2 (n[1])=" << n[1] - << " count (n[2])=" << n[2] - << " magic=" << n[3] - << " this=" << this;*/ - sbuf->putSpan(Span(n,4)); - UniqueArray v(total*nb_count); - { - Integer index = 0; - for( Int32 i=0, is=count; i(m_value[ids[i]].data()); - for( Int64 z=0, iz=dim2_size*nb_count; zputSpan(v); - } - else if (mode==ISerializer::ModeGet){ - switch(sbuf->readMode()){ - case ISerializer::ReadReplace: - { - Int64 n[4] = { 0, 0, 0, 0 }; - sbuf->getSpan(Span(n,4)); - //Integer dim1_size = n[0]; - Int64 dim2_size = n[1]; - Int32 count = CheckedConvert::toInt32(n[2]); - Int64 total = count * dim2_size; - // One dim - /*m_trace->info() << "COUNT = " << count << " total=" << total - << " dim1 (n[0])=" << n[0] - << " dim1 current=" << m_value.dim1Size() - << " dim2 (n[1])=" << n[1] - << " dim2 current=" << m_value.dim2Size() - << " count (n[2])=" << n[2] - << " magic=" << n[3] - << " this=" << this;*/ - if (n[3]!=SERIALIZE2_MAGIC_NUMBER) - ARCANE_FATAL("Bad magic number"); - Int64 current_dim2_size = m_value.dim2Size(); - if (dim2_size!=current_dim2_size){ - if (current_dim2_size!=0 && dim2_size!=0) - ARCANE_FATAL("serialized data should have the same dim2Size current={0} found={1}", - current_dim2_size,dim2_size); - else - m_value.resize(m_value.dim1Size(),dim2_size); - } - Int64 nb_value = count; - //Array v(total*nb_count); - UniqueArray base_value(total*nb_count); - - sbuf->getSpan(base_value); - - Span data_value(reinterpret_cast(base_value.data()),nb_value*dim2_size); - UniqueArray current_value; - Span transformed_value; - - // Si on applique une transformantion, effectue la transformation dans un - // tableau temporaire 'current_value'. - if (operation && nb_value!=0) { - current_value.resize(data_value.size()); - - Int64 index = 0; - for( Int32 i=0, n=count; i a(m_value[ids[i]]); - for( Int64 z=0, iz=dim2_size; zapplySpan(transformed_value,data_value); - } - else { - transformed_value = data_value; - } - - { - Int64 index = 0; - for( Int32 i=0, n=count; i a(m_value[ids[i]]); - for( Int64 z=0, iz=dim2_size; z void Array2DataT:: -fillDefault() -{ - m_value.fill(DataType()); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -setName(const String& name) -{ - m_value.setDebugName(name); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -computeHash(IHashAlgorithm* algo,ByteArray& output) const -{ - //TODO: passer en 64 bits - Span values = m_value.to1DSpan(); - - // Calcule la fonction de hashage pour les valeurs - Int64 type_size = sizeof(DataType); - Int64 nb_element = values.size(); - const Byte* ptr = reinterpret_cast(values.data()); - Span input(ptr,type_size*nb_element); - algo->computeHash64(input,output); - - // Calcule la fonction de hashage pour les tailles - UniqueArray dimensions(2); - dimensions[0] = m_value.dim1Size(); - dimensions[1] = m_value.dim2Size(); - ptr = reinterpret_cast(dimensions.data()); - Int64 array_len = dimensions.size() * sizeof(Int64); - input = Span(ptr,array_len); - algo->computeHash64(input,output); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -computeHash(DataHashInfo& hash_info) const -{ - hash_info.setVersion(2); - IHashAlgorithmContext* context = hash_info.context(); - - // Calcule la fonction de hashage pour les tailles - Int64 dimensions[2]; - dimensions[0] = m_value.dim1Size(); - dimensions[1] = m_value.dim2Size(); - Span dimension_span(dimensions,2); - context->updateHash(asBytes(dimension_span)); - - // Calcule la fonction de hashage pour les valeurs - context->updateHash(asBytes(m_value.to1DSpan())); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -copy(const IData* data) -{ - auto* true_data = dynamic_cast< const DataInterfaceType* >(data); - if (!true_data) - throw ArgumentException(A_FUNCINFO,"Can not cast 'IData' to 'IArray2DataT'"); - m_value.copy(true_data->view()); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -swapValues(IData* data) -{ - auto* true_data = dynamic_cast(data); - if (!true_data) - throw ArgumentException(A_FUNCINFO,"Can not cast 'IData' to 'Array2DataT'"); - swapValuesDirect(true_data); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -swapValuesDirect(ThatClass* true_data) -{ - m_value.swap(true_data->m_value); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -setAllocationInfo(const DataAllocationInfo& v) -{ - if (m_allocation_info==v) - return; - m_allocation_info = v; - m_value.setMemoryLocationHint(v.memoryLocationHint()); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void Array2DataT:: -changeAllocator(const MemoryAllocationOptions& alloc_info) -{ - ARCANE_UNUSED(alloc_info); - ARCANE_THROW(NotImplementedException,"changeAllocator for 2D Array"); -} - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -762,23 +47,6 @@ registerArray2DataFactory(IDataFactoryMng* dfm) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; -template class Array2DataT; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/Array2Data.h b/arcane/src/arcane/impl/Array2Data.h deleted file mode 100644 index fb6c02bc2f..0000000000 --- a/arcane/src/arcane/impl/Array2Data.h +++ /dev/null @@ -1,7 +0,0 @@ -// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- -//----------------------------------------------------------------------------- -// Copyright 2000-2021 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) -// See the top-level COPYRIGHT file for details. -// SPDX-License-Identifier: Apache-2.0 -//----------------------------------------------------------------------------- -#error "Do not include this file" diff --git a/arcane/src/arcane/impl/Array2Data.inst.h b/arcane/src/arcane/impl/Array2Data.inst.h new file mode 100644 index 0000000000..37007fb748 --- /dev/null +++ b/arcane/src/arcane/impl/Array2Data.inst.h @@ -0,0 +1,537 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* Array2Data.inst.h (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array2'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/internal/Array2Data.h" + +#include "arcane/utils/NotSupportedException.h" +#include "arcane/utils/Real2.h" +#include "arcane/utils/Real2x2.h" +#include "arcane/utils/Real3.h" +#include "arcane/utils/Real3x3.h" +#include "arcane/utils/IHashAlgorithm.h" +#include "arcane/utils/NotImplementedException.h" +#include "arcane/utils/ArgumentException.h" +#include "arcane/utils/FatalErrorException.h" +#include "arcane/utils/ITraceMng.h" +#include "arcane/utils/CheckedConvert.h" +#include "arcane/utils/MemoryAllocator.h" + +#include "arcane/core/datatype/DataStorageBuildInfo.h" +#include "arcane/core/datatype/IDataOperation.h" + +#include "arcane/core/ISerializer.h" + +#include "arcane/impl/SerializedData.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace +{ +inline constexpr Int64 SERIALIZE2_MAGIC_NUMBER = 0x12ff7789; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template Array2DataT:: +Array2DataT(ITraceMng* trace) +: m_value(AlignedMemoryAllocator::Simd()) +, m_trace(trace) +, m_internal(new Impl(this)) +{ +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template Array2DataT:: +Array2DataT(const Array2DataT& rhs) +: m_value(AlignedMemoryAllocator::Simd()) +, m_trace(rhs.m_trace) +, m_internal(new Impl(this)) +, m_allocation_info(rhs.m_allocation_info) +{ + m_value = rhs.m_value; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template Array2DataT:: +Array2DataT(const DataStorageBuildInfo& dsbi) +: m_value(dsbi.memoryAllocator()) +, m_trace(dsbi.traceMng()) +, m_internal(new Impl(this)) +{ +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template Array2DataT:: +~Array2DataT() +{ + delete m_internal; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template DataStorageTypeInfo Array2DataT:: +staticStorageTypeInfo() +{ + typedef DataTypeTraitsT TraitsType; + eBasicDataType bdt = TraitsType::basicDataType(); + Int32 nb_basic_type = TraitsType::nbBasicType(); + Int32 dimension = 2; + Int32 multi_tag = 0; + return DataStorageTypeInfo(bdt,nb_basic_type,dimension,multi_tag); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template DataStorageTypeInfo Array2DataT:: +storageTypeInfo() const +{ + return staticStorageTypeInfo(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +resize(Integer new_size) +{ + m_value.resize(new_size); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template Ref Array2DataT:: +createSerializedDataRef(bool use_basic_type) const +{ + typedef typename DataTypeTraitsT::BasicType BasicType; + + Int64 nb_count = 1; + eDataType data_type = dataType(); + Int64 type_size = sizeof(DataType); + + if (use_basic_type){ + nb_count = DataTypeTraitsT::nbBasicType(); + data_type = DataTypeTraitsT::type(); + type_size = sizeof(BasicType); + } + + Int64 nb_element = m_value.totalNbElement(); + Int64 nb_base_element = nb_element * nb_count; + Int64 full_size = nb_base_element * type_size; + const Byte* bt = reinterpret_cast(m_value.to1DSpan().data()); + Span base_values(bt,full_size); + UniqueArray dimensions; + dimensions.resize(2); + dimensions[0] = m_value.dim1Size(); + dimensions[1] = m_value.dim2Size(); + + auto sd = arcaneCreateSerializedDataRef(data_type,base_values.size(),2,nb_element, + nb_base_element,false,dimensions,shape()); + sd->setConstBytes(base_values); + return sd; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +allocateBufferForSerializedData(ISerializedData* sdata) +{ + typedef typename DataTypeTraitsT::BasicType BasicType; + + eDataType data_type = sdata->baseDataType(); + eDataType base_data_type = DataTypeTraitsT::type(); + + if (data_type!=dataType() && data_type==base_data_type) + ARCANE_FATAL("Bad serialized type"); + bool is_multi_size = sdata->isMultiSize(); + if (is_multi_size) + ARCANE_FATAL("Can not allocate multi-size array"); + + Int64 dim1_size = sdata->extents()[0]; + Int64 dim2_size = sdata->extents()[1]; + //m_trace->info() << " ASSIGN DATA dim1=" << dim1_size + // << " dim2=" << dim2_size + // << " addr=" << m_value.viewAsArray().unguardedBasePointer(); + + m_value.resize(dim1_size,dim2_size); + m_shape = sdata->shape(); + + Byte* byte_data = reinterpret_cast(m_value.to1DSpan().data()); + Span bytes_view(byte_data,sdata->memorySize()); + sdata->setWritableBytes(bytes_view); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +assignSerializedData(const ISerializedData* sdata) +{ + ARCANE_UNUSED(sdata); + // Rien à faire car \a sdata pointe directement vers m_value +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +serialize(ISerializer* sbuf,IDataOperation* operation) +{ + Integer nb_count = DataTypeTraitsT::nbBasicType(); + typedef typename DataTypeTraitsT::BasicType BasicType; + eBasicDataType data_type = DataTypeTraitsT::basicDataType(); + + ISerializer::eMode mode = sbuf->mode(); + if (mode==ISerializer::ModeReserve){ + // Réserve la mémoire pour + // - le nombre d'éléments de la première dimension + // - le nombre d'éléments de la deuxième dimension + // - le nombre d'éléments de ids. + // - le nombre magique pour verification + sbuf->reserveSpan(eBasicDataType::Int64,4); + // Réserve la mémoire pour les valeurs + Int64 total_nb_element = m_value.totalNbElement(); + sbuf->reserveSpan(data_type,total_nb_element*nb_count); + } + else if (mode==ISerializer::ModePut){ + Int64 count = m_value.dim1Size(); + Int64 total = m_value.totalNbElement(); + Int64 n[4]; + n[0] = count; + n[1] = m_value.dim2Size(); + n[2] = total; + n[3] = SERIALIZE2_MAGIC_NUMBER; + sbuf->putSpan(Span(n,4)); + BasicType* bt = reinterpret_cast(m_value.to1DSpan().data()); + Span v(bt,total*nb_count); + //m_trace->info() << "PUT array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType); + sbuf->putSpan(v); + } + else if (mode==ISerializer::ModeGet){ + Int64 n[4] = { 0, 0, 0, 0 }; + sbuf->getSpan(Span(n,4)); + Int64 count = n[0]; + Int64 dim2_size = n[1]; + Int64 total = n[2]; + if (n[3]!=SERIALIZE2_MAGIC_NUMBER) + ARCANE_FATAL("Bad magic number"); + switch(sbuf->readMode()){ + case ISerializer::ReadReplace: + { + //m_trace->info() << "READ REPLACE count=" << count << " dim2_size=" << dim2_size; + m_value.resize(count,dim2_size); + if (operation) + throw NotImplementedException(A_FUNCINFO,"serialize(ReadReplace) with IDataOperation"); + BasicType* bt = reinterpret_cast(m_value.to1DSpan().data()); + Span v(bt,total*nb_count); + sbuf->getSpan(v); + } + break; + case ISerializer::ReadAdd: + { + Int64 current_size = m_value.dim1Size(); + Int64 current_total = m_value.totalNbElement(); + //m_trace->info() << "READ ADD NEW_SIZE=" << current_size << " COUNT=" << count + // << " dim2_size=" << dim2_size << " current_dim2_size=" << m_value.dim2Size() + // << " current_total=" << current_total << " read_elem=" << (total*nb_count); + m_value.resize(current_size + count,dim2_size); + if (operation) + throw NotImplementedException(A_FUNCINFO,"serialize(ReadAdd) with IDataOperation"); + BasicType* bt = reinterpret_cast(m_value.to1DSpan().data()+current_total); + //m_trace->info() << "GET array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType); + Span v(bt,total*nb_count); + sbuf->getSpan(v); + } + break; + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +serialize(ISerializer* sbuf,Int32ConstArrayView ids,IDataOperation* operation) +{ + Integer nb_count = DataTypeTraitsT::nbBasicType(); + typedef typename DataTypeTraitsT::BasicType BasicType; + eBasicDataType data_type = DataTypeTraitsT::basicDataType(); + + ISerializer::eMode mode = sbuf->mode(); + if (mode==ISerializer::ModeReserve){ + // Réserve la mémoire pour + // - le nombre d'éléments de la première dimension + // - le nombre d'éléments de la deuxième dimension + // - le nombre d'éléments de ids. + // - le nombre magique pour verification + sbuf->reserveSpan(eBasicDataType::Int64,4); + // Réserve la mémoire pour les valeurs + Int64 total_nb_value = ((Int64)ids.size()) * ((Int64)m_value.dim2Size()); + sbuf->reserveSpan(data_type,total_nb_value*nb_count); + + } + else if (mode==ISerializer::ModePut){ + Int32 count = ids.size(); + Int64 dim2_size = m_value.dim2Size(); + Int64 total_nb_value = count * dim2_size; + Int64 total = total_nb_value; + Int64 n[4]; + n[0] = m_value.dim1Size(); + n[1] = m_value.dim2Size(); + n[2] = count; + n[3] = SERIALIZE2_MAGIC_NUMBER; + /*m_trace->info() << "PUT COUNT = " << count << " total=" << total + << " dim1 (n[0])=" << n[0] + << " dim2 (n[1])=" << n[1] + << " count (n[2])=" << n[2] + << " magic=" << n[3] + << " this=" << this;*/ + sbuf->putSpan(Span(n,4)); + UniqueArray v(total*nb_count); + { + Integer index = 0; + for( Int32 i=0, is=count; i(m_value[ids[i]].data()); + for( Int64 z=0, iz=dim2_size*nb_count; zputSpan(v); + } + else if (mode==ISerializer::ModeGet){ + switch(sbuf->readMode()){ + case ISerializer::ReadReplace: + { + Int64 n[4] = { 0, 0, 0, 0 }; + sbuf->getSpan(Span(n,4)); + //Integer dim1_size = n[0]; + Int64 dim2_size = n[1]; + Int32 count = CheckedConvert::toInt32(n[2]); + Int64 total = count * dim2_size; + // One dim + /*m_trace->info() << "COUNT = " << count << " total=" << total + << " dim1 (n[0])=" << n[0] + << " dim1 current=" << m_value.dim1Size() + << " dim2 (n[1])=" << n[1] + << " dim2 current=" << m_value.dim2Size() + << " count (n[2])=" << n[2] + << " magic=" << n[3] + << " this=" << this;*/ + if (n[3]!=SERIALIZE2_MAGIC_NUMBER) + ARCANE_FATAL("Bad magic number"); + Int64 current_dim2_size = m_value.dim2Size(); + if (dim2_size!=current_dim2_size){ + if (current_dim2_size!=0 && dim2_size!=0) + ARCANE_FATAL("serialized data should have the same dim2Size current={0} found={1}", + current_dim2_size,dim2_size); + else + m_value.resize(m_value.dim1Size(),dim2_size); + } + Int64 nb_value = count; + //Array v(total*nb_count); + UniqueArray base_value(total*nb_count); + + sbuf->getSpan(base_value); + + Span data_value(reinterpret_cast(base_value.data()),nb_value*dim2_size); + UniqueArray current_value; + Span transformed_value; + + // Si on applique une transformantion, effectue la transformation dans un + // tableau temporaire 'current_value'. + if (operation && nb_value!=0) { + current_value.resize(data_value.size()); + + Int64 index = 0; + for( Int32 i=0, n=count; i a(m_value[ids[i]]); + for( Int64 z=0, iz=dim2_size; zapplySpan(transformed_value,data_value); + } + else { + transformed_value = data_value; + } + + { + Int64 index = 0; + for( Int32 i=0, n=count; i a(m_value[ids[i]]); + for( Int64 z=0, iz=dim2_size; z void Array2DataT:: +fillDefault() +{ + m_value.fill(DataType()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +setName(const String& name) +{ + m_value.setDebugName(name); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +computeHash(IHashAlgorithm* algo,ByteArray& output) const +{ + //TODO: passer en 64 bits + Span values = m_value.to1DSpan(); + + // Calcule la fonction de hashage pour les valeurs + Int64 type_size = sizeof(DataType); + Int64 nb_element = values.size(); + const Byte* ptr = reinterpret_cast(values.data()); + Span input(ptr,type_size*nb_element); + algo->computeHash64(input,output); + + // Calcule la fonction de hashage pour les tailles + UniqueArray dimensions(2); + dimensions[0] = m_value.dim1Size(); + dimensions[1] = m_value.dim2Size(); + ptr = reinterpret_cast(dimensions.data()); + Int64 array_len = dimensions.size() * sizeof(Int64); + input = Span(ptr,array_len); + algo->computeHash64(input,output); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +computeHash(DataHashInfo& hash_info) const +{ + hash_info.setVersion(2); + IHashAlgorithmContext* context = hash_info.context(); + + // Calcule la fonction de hashage pour les tailles + Int64 dimensions[2]; + dimensions[0] = m_value.dim1Size(); + dimensions[1] = m_value.dim2Size(); + Span dimension_span(dimensions,2); + context->updateHash(asBytes(dimension_span)); + + // Calcule la fonction de hashage pour les valeurs + context->updateHash(asBytes(m_value.to1DSpan())); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +copy(const IData* data) +{ + auto* true_data = dynamic_cast< const DataInterfaceType* >(data); + if (!true_data) + throw ArgumentException(A_FUNCINFO,"Can not cast 'IData' to 'IArray2DataT'"); + m_value.copy(true_data->view()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +swapValues(IData* data) +{ + auto* true_data = dynamic_cast(data); + if (!true_data) + throw ArgumentException(A_FUNCINFO,"Can not cast 'IData' to 'Array2DataT'"); + swapValuesDirect(true_data); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +swapValuesDirect(ThatClass* true_data) +{ + m_value.swap(true_data->m_value); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +setAllocationInfo(const DataAllocationInfo& v) +{ + if (m_allocation_info==v) + return; + m_allocation_info = v; + m_value.setMemoryLocationHint(v.memoryLocationHint()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void Array2DataT:: +changeAllocator(const MemoryAllocationOptions& alloc_info) +{ + ARCANE_UNUSED(alloc_info); + ARCANE_THROW(NotImplementedException,"changeAllocator for 2D Array"); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/Array2DataTpl1.cc b/arcane/src/arcane/impl/Array2DataTpl1.cc new file mode 100644 index 0000000000..82ad75e53a --- /dev/null +++ b/arcane/src/arcane/impl/Array2DataTpl1.cc @@ -0,0 +1,33 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* Array2Data.cc (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array2'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/Array2Data.inst.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE1(Array2DataT); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/Array2DataTpl2.cc b/arcane/src/arcane/impl/Array2DataTpl2.cc new file mode 100644 index 0000000000..ceb8da55ef --- /dev/null +++ b/arcane/src/arcane/impl/Array2DataTpl2.cc @@ -0,0 +1,33 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* Array2Data.cc (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array2'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/Array2Data.inst.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE2(Array2DataT); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/Array2DataTpl3.cc b/arcane/src/arcane/impl/Array2DataTpl3.cc new file mode 100644 index 0000000000..4877c37191 --- /dev/null +++ b/arcane/src/arcane/impl/Array2DataTpl3.cc @@ -0,0 +1,33 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* Array2Data.cc (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array2'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/Array2Data.inst.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE3(Array2DataT); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/ArrayData.cc b/arcane/src/arcane/impl/ArrayData.cc index e54d2e56dd..bc008ba2b6 100644 --- a/arcane/src/arcane/impl/ArrayData.cc +++ b/arcane/src/arcane/impl/ArrayData.cc @@ -11,41 +11,10 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arccore/base/ReferenceCounterImpl.h" -#include "arccore/base/Ref.h" +#include "arcane/impl/internal/ArrayData.h" -#include "arcane/utils/IDataCompressor.h" -#include "arcane/utils/Real2.h" -#include "arcane/utils/Real2x2.h" -#include "arcane/utils/Real3.h" -#include "arcane/utils/Real3x3.h" -#include "arcane/utils/IHashAlgorithm.h" -#include "arcane/utils/NotImplementedException.h" -#include "arcane/utils/NotSupportedException.h" -#include "arcane/utils/ArgumentException.h" -#include "arcane/utils/FatalErrorException.h" -#include "arcane/utils/IndexOutOfRangeException.h" -#include "arcane/utils/ITraceMng.h" -#include "arcane/utils/Array.h" -#include "arcane/utils/ArrayShape.h" -#include "arcane/utils/MemoryAllocator.h" -#include "arcane/utils/MemoryView.h" -#include "arcane/utils/MemoryUtils.h" -#include "arcane/utils/PlatformUtils.h" +#include "arcane/utils/NumericTypes.h" -#include "arcane/core/datatype/DataAllocationInfo.h" -#include "arcane/core/datatype/DataStorageBuildInfo.h" -#include "arcane/core/datatype/IDataOperation.h" -#include "arcane/core/datatype/DataStorageTypeInfo.h" -#include "arcane/core/datatype/DataTypeTraits.h" - -#include "arcane/core/ISerializer.h" -#include "arcane/core/IData.h" -#include "arcane/core/IDataVisitor.h" - -#include "arcane/core/internal/IDataInternal.h" - -#include "arcane/impl/SerializedData.h" #include "arcane/impl/DataStorageFactory.h" /*---------------------------------------------------------------------------*/ @@ -54,666 +23,6 @@ namespace Arcane { -namespace -{ - const Int64 SERIALIZE_MAGIC_NUMBER = 0x456ff989; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -/*! - * \brief Donnée tableau d'un type \a T - */ -template -class ArrayDataT -: public ReferenceCounterImpl -, public IArrayDataT -{ - ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(); - class Impl; - friend class Impl; - - public: - - typedef ArrayDataT ThatClass; - typedef IArrayDataT DataInterfaceType; - - public: - - explicit ArrayDataT(ITraceMng* trace); - explicit ArrayDataT(const DataStorageBuildInfo& dsbi); - ArrayDataT(const ArrayDataT& rhs); - ~ArrayDataT() override; - - public: - - Integer dimension() const override { return 1; } - Integer multiTag() const override { return 0; } - eDataType dataType() const override { return DataTypeTraitsT::type(); } - void serialize(ISerializer* sbuf,IDataOperation* operation) override; - void serialize(ISerializer* sbuf,Int32ConstArrayView ids,IDataOperation* operation) override; - Array& value() override { return m_value; } - const Array& value() const override { return m_value; } - ConstArrayView view() const override { return m_value; } - ArrayView view() override { return m_value; } - void resize(Integer new_size) override { m_value.resize(new_size); } - IData* clone() override { return _cloneTrue(); } - IData* cloneEmpty() override { return _cloneTrueEmpty(); }; - Ref cloneRef() override { return makeRef(cloneTrue()); } - Ref cloneEmptyRef() override { return makeRef(cloneTrueEmpty()); } - DataStorageTypeInfo storageTypeInfo() const override; - DataInterfaceType* cloneTrue() override { return _cloneTrue(); } - DataInterfaceType* cloneTrueEmpty() override { return _cloneTrueEmpty(); } - Ref cloneTrueRef() override { auto* d = _cloneTrue(); return makeRef(d); } - Ref cloneTrueEmptyRef() override { auto* d = _cloneTrueEmpty(); return makeRef(d); } - void fillDefault() override; - void setName(const String& name) override; - Ref createSerializedDataRef(bool use_basic_type) const override; - void allocateBufferForSerializedData(ISerializedData* sdata) override; - void assignSerializedData(const ISerializedData* sdata) override; - void copy(const IData* data) override; - void swapValues(IData* data) override; - void computeHash(IHashAlgorithm* algo,ByteArray& output) const override; - void computeHash(DataHashInfo& hash_info) const; - ArrayShape shape() const override { return m_shape; } - void setShape(const ArrayShape& new_shape) override { m_shape = new_shape; } - void setAllocationInfo(const DataAllocationInfo& v) override; - DataAllocationInfo allocationInfo() const override { return m_allocation_info; } - void visit(IArrayDataVisitor* visitor) override - { - visitor->applyVisitor(this); - } - void visit(IDataVisitor* visitor) override - { - visitor->applyDataVisitor(this); - } - void visitScalar(IScalarDataVisitor*) override - { - ARCANE_THROW(NotSupportedException,"Can not visit scalar data with array data"); - } - void visitArray(IArrayDataVisitor* visitor) override - { - visitor->applyVisitor(this); - } - void visitArray2(IArray2DataVisitor*) override - { - ARCANE_THROW(NotSupportedException,"Can not visit array2 data with array data"); - } - - public: - - void swapValuesDirect(ThatClass* true_data); - void changeAllocator(const MemoryAllocationOptions& alloc_info); - - public: - - IArrayDataInternalT* _internal() override { return m_internal; } - IDataInternal* _commonInternal() override { return m_internal; } - - public: - - static DataStorageTypeInfo staticStorageTypeInfo(); - - public: - - - private: - - UniqueArray m_value; //!< Donnée - ITraceMng* m_trace; - IArrayDataInternalT* m_internal; - ArrayShape m_shape; - DataAllocationInfo m_allocation_info; - - private: - - void _serialize(ISerializer* sbuf,Span ids,IDataOperation* operation); - IArrayDataT* _cloneTrue() const { return new ThatClass(*this); } - IArrayDataT* _cloneTrueEmpty() const { return new ThatClass(m_trace); } - void _setShape(); -}; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template -class ArrayDataT::Impl -: public IArrayDataInternalT -, public INumericDataInternal -{ - public: - - explicit Impl(ArrayDataT* p) : m_p(p){} - - public: - - void reserve(Integer new_capacity) override { m_p->m_value.reserve(new_capacity); } - Array& _internalDeprecatedValue() override { return m_p->m_value; } - Integer capacity() const override { return m_p->m_value.capacity(); } - void shrink() const override { m_p->m_value.shrink(); } - void resize(Integer new_size) override { m_p->m_value.resize(new_size);} - void dispose() override { m_p->m_value.dispose(); } - bool compressAndClear(DataCompressionBuffer& buf) override - { - IDataCompressor* compressor = buf.m_compressor; - if (!compressor) - return false; - Span values = m_p->m_value; - Span bytes = asBytes(values); - compressor->compress(bytes,buf.m_buffer); - buf.m_original_dim1_size = values.size(); - m_p->m_value.clear(); - m_p->m_value.shrink(); - return true; - } - bool decompressAndFill(DataCompressionBuffer& buf) override - { - IDataCompressor* compressor = buf.m_compressor; - if (!compressor) - return false; - m_p->m_value.resize(buf.m_original_dim1_size); - Span values = m_p->m_value; - compressor->decompress(buf.m_buffer,asWritableBytes(values)); - return true; - } - MutableMemoryView memoryView() override - { - return makeMutableMemoryView(m_p->view()); - } - Int32 extent0() const override - { - return m_p->view().size(); - } - INumericDataInternal* numericData() override { return this; } - void changeAllocator(const MemoryAllocationOptions& v) override { m_p->changeAllocator(v); } - void computeHash(DataHashInfo& hash_info) override - { - m_p->computeHash(hash_info); - } - - private: - - ArrayDataT* m_p; -}; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template ArrayDataT:: -ArrayDataT(ITraceMng* trace) -: m_value(AlignedMemoryAllocator::Simd()) -, m_trace(trace) -, m_internal(new Impl(this)) -{ - _setShape(); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template ArrayDataT:: -ArrayDataT(const ArrayDataT& rhs) -: m_value(AlignedMemoryAllocator::Simd()) -, m_trace(rhs.m_trace) -, m_internal(new Impl(this)) -, m_shape(rhs.m_shape) -, m_allocation_info(rhs.m_allocation_info) -{ - m_value = rhs.m_value.constSpan(); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template ArrayDataT:: -ArrayDataT(const DataStorageBuildInfo& dsbi) -: m_value(dsbi.memoryAllocator()) -, m_trace(dsbi.traceMng()) -, m_internal(new Impl(this)) -{ - _setShape(); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template ArrayDataT:: -~ArrayDataT() -{ - delete m_internal; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template DataStorageTypeInfo ArrayDataT:: -staticStorageTypeInfo() -{ - typedef DataTypeTraitsT TraitsType; - eBasicDataType bdt = TraitsType::basicDataType(); - Int32 nb_basic_type = TraitsType::nbBasicType(); - Int32 dimension = 1; - Int32 multi_tag = 0; - return DataStorageTypeInfo(bdt,nb_basic_type,dimension,multi_tag); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template DataStorageTypeInfo ArrayDataT:: -storageTypeInfo() const -{ - return staticStorageTypeInfo(); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template Ref ArrayDataT:: -createSerializedDataRef(bool use_basic_type) const -{ - typedef typename DataTypeTraitsT::BasicType BasicType; - - Integer nb_count = 1; - eDataType data_type = dataType(); - Integer type_size = sizeof(DataType); - - if (use_basic_type){ - nb_count = DataTypeTraitsT::nbBasicType(); - data_type = DataTypeTraitsT::type(); - type_size = sizeof(BasicType); - } - - Int64 nb_element = m_value.largeSize(); - Int64 nb_base_element = nb_element * nb_count; - Int64 full_size = nb_base_element * type_size; - Span base_values(reinterpret_cast(m_value.data()),full_size); - UniqueArray extents; - extents.add(nb_element); - auto sd = arcaneCreateSerializedDataRef(data_type,base_values.size(),1,nb_element, - nb_base_element,false,extents,shape()); - sd->setConstBytes(base_values); - return sd; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -allocateBufferForSerializedData(ISerializedData* sdata) -{ - typedef typename DataTypeTraitsT::BasicType BasicType; - - eDataType data_type = sdata->baseDataType(); - eDataType base_data_type = DataTypeTraitsT::type(); - - if (data_type!=dataType() && data_type==base_data_type) - ARCANE_THROW(ArgumentException,"Bad serialized type"); - - Int64 nb_element = sdata->nbElement(); - - //m_trace->info() << " ASSIGN DATA nb_element=" << nb_element - // << " this=" << this; - m_value.resize(nb_element); - m_shape = sdata->shape(); - Byte* byte_data = reinterpret_cast(m_value.data()); - Span buffer(byte_data,sdata->memorySize()); - sdata->setWritableBytes(buffer); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -assignSerializedData(const ISerializedData* sdata) -{ - ARCANE_UNUSED(sdata); - // Rien à faire car \a sdata pointe directement vers m_value -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -serialize(ISerializer* sbuf,IDataOperation* operation) -{ - Integer nb_count = DataTypeTraitsT::nbBasicType(); - typedef typename DataTypeTraitsT::BasicType BasicType; - eBasicDataType data_type = DataTypeTraitsT::basicDataType(); - bool is_debug = arcaneIsDebug(); - - switch(sbuf->mode()){ - case ISerializer::ModeReserve: - { - Int64 nb_value = m_value.largeSize(); - Int64 total_size = nb_value*nb_count; - m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) reserve datatype=" - << data_type << " ids=" << nb_value << " totalsize=" << total_size; - sbuf->reserveInt64(2); // 1 pour magic number et 1 pour la taille - sbuf->reserveSpan(data_type,total_size); - } - break; - case ISerializer::ModePut: - { - Int64 nb_value = m_value.largeSize(); - Int64 total_size = nb_value*nb_count; - m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) put datatype=" - << data_type << " ids=" << nb_value << " totalsize=" << total_size; - if (is_debug) - for( Int64 i=0; idebug(Trace::Highest) << "Put i=" << i << " value =" << m_value[i]; - - Span base_value(reinterpret_cast(m_value.data()),total_size); - sbuf->putInt64(SERIALIZE_MAGIC_NUMBER); - sbuf->putInt64(nb_value); - sbuf->putSpan(base_value); - } - break; - case ISerializer::ModeGet: - { - Int64 saved_magic_number = sbuf->getInt64(); - Int64 nb_value = sbuf->getInt64(); - - if (saved_magic_number!=SERIALIZE_MAGIC_NUMBER) - ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}", - SERIALIZE_MAGIC_NUMBER,saved_magic_number); - - Int64 total_size = nb_value * nb_count; - - m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) get mode=" << sbuf->readMode() - << " datatype=" << data_type - << " ids=" << nb_value << " totalsize=" << total_size; - switch(sbuf->readMode()){ - case ISerializer::ReadReplace: - { - m_value.resize(nb_value); // must resize using resizeFromGroup ? - - if (operation) { - UniqueArray base_value(total_size); - sbuf->getSpan(base_value); - Span data_value(reinterpret_cast(base_value.data()),nb_value); - operation->applySpan(m_value,data_value); - if (is_debug) - for( Int64 i=0; idebug(Trace::Highest) << "Get i=" << i << " value=" - << data_value[i] << " transformed value=" << m_value[i]; - } - else{ - Span base_value(reinterpret_cast(m_value.data()), total_size); - sbuf->getSpan(base_value); - if (is_debug) - for( Int64 i=0; idebug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i]; - } - } - break; - case ISerializer::ReadAdd: - { - Int64 current_size = m_value.largeSize(); - m_value.resize(current_size+nb_value); // must resize using resizeFromGroup ? - Span base_value(reinterpret_cast(m_value.data()+current_size),total_size); - if (operation) - ARCANE_THROW(NotImplementedException,"ArrayData::serialize : Cannot deserialize using operation in ReadAdd mode"); - sbuf->getSpan(base_value); - if (is_debug) - for( Int64 i=0; idebug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i]; - } - } - break; - } - break; - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -serialize(ISerializer* sbuf,Int32ConstArrayView ids,IDataOperation* operation) -{ - _serialize(sbuf,ids,operation); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -_serialize(ISerializer* sbuf,Span ids,IDataOperation* operation) -{ - Integer nb_count = DataTypeTraitsT::nbBasicType(); - typedef typename DataTypeTraitsT::BasicType BasicType; - eBasicDataType data_type = DataTypeTraitsT::basicDataType(); - bool is_debug = arcaneIsDebug(); - - Int64 nb_value = ids.size(); - Int64 total_size = nb_value*nb_count; - - switch(sbuf->mode()){ - case ISerializer::ModeReserve: - { - m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) reserve datatype=" - << data_type << " ids=" << nb_value << " totalsize=" << total_size; - sbuf->reserveInt64(2); - sbuf->reserveSpan(data_type,total_size); - } - break; - case ISerializer::ModePut: - { - m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) put datatype=" - << data_type << " ids=" << nb_value << " totalsize=" << total_size; - if (is_debug){ - // Vérifie les valeurs - for( Integer i=0, max_value=m_value.size(); imax_value) - throw IndexOutOfRangeException(A_FUNCINFO, - String::format(" put,serialize : bad sizes i={0} ids[i]={1} nb_value={2} this={3}", - i,ids[i], max_value, this), - i,0,max_value); - } - - UniqueArray base_value; - base_value.reserve(total_size); - for( Int64 i=0; idebug(Trace::Highest) << "Put i=" << i << " index=" << ids[i] << " value=" << m_value[ids[i]]; -#endif /* ARCANE_DEBUG */ - ConstArrayView current_value(nb_count, reinterpret_cast(&m_value[ids[i]])); - base_value.addRange(current_value); - } - sbuf->putInt64(SERIALIZE_MAGIC_NUMBER); - sbuf->putInt64(nb_value); - sbuf->putSpan(base_value); - } - break; - case ISerializer::ModeGet: - { - m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) get mode=" << sbuf->readMode() - << " datatype=" << data_type - << " ids=" << nb_value << " totalsize=" << total_size; - if (is_debug){ - // Vérifie les valeurs - for( Integer i=0, max_value=m_value.size(); imax_value) - throw IndexOutOfRangeException(A_FUNCINFO, - String::format(" put,serialize : bad sizes i={0} ids[i]={1} nb_value={2} this={3}", - i,ids[i], max_value, this), - i,0,max_value); - } - - switch(sbuf->readMode()){ - case ISerializer::ReadReplace: - { - Int64 saved_magic_number = sbuf->getInt64(); - Int64 saved_nb_value = sbuf->getInt64(); - - if (saved_magic_number!=SERIALIZE_MAGIC_NUMBER) - ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}", - SERIALIZE_MAGIC_NUMBER,saved_magic_number); - - if (saved_nb_value!=nb_value) - ARCANE_FATAL("Internal errror: bad size for serialisation expected={0} found={1}", - nb_value,saved_nb_value); - - UniqueArray base_value(total_size); - sbuf->getSpan(base_value); - - Span data_value(reinterpret_cast(base_value.data()),nb_value); - UniqueArray current_value; - Span transformed_value; - - if (operation && nb_value!=0) { - current_value.resize(ids.size()); - Arccore::sampleSpan(m_value.constSpan(),ids,current_value.span()); - transformed_value = current_value.view(); - operation->applySpan(transformed_value,data_value); - } - else { - transformed_value = data_value; - } - - if (is_debug){ - if (operation) - for( Int64 i=0; idebug(Trace::Highest) << "Get i=" << i << " index=" << ids[i] - << " value=" << data_value[i] << " transformed value=" << transformed_value[i]; - else - for( Int64 i=0; idebug(Trace::Highest) << "Get i=" << i << " index=" << ids[i] - << " value=" << data_value[i]; - } - - for( Int64 i=0; i void ArrayDataT:: -fillDefault() -{ - m_value.fill(DataType()); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -setName(const String& name) -{ - m_value.setDebugName(name); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -computeHash(IHashAlgorithm* algo,ByteArray& output) const -{ - Int64 type_size = sizeof(DataType); - Int64 nb_element = m_value.largeSize(); - const Byte* ptr = reinterpret_cast(m_value.data()); - Span input(ptr,type_size*nb_element); - algo->computeHash64(input,output); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -computeHash(DataHashInfo& hash_info) const -{ - hash_info.setVersion(2); - hash_info.context()->updateHash(asBytes(m_value.span())); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -copy(const IData* data) -{ - auto* true_data = dynamic_cast< const DataInterfaceType* >(data); - if (!true_data) - ARCANE_THROW(ArgumentException,"Can not cast 'IData' to 'IArrayDataT'"); - m_value.copy(true_data->view()); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -swapValues(IData* data) -{ - auto* true_data = dynamic_cast(data); - if (!true_data) - ARCANE_THROW(ArgumentException,"Can not cast 'IData' to 'ArrayDataT'"); - swapValuesDirect(true_data); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -swapValuesDirect(ThatClass* true_data) -{ - m_value.swap(true_data->m_value); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -_setShape() -{ - m_shape.setNbDimension(1); - m_shape.setDimension(0,1); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -setAllocationInfo(const DataAllocationInfo& v) -{ - if (m_allocation_info==v) - return; - m_allocation_info = v; - m_value.setMemoryLocationHint(v.memoryLocationHint()); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -template void ArrayDataT:: -changeAllocator(const MemoryAllocationOptions& alloc_info) -{ - UniqueArray new_value(alloc_info,m_value.size()); - - // Copie \a m_value dans \a new_value - // Tant qu'il n'y a pas l'API dans Arccore, il faut faire la copie à la - // main pour ne pas avoir de plantage si l'allocateur est uniquement sur - // un accélérateur - MemoryUtils::copy(new_value.span(), m_value.constSpan()); - - std::swap(m_value,new_value); - m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint()); -} - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -738,24 +47,7 @@ registerArrayDataFactory(IDataFactoryMng* dfm) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; -template class ArrayDataT; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -} // End namesapce Arcane +} // namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/ArrayData.h b/arcane/src/arcane/impl/ArrayData.h deleted file mode 100644 index fb6c02bc2f..0000000000 --- a/arcane/src/arcane/impl/ArrayData.h +++ /dev/null @@ -1,7 +0,0 @@ -// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- -//----------------------------------------------------------------------------- -// Copyright 2000-2021 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) -// See the top-level COPYRIGHT file for details. -// SPDX-License-Identifier: Apache-2.0 -//----------------------------------------------------------------------------- -#error "Do not include this file" diff --git a/arcane/src/arcane/impl/ArrayData.inst.h b/arcane/src/arcane/impl/ArrayData.inst.h new file mode 100644 index 0000000000..d3402dcb6e --- /dev/null +++ b/arcane/src/arcane/impl/ArrayData.inst.h @@ -0,0 +1,515 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ArrayData.inst.h (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/internal/ArrayData.h" + +#include "arcane/utils/NotSupportedException.h" +#include "arcane/utils/Real2.h" +#include "arcane/utils/Real2x2.h" +#include "arcane/utils/Real3.h" +#include "arcane/utils/Real3x3.h" +#include "arcane/utils/IHashAlgorithm.h" +#include "arcane/utils/NotImplementedException.h" +#include "arcane/utils/IndexOutOfRangeException.h" +#include "arcane/utils/ArgumentException.h" +#include "arcane/utils/FatalErrorException.h" +#include "arcane/utils/ITraceMng.h" +#include "arcane/utils/CheckedConvert.h" +#include "arcane/utils/MemoryAllocator.h" +#include "arcane/utils/MemoryUtils.h" + +#include "arcane/core/datatype/DataStorageBuildInfo.h" +#include "arcane/core/datatype/IDataOperation.h" + +#include "arcane/core/ISerializer.h" + +#include "arcane/impl/SerializedData.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ +namespace +{ + inline constexpr Int64 SERIALIZE_MAGIC_NUMBER = 0x456ff989; +} // namespace + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template ArrayDataT:: +ArrayDataT(ITraceMng* trace) +: m_value(AlignedMemoryAllocator::Simd()) +, m_trace(trace) +, m_internal(new Impl(this)) +{ + _setShape(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template ArrayDataT:: +ArrayDataT(const ArrayDataT& rhs) +: m_value(AlignedMemoryAllocator::Simd()) +, m_trace(rhs.m_trace) +, m_internal(new Impl(this)) +, m_shape(rhs.m_shape) +, m_allocation_info(rhs.m_allocation_info) +{ + m_value = rhs.m_value.constSpan(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template ArrayDataT:: +ArrayDataT(const DataStorageBuildInfo& dsbi) +: m_value(dsbi.memoryAllocator()) +, m_trace(dsbi.traceMng()) +, m_internal(new Impl(this)) +{ + _setShape(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template ArrayDataT:: +~ArrayDataT() +{ + delete m_internal; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template DataStorageTypeInfo ArrayDataT:: +staticStorageTypeInfo() +{ + typedef DataTypeTraitsT TraitsType; + eBasicDataType bdt = TraitsType::basicDataType(); + Int32 nb_basic_type = TraitsType::nbBasicType(); + Int32 dimension = 1; + Int32 multi_tag = 0; + return DataStorageTypeInfo(bdt, nb_basic_type, dimension, multi_tag); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template DataStorageTypeInfo ArrayDataT:: +storageTypeInfo() const +{ + return staticStorageTypeInfo(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template Ref ArrayDataT:: +createSerializedDataRef(bool use_basic_type) const +{ + typedef typename DataTypeTraitsT::BasicType BasicType; + + Integer nb_count = 1; + eDataType data_type = dataType(); + Integer type_size = sizeof(DataType); + + if (use_basic_type) { + nb_count = DataTypeTraitsT::nbBasicType(); + data_type = DataTypeTraitsT::type(); + type_size = sizeof(BasicType); + } + + Int64 nb_element = m_value.largeSize(); + Int64 nb_base_element = nb_element * nb_count; + Int64 full_size = nb_base_element * type_size; + Span base_values(reinterpret_cast(m_value.data()), full_size); + UniqueArray extents; + extents.add(nb_element); + auto sd = arcaneCreateSerializedDataRef(data_type, base_values.size(), 1, nb_element, + nb_base_element, false, extents, shape()); + sd->setConstBytes(base_values); + return sd; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +allocateBufferForSerializedData(ISerializedData* sdata) +{ + typedef typename DataTypeTraitsT::BasicType BasicType; + + eDataType data_type = sdata->baseDataType(); + eDataType base_data_type = DataTypeTraitsT::type(); + + if (data_type != dataType() && data_type == base_data_type) + ARCANE_THROW(ArgumentException, "Bad serialized type"); + + Int64 nb_element = sdata->nbElement(); + + //m_trace->info() << " ASSIGN DATA nb_element=" << nb_element + // << " this=" << this; + m_value.resize(nb_element); + m_shape = sdata->shape(); + Byte* byte_data = reinterpret_cast(m_value.data()); + Span buffer(byte_data, sdata->memorySize()); + sdata->setWritableBytes(buffer); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +assignSerializedData(const ISerializedData* sdata) +{ + ARCANE_UNUSED(sdata); + // Rien à faire car \a sdata pointe directement vers m_value +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +serialize(ISerializer* sbuf, IDataOperation* operation) +{ + Integer nb_count = DataTypeTraitsT::nbBasicType(); + typedef typename DataTypeTraitsT::BasicType BasicType; + eBasicDataType data_type = DataTypeTraitsT::basicDataType(); + bool is_debug = arcaneIsDebug(); + + switch (sbuf->mode()) { + case ISerializer::ModeReserve: { + Int64 nb_value = m_value.largeSize(); + Int64 total_size = nb_value * nb_count; + m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) reserve datatype=" + << data_type << " ids=" << nb_value << " totalsize=" << total_size; + sbuf->reserveInt64(2); // 1 pour magic number et 1 pour la taille + sbuf->reserveSpan(data_type, total_size); + } break; + case ISerializer::ModePut: { + Int64 nb_value = m_value.largeSize(); + Int64 total_size = nb_value * nb_count; + m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) put datatype=" + << data_type << " ids=" << nb_value << " totalsize=" << total_size; + if (is_debug) + for (Int64 i = 0; i < nb_value; ++i) + m_trace->debug(Trace::Highest) << "Put i=" << i << " value =" << m_value[i]; + + Span base_value(reinterpret_cast(m_value.data()), total_size); + sbuf->putInt64(SERIALIZE_MAGIC_NUMBER); + sbuf->putInt64(nb_value); + sbuf->putSpan(base_value); + } break; + case ISerializer::ModeGet: { + Int64 saved_magic_number = sbuf->getInt64(); + Int64 nb_value = sbuf->getInt64(); + + if (saved_magic_number != SERIALIZE_MAGIC_NUMBER) + ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}", + SERIALIZE_MAGIC_NUMBER, saved_magic_number); + + Int64 total_size = nb_value * nb_count; + + m_trace->debug(Trace::High) << " ArrayDataT::serialize (full) get mode=" << sbuf->readMode() + << " datatype=" << data_type + << " ids=" << nb_value << " totalsize=" << total_size; + switch (sbuf->readMode()) { + case ISerializer::ReadReplace: { + m_value.resize(nb_value); // must resize using resizeFromGroup ? + + if (operation) { + UniqueArray base_value(total_size); + sbuf->getSpan(base_value); + Span data_value(reinterpret_cast(base_value.data()), nb_value); + operation->applySpan(m_value, data_value); + if (is_debug) + for (Int64 i = 0; i < nb_value; ++i) + m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" + << data_value[i] << " transformed value=" << m_value[i]; + } + else { + Span base_value(reinterpret_cast(m_value.data()), total_size); + sbuf->getSpan(base_value); + if (is_debug) + for (Int64 i = 0; i < nb_value; ++i) + m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i]; + } + } break; + case ISerializer::ReadAdd: { + Int64 current_size = m_value.largeSize(); + m_value.resize(current_size + nb_value); // must resize using resizeFromGroup ? + Span base_value(reinterpret_cast(m_value.data() + current_size), total_size); + if (operation) + ARCANE_THROW(NotImplementedException, "ArrayData::serialize : Cannot deserialize using operation in ReadAdd mode"); + sbuf->getSpan(base_value); + if (is_debug) + for (Int64 i = 0; i < nb_value; ++i) + m_trace->debug(Trace::Highest) << "Get i=" << i << " value=" << m_value[i]; + } + } + break; + } break; + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation) +{ + _serialize(sbuf, ids, operation); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +_serialize(ISerializer* sbuf, Span ids, IDataOperation* operation) +{ + Integer nb_count = DataTypeTraitsT::nbBasicType(); + typedef typename DataTypeTraitsT::BasicType BasicType; + eBasicDataType data_type = DataTypeTraitsT::basicDataType(); + bool is_debug = arcaneIsDebug(); + + Int64 nb_value = ids.size(); + Int64 total_size = nb_value * nb_count; + + switch (sbuf->mode()) { + case ISerializer::ModeReserve: { + m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) reserve datatype=" + << data_type << " ids=" << nb_value << " totalsize=" << total_size; + sbuf->reserveInt64(2); + sbuf->reserveSpan(data_type, total_size); + } break; + case ISerializer::ModePut: { + m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) put datatype=" + << data_type << " ids=" << nb_value << " totalsize=" << total_size; + if (is_debug) { + // Vérifie les valeurs + for (Integer i = 0, max_value = m_value.size(); i < nb_value; ++i) + if (ids[i] > max_value) + throw IndexOutOfRangeException(A_FUNCINFO, + String::format(" put,serialize : bad sizes i={0} ids[i]={1} nb_value={2} this={3}", + i, ids[i], max_value, this), + i, 0, max_value); + } + + UniqueArray base_value; + base_value.reserve(total_size); + for (Int64 i = 0; i < nb_value; ++i) { +#ifdef ARCANE_DEBUG + m_trace->debug(Trace::Highest) << "Put i=" << i << " index=" << ids[i] << " value=" << m_value[ids[i]]; +#endif /* ARCANE_DEBUG */ + ConstArrayView current_value(nb_count, reinterpret_cast(&m_value[ids[i]])); + base_value.addRange(current_value); + } + sbuf->putInt64(SERIALIZE_MAGIC_NUMBER); + sbuf->putInt64(nb_value); + sbuf->putSpan(base_value); + } break; + case ISerializer::ModeGet: { + m_trace->debug(Trace::High) << " ArrayDataT::serialize (partial) get mode=" << sbuf->readMode() + << " datatype=" << data_type + << " ids=" << nb_value << " totalsize=" << total_size; + if (is_debug) { + // Vérifie les valeurs + for (Integer i = 0, max_value = m_value.size(); i < nb_value; ++i) + if (ids[i] > max_value) + throw IndexOutOfRangeException(A_FUNCINFO, + String::format(" put,serialize : bad sizes i={0} ids[i]={1} nb_value={2} this={3}", + i, ids[i], max_value, this), + i, 0, max_value); + } + + switch (sbuf->readMode()) { + case ISerializer::ReadReplace: { + Int64 saved_magic_number = sbuf->getInt64(); + Int64 saved_nb_value = sbuf->getInt64(); + + if (saved_magic_number != SERIALIZE_MAGIC_NUMBER) + ARCANE_FATAL("Internal errror: bad magic number for serialisation expected={0} current={1}", + SERIALIZE_MAGIC_NUMBER, saved_magic_number); + + if (saved_nb_value != nb_value) + ARCANE_FATAL("Internal errror: bad size for serialisation expected={0} found={1}", + nb_value, saved_nb_value); + + UniqueArray base_value(total_size); + sbuf->getSpan(base_value); + + Span data_value(reinterpret_cast(base_value.data()), nb_value); + UniqueArray current_value; + Span transformed_value; + + if (operation && nb_value != 0) { + current_value.resize(ids.size()); + Arccore::sampleSpan(m_value.constSpan(), ids, current_value.span()); + transformed_value = current_value.view(); + operation->applySpan(transformed_value, data_value); + } + else { + transformed_value = data_value; + } + + if (is_debug) { + if (operation) + for (Int64 i = 0; i < nb_value; ++i) + m_trace->debug(Trace::Highest) << "Get i=" << i << " index=" << ids[i] + << " value=" << data_value[i] << " transformed value=" << transformed_value[i]; + else + for (Int64 i = 0; i < nb_value; ++i) + m_trace->debug(Trace::Highest) << "Get i=" << i << " index=" << ids[i] + << " value=" << data_value[i]; + } + + for (Int64 i = 0; i < nb_value; ++i) { + m_value[ids[i]] = transformed_value[i]; + } + } break; + case ISerializer::ReadAdd: + ARCANE_THROW(NotImplementedException, "ArrayData::serialize : Cannot deserialize with ReadAdd mode"); + break; + } + } break; + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +fillDefault() +{ + m_value.fill(DataType()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +setName(const String& name) +{ + m_value.setDebugName(name); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +computeHash(IHashAlgorithm* algo, ByteArray& output) const +{ + Int64 type_size = sizeof(DataType); + Int64 nb_element = m_value.largeSize(); + const Byte* ptr = reinterpret_cast(m_value.data()); + Span input(ptr, type_size * nb_element); + algo->computeHash64(input, output); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +computeHash(DataHashInfo& hash_info) const +{ + hash_info.setVersion(2); + hash_info.context()->updateHash(asBytes(m_value.span())); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +copy(const IData* data) +{ + auto* true_data = dynamic_cast(data); + if (!true_data) + ARCANE_THROW(ArgumentException, "Can not cast 'IData' to 'IArrayDataT'"); + m_value.copy(true_data->view()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +swapValues(IData* data) +{ + auto* true_data = dynamic_cast(data); + if (!true_data) + ARCANE_THROW(ArgumentException, "Can not cast 'IData' to 'ArrayDataT'"); + swapValuesDirect(true_data); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +swapValuesDirect(ThatClass* true_data) +{ + m_value.swap(true_data->m_value); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +_setShape() +{ + m_shape.setNbDimension(1); + m_shape.setDimension(0, 1); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +setAllocationInfo(const DataAllocationInfo& v) +{ + if (m_allocation_info == v) + return; + m_allocation_info = v; + m_value.setMemoryLocationHint(v.memoryLocationHint()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void ArrayDataT:: +changeAllocator(const MemoryAllocationOptions& alloc_info) +{ + UniqueArray new_value(alloc_info, m_value.size()); + + // Copie \a m_value dans \a new_value + // Tant qu'il n'y a pas l'API dans Arccore, il faut faire la copie à la + // main pour ne pas avoir de plantage si l'allocateur est uniquement sur + // un accélérateur + MemoryUtils::copy(new_value.span(), m_value.constSpan()); + + std::swap(m_value, new_value); + m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/ArrayDataTpl1.cc b/arcane/src/arcane/impl/ArrayDataTpl1.cc new file mode 100644 index 0000000000..97ac39cf35 --- /dev/null +++ b/arcane/src/arcane/impl/ArrayDataTpl1.cc @@ -0,0 +1,33 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ArrayData.cc (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/ArrayData.inst.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE1(ArrayDataT); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namesapce Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/ArrayDataTpl2.cc b/arcane/src/arcane/impl/ArrayDataTpl2.cc new file mode 100644 index 0000000000..5bb05504dd --- /dev/null +++ b/arcane/src/arcane/impl/ArrayDataTpl2.cc @@ -0,0 +1,33 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ArrayData.cc (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/ArrayData.inst.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE2(ArrayDataT); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namesapce Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/ArrayDataTpl3.cc b/arcane/src/arcane/impl/ArrayDataTpl3.cc new file mode 100644 index 0000000000..b2a913ad14 --- /dev/null +++ b/arcane/src/arcane/impl/ArrayDataTpl3.cc @@ -0,0 +1,33 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ArrayData.cc (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/impl/ArrayData.inst.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE3(ArrayDataT); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namesapce Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/ScalarData.cc b/arcane/src/arcane/impl/ScalarData.cc index e54f533103..1943216708 100644 --- a/arcane/src/arcane/impl/ScalarData.cc +++ b/arcane/src/arcane/impl/ScalarData.cc @@ -437,19 +437,7 @@ registerScalarDataFactory(IDataFactoryMng* dfm) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; -template class ScalarDataT; +ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE(ScalarDataT); /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/internal/Array2Data.h b/arcane/src/arcane/impl/internal/Array2Data.h new file mode 100644 index 0000000000..ca01c69200 --- /dev/null +++ b/arcane/src/arcane/impl/internal/Array2Data.h @@ -0,0 +1,260 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* Array2Data.h (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array2'. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_IMPL_INTERNAL_ARRAY2DATA_H +#define ARCANE_IMPL_INTERNAL_ARRAY2DATA_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arccore/base/ReferenceCounterImpl.h" + +#include "arcane/utils/ArrayShape.h" +#include "arcane/utils/String.h" +#include "arcane/utils/IDataCompressor.h" +#include "arcane/utils/Array2.h" +#include "arcane/utils/MemoryView.h" +#include "arcane/utils/Ref.h" +#include "arcane/utils/FatalErrorException.h" + +#include "arcane/core/IData.h" +#include "arcane/core/IDataVisitor.h" +#include "arcane/core/internal/IDataInternal.h" +#include "arcane/core/datatype/DataAllocationInfo.h" +#include "arcane/core/datatype/DataTypeTraits.h" +#include "arcane/core/datatype/DataStorageTypeInfo.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * \brief Donnée tableau bi-dimensionnel d'un type \a DataType + */ +template +class Array2DataT +: public ReferenceCounterImpl +, public IArray2DataT +{ + ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(); + class Impl; + friend class Impl; + + public: + + typedef Array2DataT ThatClass; + typedef IArray2DataT DataInterfaceType; + + public: + + explicit Array2DataT(ITraceMng* trace); + explicit Array2DataT(const DataStorageBuildInfo& dsbi); + Array2DataT(const Array2DataT& rhs); + ~Array2DataT() override; + + public: + + Integer dimension() const override { return 2; } + Integer multiTag() const override { return 0; } + eDataType dataType() const override { return DataTypeTraitsT::type(); } + void serialize(ISerializer* sbuf, IDataOperation* operation) override; + void serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation) override; + Array2& value() override { return m_value; } + const Array2& value() const override { return m_value; } + Array2View view() override { return m_value; } + ConstArray2View view() const override { return m_value; } + void resize(Integer new_size) override; + IData* clone() override { return _cloneTrue(); } + IData* cloneEmpty() override { return _cloneTrueEmpty(); }; + Ref cloneRef() override { return makeRef(cloneTrue()); } + Ref cloneEmptyRef() override { return makeRef(cloneTrueEmpty()); } + DataStorageTypeInfo storageTypeInfo() const override; + DataInterfaceType* cloneTrue() override { return _cloneTrue(); } + DataInterfaceType* cloneTrueEmpty() override { return _cloneTrueEmpty(); } + Ref cloneTrueRef() override + { + auto* d = _cloneTrue(); + return makeRef(d); + } + Ref cloneTrueEmptyRef() override + { + auto* d = _cloneTrueEmpty(); + return makeRef(d); + } + void fillDefault() override; + void setName(const String& name) override; + Ref createSerializedDataRef(bool use_basic_type) const override; + void allocateBufferForSerializedData(ISerializedData* sdata) override; + void assignSerializedData(const ISerializedData* sdata) override; + void copy(const IData* data) override; + void swapValues(IData* data) override; + void computeHash(IHashAlgorithm* algo, ByteArray& output) const override; + void computeHash(DataHashInfo& hash_algo) const; + ArrayShape shape() const override { return m_shape; } + void setShape(const ArrayShape& new_shape) override { m_shape = new_shape; } + void setAllocationInfo(const DataAllocationInfo& v) override; + DataAllocationInfo allocationInfo() const override { return m_allocation_info; } + + void visit(IArray2DataVisitor* visitor) + { + visitor->applyVisitor(this); + } + void visit(IDataVisitor* visitor) override + { + visitor->applyDataVisitor(this); + } + void visitScalar(IScalarDataVisitor*) override + { + ARCANE_THROW(NotSupportedException, "Can not visit scalar data with array2 data"); + } + void visitArray(IArrayDataVisitor*) override + { + ARCANE_THROW(NotSupportedException, "Can not visit array data with array2 data"); + } + void visitArray2(IArray2DataVisitor* visitor) override + { + visitor->applyVisitor(this); + } + + public: + + void swapValuesDirect(ThatClass* true_data); + void changeAllocator(const MemoryAllocationOptions& alloc_info); + + public: + + IArray2DataInternalT* _internal() override { return m_internal; } + IDataInternal* _commonInternal() override { return m_internal; } + + public: + + static DataStorageTypeInfo staticStorageTypeInfo(); + + private: + + UniqueArray2 m_value; //!< Donnée + ITraceMng* m_trace; + IArray2DataInternalT* m_internal; + ArrayShape m_shape; + DataAllocationInfo m_allocation_info; + + private: + + IArray2DataT* _cloneTrue() const { return new ThatClass(*this); } + IArray2DataT* _cloneTrueEmpty() const { return new ThatClass(m_trace); } +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template +class Array2DataT::Impl +: public IArray2DataInternalT +, public INumericDataInternal +{ + public: + + explicit Impl(Array2DataT* p) + : m_p(p) + {} + + public: + + void reserve(Integer new_capacity) override { m_p->m_value.reserve(new_capacity); } + void resizeOnlyDim1(Int32 new_dim1_size) override + { + m_p->m_value.resize(new_dim1_size, m_p->m_value.dim2Size()); + } + void resize(Int32 new_dim1_size, Int32 new_dim2_size) override + { + if (new_dim1_size < 0) + ARCANE_FATAL("Bad value '{0}' for dim1_size", new_dim1_size); + if (new_dim2_size < 0) + ARCANE_FATAL("Bad value '{0}' for dim2_size", new_dim2_size); + // Cette méthode est appelée si on modifie la deuxième dimension. + // Dans ce cas cela invalide l'ancienne valeur de shape. + bool need_reshape = false; + if (new_dim2_size != m_p->m_value.dim2Size()) + need_reshape = true; + m_p->m_value.resize(new_dim1_size, new_dim2_size); + if (need_reshape) { + m_p->m_shape.setNbDimension(1); + m_p->m_shape.setDimension(0, new_dim2_size); + } + } + Array2& _internalDeprecatedValue() override { return m_p->m_value; } + void shrink() const override { m_p->m_value.shrink(); } + bool compressAndClear(DataCompressionBuffer& buf) override + { + IDataCompressor* compressor = buf.m_compressor; + if (!compressor) + return false; + Span values = m_p->m_value.to1DSpan(); + Span bytes = asBytes(values); + compressor->compress(bytes, buf.m_buffer); + buf.m_original_dim1_size = m_p->m_value.dim1Size(); + buf.m_original_dim2_size = m_p->m_value.dim2Size(); + m_p->m_value.clear(); + m_p->m_value.shrink(); + return true; + } + bool decompressAndFill(DataCompressionBuffer& buf) override + { + IDataCompressor* compressor = buf.m_compressor; + if (!compressor) + return false; + m_p->m_value.resize(buf.m_original_dim1_size, buf.m_original_dim2_size); + Span values = m_p->m_value.to1DSpan(); + compressor->decompress(buf.m_buffer, asWritableBytes(values)); + return true; + } + + MutableMemoryView memoryView() override + { + Array2View value = m_p->view(); + Int32 dim1_size = value.dim1Size(); + Int32 dim2_size = value.dim2Size(); + DataStorageTypeInfo storage_info = m_p->storageTypeInfo(); + Int32 nb_basic_element = storage_info.nbBasicElement(); + Int32 datatype_size = basicDataTypeSize(storage_info.basicDataType()) * nb_basic_element; + return makeMutableMemoryView(value.data(), datatype_size * dim2_size, dim1_size); + } + Int32 extent0() const override + { + return m_p->view().dim1Size(); + } + INumericDataInternal* numericData() override { return this; } + void changeAllocator(const MemoryAllocationOptions& v) override { m_p->changeAllocator(v); } + void computeHash(DataHashInfo& hash_info) override + { + m_p->computeHash(hash_info); + } + + private: + + Array2DataT* m_p; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/impl/internal/ArrayData.h b/arcane/src/arcane/impl/internal/ArrayData.h new file mode 100644 index 0000000000..70c2dcc9c4 --- /dev/null +++ b/arcane/src/arcane/impl/internal/ArrayData.h @@ -0,0 +1,225 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ArrayData.h (C) 2000-2024 */ +/* */ +/* Donnée du type 'Array'. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_IMPL_INTERNAL_ARRAYDATA_H +#define ARCANE_IMPL_INTERNAL_ARRAYDATA_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arccore/base/ReferenceCounterImpl.h" + +#include "arcane/utils/ArrayShape.h" +#include "arcane/utils/String.h" +#include "arcane/utils/IDataCompressor.h" +#include "arcane/utils/Array.h" +#include "arcane/utils/MemoryView.h" +#include "arcane/utils/Ref.h" +#include "arcane/utils/NotSupportedException.h" + +#include "arcane/core/IData.h" +#include "arcane/core/IDataVisitor.h" +#include "arcane/core/internal/IDataInternal.h" +#include "arcane/core/datatype/DataAllocationInfo.h" +#include "arcane/core/datatype/DataTypeTraits.h" +#include "arcane/core/datatype/DataStorageTypeInfo.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * \brief Donnée tableau d'un type \a T + */ +template +class ArrayDataT +: public ReferenceCounterImpl +, public IArrayDataT +{ + ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(); + class Impl; + friend class Impl; + + public: + + typedef ArrayDataT ThatClass; + typedef IArrayDataT DataInterfaceType; + + public: + + explicit ArrayDataT(ITraceMng* trace); + explicit ArrayDataT(const DataStorageBuildInfo& dsbi); + ArrayDataT(const ArrayDataT& rhs); + ~ArrayDataT() override; + + public: + + Integer dimension() const override { return 1; } + Integer multiTag() const override { return 0; } + eDataType dataType() const override { return DataTypeTraitsT::type(); } + void serialize(ISerializer* sbuf,IDataOperation* operation) override; + void serialize(ISerializer* sbuf,Int32ConstArrayView ids,IDataOperation* operation) override; + Array& value() override { return m_value; } + const Array& value() const override { return m_value; } + ConstArrayView view() const override { return m_value; } + ArrayView view() override { return m_value; } + void resize(Integer new_size) override { m_value.resize(new_size); } + IData* clone() override { return _cloneTrue(); } + IData* cloneEmpty() override { return _cloneTrueEmpty(); }; + Ref cloneRef() override { return makeRef(cloneTrue()); } + Ref cloneEmptyRef() override { return makeRef(cloneTrueEmpty()); } + DataStorageTypeInfo storageTypeInfo() const override; + DataInterfaceType* cloneTrue() override { return _cloneTrue(); } + DataInterfaceType* cloneTrueEmpty() override { return _cloneTrueEmpty(); } + Ref cloneTrueRef() override { auto* d = _cloneTrue(); return makeRef(d); } + Ref cloneTrueEmptyRef() override { auto* d = _cloneTrueEmpty(); return makeRef(d); } + void fillDefault() override; + void setName(const String& name) override; + Ref createSerializedDataRef(bool use_basic_type) const override; + void allocateBufferForSerializedData(ISerializedData* sdata) override; + void assignSerializedData(const ISerializedData* sdata) override; + void copy(const IData* data) override; + void swapValues(IData* data) override; + void computeHash(IHashAlgorithm* algo,ByteArray& output) const override; + void computeHash(DataHashInfo& hash_info) const; + ArrayShape shape() const override { return m_shape; } + void setShape(const ArrayShape& new_shape) override { m_shape = new_shape; } + void setAllocationInfo(const DataAllocationInfo& v) override; + DataAllocationInfo allocationInfo() const override { return m_allocation_info; } + void visit(IArrayDataVisitor* visitor) override + { + visitor->applyVisitor(this); + } + void visit(IDataVisitor* visitor) override + { + visitor->applyDataVisitor(this); + } + void visitScalar(IScalarDataVisitor*) override + { + ARCANE_THROW(NotSupportedException, "Can not visit scalar data with array data"); + } + void visitArray(IArrayDataVisitor* visitor) override + { + visitor->applyVisitor(this); + } + void visitArray2(IArray2DataVisitor*) override + { + ARCANE_THROW(NotSupportedException,"Can not visit array2 data with array data"); + } + + public: + + void swapValuesDirect(ThatClass* true_data); + void changeAllocator(const MemoryAllocationOptions& alloc_info); + + public: + + IArrayDataInternalT* _internal() override { return m_internal; } + IDataInternal* _commonInternal() override { return m_internal; } + + public: + + static DataStorageTypeInfo staticStorageTypeInfo(); + + public: + + + private: + + UniqueArray m_value; //!< Donnée + ITraceMng* m_trace; + IArrayDataInternalT* m_internal; + ArrayShape m_shape; + DataAllocationInfo m_allocation_info; + + private: + + void _serialize(ISerializer* sbuf,Span ids,IDataOperation* operation); + IArrayDataT* _cloneTrue() const { return new ThatClass(*this); } + IArrayDataT* _cloneTrueEmpty() const { return new ThatClass(m_trace); } + void _setShape(); +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template +class ArrayDataT::Impl +: public IArrayDataInternalT +, public INumericDataInternal +{ + public: + + explicit Impl(ArrayDataT* p) : m_p(p){} + + public: + + void reserve(Integer new_capacity) override { m_p->m_value.reserve(new_capacity); } + Array& _internalDeprecatedValue() override { return m_p->m_value; } + Integer capacity() const override { return m_p->m_value.capacity(); } + void shrink() const override { m_p->m_value.shrink(); } + void resize(Integer new_size) override { m_p->m_value.resize(new_size);} + void dispose() override { m_p->m_value.dispose(); } + bool compressAndClear(DataCompressionBuffer& buf) override + { + IDataCompressor* compressor = buf.m_compressor; + if (!compressor) + return false; + Span values = m_p->m_value; + Span bytes = asBytes(values); + compressor->compress(bytes,buf.m_buffer); + buf.m_original_dim1_size = values.size(); + m_p->m_value.clear(); + m_p->m_value.shrink(); + return true; + } + bool decompressAndFill(DataCompressionBuffer& buf) override + { + IDataCompressor* compressor = buf.m_compressor; + if (!compressor) + return false; + m_p->m_value.resize(buf.m_original_dim1_size); + Span values = m_p->m_value; + compressor->decompress(buf.m_buffer,asWritableBytes(values)); + return true; + } + MutableMemoryView memoryView() override + { + return makeMutableMemoryView(m_p->view()); + } + Int32 extent0() const override + { + return m_p->view().size(); + } + INumericDataInternal* numericData() override { return this; } + void changeAllocator(const MemoryAllocationOptions& v) override { m_p->changeAllocator(v); } + void computeHash(DataHashInfo& hash_info) override + { + m_p->computeHash(hash_info); + } + + private: + + ArrayDataT* m_p; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namesapce Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/arcane/src/arcane/impl/srcs.cmake b/arcane/src/arcane/impl/srcs.cmake index f09fd1319d..e2988f23ef 100644 --- a/arcane/src/arcane/impl/srcs.cmake +++ b/arcane/src/arcane/impl/srcs.cmake @@ -11,8 +11,16 @@ set( ARCANE_SOURCES ArcaneCodeService.cc ArcaneMain.cc ArcaneMain.h + ArrayData.inst.h ArrayData.cc - ArrayData.h + ArrayDataTpl1.cc + ArrayDataTpl2.cc + ArrayDataTpl3.cc + Array2Data.inst.h + Array2Data.cc + Array2DataTpl1.cc + Array2DataTpl2.cc + Array2DataTpl3.cc ArcaneMainBatch.cc CaseDocument.cc CaseDocumentLangTranslator.cc @@ -47,8 +55,6 @@ set( ARCANE_SOURCES MainFactory.cc MainFactory.h ModuleMng.cc - Array2Data.cc - Array2Data.h MemoryDataReaderWriter.cc MemoryDataReaderWriter.h DefaultBackwardMng.cc @@ -106,13 +112,11 @@ set( ARCANE_SOURCES Application.h ArcaneSession.h ArcaneMain.h - ArrayData.h CaseDocumentLangTranslator.h GetVariablesValuesParallelOperation.h DataFactory.h ItemEnumeratorTracer.h MainFactory.h - Array2Data.h MemoryDataReaderWriter.h DefaultBackwardMng.h LoadBalanceMng.h @@ -136,6 +140,8 @@ set( ARCANE_SOURCES DataOperation.cc SequentialParallelSuperMng.h + internal/ArrayData.h + internal/Array2Data.h internal/ArcaneMainExecInfo.h internal/DataSynchronizeBuffer.h internal/IDataSynchronizeDispatcher.h