12#ifndef ARCCORE_COMMON_ABSTRACTARRAY_H
13#define ARCCORE_COMMON_ABSTRACTARRAY_H
19#include "arccore/common/ArrayTraits.h"
20#include "arccore/common/ArrayMetaData.h"
46class ARCCORE_COMMON_EXPORT AbstractArrayBase
54 virtual ~AbstractArrayBase() =
default;
60 return m_md->allocation_options.allocator();
64 return m_md->allocation_options;
100 std::swap(m_md, rhs.m_md);
101 std::swap(m_meta_data, rhs.m_meta_data);
102 _checkSetUseOwnMetaData();
103 rhs._checkSetUseOwnMetaData();
106 void _copyMetaData(
const AbstractArrayBase& rhs)
111 m_meta_data = rhs.m_meta_data;
113 _checkSetUseOwnMetaData();
116 void _allocateMetaData()
120 ArrayMetaData::throwNullExpected();
122 if (_isUseOwnMetaData()) {
123 m_meta_data = ArrayMetaData();
127 m_md =
new ArrayMetaData();
133 void _deallocateMetaData(ArrayMetaData* md)
135 if (md->is_allocated_by_new)
138 *md = ArrayMetaData();
141 void _checkValidSharedArray()
145 ArrayMetaData::throwInvalidMetaDataForSharedArray();
151 void _checkSetUseOwnMetaData()
169:
public AbstractArrayBase
173 typedef typename ArrayTraits<T>::ConstReferenceType ConstReferenceType;
174 typedef typename ArrayTraits<T>::IsPODType IsPODType;
199 typedef std::reverse_iterator<iterator> reverse_iterator;
200 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
229 static constexpr Int64 typeSize() {
return static_cast<Int64
>(
sizeof(T)); }
230 AllocatedMemoryInfo _currentMemoryInfo()
const
232 return AllocatedMemoryInfo(m_ptr, m_md->size * typeSize(), m_md->capacity * typeSize());
247 _createRange(0, asize, view.
data());
262 void* pre_allocated_buffer =
nullptr)
274 _internalDeallocate();
278 if (options.allocator() != m_md->_allocator())
289 operator Span<const T>()
const
291 return Span<const T>(m_ptr, m_md->
size);
293 operator SmallSpan<const T>()
const
295 return SmallSpan<const T>(m_ptr, ARCCORE_CAST_SMALL_SIZE(
size()));
301 Integer size()
const {
return ARCCORE_CAST_SMALL_SIZE(m_md->size); }
313 bool empty()
const {
return m_md->size == 0; }
317 const T* ptr = m_ptr;
318 for (
Int64 i = 0, n = m_md->size; i < n; ++i) {
330 ARCCORE_CHECK_AT(i, m_md->size);
336 ARCCORE_CHECK_AT(i, m_md->size);
345 m_md->_setMemoryLocationHint(new_hint, m_ptr,
sizeof(T));
356 m_md->m_host_device_memory_location = location;
362 return m_md->m_host_device_memory_location;
374 return !(rhs == lhs);
377 friend bool operator==(
const AbstractArray<T>& rhs,
const Span<const T>& lhs)
379 return operator==(Span<const T>(rhs), lhs);
382 friend bool operator!=(
const AbstractArray<T>& rhs,
const Span<const T>& lhs)
384 return !(rhs == lhs);
387 friend bool operator==(
const Span<const T>& rhs,
const AbstractArray<T>& lhs)
389 return operator==(rhs, Span<const T>(lhs));
392 friend bool operator!=(
const Span<const T>& rhs,
const AbstractArray<T>& lhs)
394 return !(rhs == lhs);
397 friend std::ostream& operator<<(std::ostream& o,
const AbstractArray<T>& val)
399 o << Span<const T>(val);
405 using AbstractArrayBase::m_meta_data;
419 if (new_capacity <= m_md->
capacity) {
422 if (m_meta_data.is_collective_allocator) {
434 template <
typename PodType>
439 if (_isSharedNull()) {
440 if (new_capacity != 0 || m_meta_data.is_collective_allocator)
441 _internalAllocate(new_capacity, queue);
445 Int64 acapacity = new_capacity;
446 if (compute_capacity) {
447 acapacity = m_md->capacity;
449 while (new_capacity > acapacity)
450 acapacity = (acapacity == 0) ? 4 : (acapacity + 1 + acapacity / 2);
456 if (m_meta_data.is_collective_allocator) {
473 Int64 old_capacity = m_md->capacity;
474 _directReAllocate(new_capacity, queue);
475 bool update = (new_capacity < old_capacity) || (m_ptr != old_ptr);
487 Int64 old_size = m_md->size;
488 _directAllocate(new_capacity, queue);
489 if (m_ptr != old_ptr) {
490 for (
Int64 i = 0; i < old_size; ++i) {
491 new (m_ptr + i) T(old_ptr[i]);
494 m_md->nb_ref = old_md->
nb_ref;
495 m_md->_deallocate(old_mem_info, queue);
500 void _internalDeallocate(
RunQueue* queue =
nullptr)
504 if (!_isSharedNull())
505 m_md->_deallocate(_currentMemoryInfo(), queue);
507 _deallocateMetaData(m_md);
509 void _internalAllocate(Int64 new_capacity, RunQueue* queue)
511 _directAllocate(new_capacity, queue);
516 void _copyFromMemory(
const T* source)
518 m_md->_copyFromMemory(m_ptr, source,
sizeof(T),
_nullRunQueue());
532 void* pre_allocated_buffer =
nullptr)
535 if (!wanted_allocator) {
536 wanted_allocator = ArrayMetaData::_defaultAllocator();
537 options.setAllocator(wanted_allocator);
540 m_md->allocation_options = options;
541 if (new_capacity > 0) {
542 if (!pre_allocated_buffer)
543 _allocateMP(new_capacity,
nullptr);
545 _setMPCast(pre_allocated_buffer);
556 _allocateMP(new_capacity, queue);
559 void _allocateMP(Int64 new_capacity, RunQueue* queue)
561 _setMPCast(m_md->_allocate(new_capacity, typeSize(), queue));
564 void _directReAllocate(
Int64 new_capacity, RunQueue* queue)
566 _setMPCast(m_md->_reallocate(_currentMemoryInfo(), new_capacity, typeSize(), queue));
571 void changeAllocator(
const MemoryAllocationOptions& options, RunQueue* queue)
573 _setMPCast(m_md->_changeAllocator(options, _currentMemoryInfo(), typeSize(), queue));
577 void changeAllocator(
const MemoryAllocationOptions& options)
579 _setMPCast(m_md->_changeAllocator(options, _currentMemoryInfo(), typeSize(),
_nullRunQueue()));
585 void printInfos(std::ostream& o)
587 o <<
" Infos: size=" << m_md->size <<
" capacity=" << m_md->capacity <<
'\n';
604 Int64 s = m_md->size;
605 if ((s + n) > m_md->capacity)
607 for (
Int64 i = 0; i < n; ++i)
608 new (m_ptr + s + i) T(val);
616 const T* ptr = val.
data();
617 Int64 s = m_md->size;
618 if ((s + n) > m_md->capacity)
620 _createRange(s, s + n, ptr);
627 if (m_md->nb_ref == 0) {
634 _destroyRange(0, m_md->
size, IsPODType());
636 void _destroyRange(Int64, Int64, TrueType)
640 void _destroyRange(
Int64 abegin,
Int64 aend, FalseType)
644 for (
Int64 i = abegin; i < aend; ++i)
647 void _createRangeDefault(
Int64,
Int64, TrueType)
650 void _createRangeDefault(
Int64 abegin,
Int64 aend, FalseType)
654 for (
Int64 i = abegin; i < aend; ++i)
657 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, TrueType)
661 for (
Int64 i = abegin; i < aend; ++i)
664 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, FalseType)
668 for (
Int64 i = abegin; i < aend; ++i)
669 new (m_ptr + i) T(value);
671 void _createRange(
Int64 abegin,
Int64 aend,
const T* values)
675 for (
Int64 i = abegin; i < aend; ++i) {
676 new (m_ptr + i) T(*values);
680 void _fill(ConstReferenceType value)
682 for (
Int64 i = 0, n =
size(); i < n; ++i)
685 void _clone(
const ThatClassType& orig_array)
687 Int64 that_size = orig_array.size();
689 m_md->size = that_size;
690 m_md->dim1_size = orig_array.m_md->dim1_size;
691 m_md->dim2_size = orig_array.m_md->dim2_size;
692 _createRange(0, that_size, orig_array.m_ptr);
694 template <
typename PodType>
695 void _resizeHelper(
Int64 s, PodType pod_type, RunQueue* queue)
699 if (s > m_md->size) {
701 this->_createRangeDefault(m_md->size, s, pod_type);
704 this->_destroyRange(s, m_md->size, pod_type);
705 if (m_meta_data.is_collective_allocator) {
711 void _resize(
Int64 s)
718 _resizeHelper(s,
TrueType{}, queue);
722 this->_destroyRange(0, m_md->
size, IsPODType());
730 if (s > m_md->size) {
732 this->_createRange(m_md->size, s, value, IsPODType());
735 this->_destroyRange(s, m_md->size, IsPODType());
736 if (m_meta_data.is_collective_allocator) {
742 void _copy(
const T* rhs_begin,
TrueType)
744 _copyFromMemory(rhs_begin);
746 void _copy(
const T* rhs_begin, FalseType)
748 for (Int64 i = 0, n = m_md->
size; i < n; ++i)
749 m_ptr[i] = rhs_begin[i];
751 void _copy(
const T* rhs_begin)
753 _copy(rhs_begin, IsPODType());
766 const T* rhs_begin = rhs.
data();
768 const Int64 current_size = m_md->size;
771 if (abegin >= rhs_begin && abegin < (rhs_begin + rhs_size))
772 ArrayMetaData::overlapError(abegin, m_md->size, rhs_begin, rhs_size);
774 if (rhs_size > current_size) {
777 this->_createRange(m_md->size, rhs_size, rhs_begin + current_size);
780 m_md->size = rhs_size;
783 this->_destroyRange(rhs_size, current_size, IsPODType{});
784 m_md->size = rhs_size;
796 void _move(ThatClassType& rhs) ARCCORE_NOEXCEPT
820 void _swap(ThatClassType& rhs) ARCCORE_NOEXCEPT
822 std::swap(m_ptr, rhs.m_ptr);
832 void _shrink(Int64 new_capacity)
837 if (new_capacity > this->
capacity())
839 if (new_capacity < 4)
857 if (asize > max_size)
859 asize =
static_cast<Integer>(max_size);
868 Span<const T> rhs_span(rhs);
869 if (rhs.allocator() == this->allocator()) {
883 void _setMP(TrueImpl* new_mp)
888 void _setMP2(TrueImpl* new_mp, ArrayMetaData* new_md)
894 if (!m_md->is_allocated_by_new)
900 return m_ptr ==
nullptr;
905 void _setToSharedNull()
908 m_meta_data = ArrayMetaData();
911 void _setMPCast(
void* p)
913 _setMP(
reinterpret_cast<TrueImpl*
>(p));
Types et fonctions associés aux classes SpanImpl, SmallSpan and Span.
Classe de base interne pour les tableaux.
static constexpr RunQueue * _nullRunQueue()
Méthode explicite pour une RunQueue nulle.
virtual bool _isUseOwnMetaData() const
Indique si m_md fait référence à m_meta_data.
Classe abstraite de base d'un vecteur.
void _addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
Integer capacity() const
Capacité (nombre d'éléments alloués) du vecteur.
void _addRange(Span< const T > val)
Ajoute n élément de valeur val à la fin du tableau.
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Positionne l'emplacement physique de la zone mémoire.
virtual void _updateReferences()
Mise à jour des références.
const value_type * const_pointer
void _checkFreeMemory()
Détruit l'instance si plus personne ne la référence.
ConstReferenceType operator[](Int64 i) const
Elément d'indice i.
void dispose()
Libère la mémoire utilisée par le tableau.
AbstractArray()
Construit un vecteur vide avec l'allocateur par défaut.
Integer size() const
Nombre d'éléments du vecteur.
void _initFromSpan(const Span< const T > &view)
Initialise le tableau avec la vue view.
void _move(ThatClassType &rhs) ARCCORE_NOEXCEPT
Implémente l'opérateur d'assignement par déplacement.
void _initFromAllocator(MemoryAllocationOptions o, Int64 acapacity, void *pre_allocated_buffer=nullptr)
Construit un vecteur vide avec un allocateur spécifique a.
ArrayIterator< pointer > iterator
void _resize(Int64 s, ConstReferenceType value)
Redimensionne et remplit les nouvelles valeurs avec value.
void setMemoryLocationHint(eMemoryLocationHint new_hint)
Modifie les informations sur la localisation mémoire.
void _internalReallocate(Int64 new_capacity, FalseType, RunQueue *queue)
Réallocation pour un type complexe (non POD)
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Positionne l'emplacement physique de la zone mémoire.
ptrdiff_t difference_type
Int64 largeSize() const
Nombre d'éléments du vecteur (en 64 bits)
bool contains(ConstReferenceType v) const
Vrai si le tableau contient l'élément de valeur v.
Int64 largeCapacity() const
Capacité (nombre d'éléments alloués) du vecteur (en 64 bits)
Int64 largeLength() const
Nombre d'éléments du vecteur (en 64 bits)
void _directFirstAllocateWithAllocator(Int64 new_capacity, MemoryAllocationOptions options, void *pre_allocated_buffer=nullptr)
Effectue la première allocation.
void _reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void _resizeAndCopyView(Span< const T > rhs)
Redimensionne l'instance et recopie les valeurs de rhs.
virtual Integer _getNbRef()
Mise à jour des références.
ConstReferenceType const_reference
ArrayIterator< const_pointer > const_iterator
void _resizeNoInit(Int64 s, RunQueue *queue=nullptr)
Redimensionne sans initialiser les nouvelles valeurs.
AbstractArray(ThatClassType &&rhs) ARCCORE_NOEXCEPT
Constructeur par déplacement. Ne doit être utilisé que par UniqueArray.
void _internalRealloc(Int64 new_capacity, bool compute_capacity, PodType pod_type, RunQueue *queue=nullptr)
Réalloue le tableau pour une nouvelle capacité égale à new_capacity.
void _swap(ThatClassType &rhs) ARCCORE_NOEXCEPT
Échange les valeurs de l'instance avec celles de rhs.
ConstReferenceType operator()(Int64 i) const
Elément d'indice i.
void _reset()
Réinitialise le tableau à un tableau vide.
void _internalReallocate(Int64 new_capacity, TrueType, RunQueue *queue)
Réallocation pour un type POD.
Integer length() const
Nombre d'éléments du vecteur.
File d'exécution pour un accélérateur.
Informations sur une zone mémoire allouée.
void setDebugName(const String &name)
Itérateur sur les classes tableau de Arccore.
Vue constante d'un tableau de type T.
Interface d'un allocateur pour la mémoire.
Options pour configurer les allocations.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Vue d'un tableau d'éléments de type T.
Chaîne de caractères unicode.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
eMemoryLocationHint
Indices sur la localisation mémoire attendue.
eHostDeviceMemoryLocation
Localisation physique d'une adresse mémoire.
std::int32_t Int32
Type entier signé sur 32 bits.
Structure équivalente à la valeur booléenne vrai.
Structure équivalente à la valeur booléenne vrai.