diff --git a/arccore/src/collections/arccore/collections/Array.cc b/arccore/src/collections/arccore/collections/Array.cc index 7ac1cfb6cf..8d83f9488a 100644 --- a/arccore/src/collections/arccore/collections/Array.cc +++ b/arccore/src/collections/arccore/collections/Array.cc @@ -107,6 +107,15 @@ _setMemoryLocationHint(eMemoryLocationHint new_hint,void* ptr,Int64 sizeof_true_ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void ArrayMetaData:: +_setHostDeviceMemoryLocation(eHostDeviceMemoryLocation location) +{ + allocation_options.setHostDeviceMemoryLocation(location); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void ArrayMetaData:: _copyFromMemory(MemoryPointer destination, ConstMemoryPointer source, Int64 sizeof_true_type, RunQueue* queue) { diff --git a/arccore/src/collections/arccore/collections/Array.h b/arccore/src/collections/arccore/collections/Array.h index 8c8d1cb172..0ebf2e4634 100644 --- a/arccore/src/collections/arccore/collections/Array.h +++ b/arccore/src/collections/arccore/collections/Array.h @@ -77,6 +77,7 @@ class ARCCORE_COLLECTIONS_EXPORT ArrayMetaData Int32 nb_ref = 0; //! Indique is cette instance a été allouée par l'opérateur new. bool is_allocated_by_new = false; + //! Indique si cette instance n'est pas l'instance nulle (partagée par tous les SharedArray) bool is_not_null = false; protected: @@ -102,6 +103,7 @@ class ARCCORE_COLLECTIONS_EXPORT ArrayMetaData MemoryPointer _reallocate(const AllocatedMemoryInfo& mem_info, Int64 new_capacity, Int64 sizeof_true_type, RunQueue* queue); void _deallocate(const AllocatedMemoryInfo& mem_info, RunQueue* queue) ARCCORE_NOEXCEPT; void _setMemoryLocationHint(eMemoryLocationHint new_hint, void* ptr, Int64 sizeof_true_type); + void _setHostDeviceMemoryLocation(eHostDeviceMemoryLocation location); void _copyFromMemory(MemoryPointer destination, ConstMemoryPointer source, Int64 sizeof_true_type, RunQueue* queue); private: @@ -465,6 +467,23 @@ class AbstractArray m_md->_setMemoryLocationHint(new_hint,m_ptr,sizeof(T)); } + /*! + * \brief Positionne l'emplacement physique de la zone mémoire. + * + * \warning L'appelant doit garantir la cohérence entre l'allocateur + * et la zone mémoire spécifiée. + */ + void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location) + { + m_md->_setHostDeviceMemoryLocation(location); + } + + //! Positionne l'emplacement physique de la zone mémoire. + eHostDeviceMemoryLocation hostDeviceMemoryLocation() const + { + return m_md->allocation_options.hostDeviceMemoryLocation(); + } + public: friend bool operator==(const AbstractArray& rhs, const AbstractArray& lhs) diff --git a/arccore/src/collections/arccore/collections/CMakeLists.txt b/arccore/src/collections/arccore/collections/CMakeLists.txt index 76fb89fa5e..7710265bff 100644 --- a/arccore/src/collections/arccore/collections/CMakeLists.txt +++ b/arccore/src/collections/arccore/collections/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES ArrayTraits.h ArrayDebugInfo.h CollectionsGlobal.h + CollectionsGlobal.cc IMemoryAllocator.h MemoryAllocationArgs.h MemoryAllocationOptions.h diff --git a/arccore/src/collections/arccore/collections/CollectionsGlobal.cc b/arccore/src/collections/arccore/collections/CollectionsGlobal.cc new file mode 100644 index 0000000000..10d96e81a0 --- /dev/null +++ b/arccore/src/collections/arccore/collections/CollectionsGlobal.cc @@ -0,0 +1,85 @@ +// -*- 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 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* CollectionsGlobal.cc (C) 2000-2024 */ +/* */ +/* Définitions globales de la composante 'Collections' de 'Arccore'. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arccore/collections/CollectionsGlobal.h" + +#include + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arccore +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace +{ + const char* _toName(eHostDeviceMemoryLocation v) + { + switch (v) { + case eHostDeviceMemoryLocation::Unknown: + return "Unknown"; + case eHostDeviceMemoryLocation::Device: + return "Device"; + case eHostDeviceMemoryLocation::Host: + return "Host"; + case eHostDeviceMemoryLocation::ManagedMemoryDevice: + return "ManagedMemoryDevice"; + case eHostDeviceMemoryLocation::ManagedMemoryHost: + return "ManagedMemoryHost"; + } + return "Invalid"; + } + + const char* _toName(eMemoryResource r) + { + switch (r) { + case eMemoryResource::Unknown: + return "Unknown"; + case eMemoryResource::Host: + return "Host"; + case eMemoryResource::HostPinned: + return "HostPinned"; + case eMemoryResource::Device: + return "Device"; + case eMemoryResource::UnifiedMemory: + return "UnifiedMemory"; + } + return "Invalid"; + } + +} // namespace + +extern "C++" ARCCORE_COLLECTIONS_EXPORT std::ostream& +operator<<(std::ostream& o, eHostDeviceMemoryLocation v) +{ + o << _toName(v); + return o; +} + +extern "C++" ARCCORE_COLLECTIONS_EXPORT std::ostream& +operator<<(std::ostream& o, eMemoryResource v) +{ + o << _toName(v); + return o; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arccore + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arccore/src/collections/arccore/collections/CollectionsGlobal.h b/arccore/src/collections/arccore/collections/CollectionsGlobal.h index 2bb5e8bba1..a828ca7db4 100644 --- a/arccore/src/collections/arccore/collections/CollectionsGlobal.h +++ b/arccore/src/collections/arccore/collections/CollectionsGlobal.h @@ -16,6 +16,8 @@ #include "arccore/base/ArccoreGlobal.h" +#include + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -85,6 +87,60 @@ enum class eMemoryLocationHint : int8_t HostAndDeviceMostlyRead = 3 }; +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * \brief Localisation physique d'une adresse mémoire. + * + * Pour les valeurs ManagedMemoryDevice et ManagedMemoryHost il s'agit d'une + * indication car il n'y a pas de moyen simple de savoir où se trouve + * réellement la mémoire. + */ +enum class eHostDeviceMemoryLocation : int8_t +{ + //! Localisation inconnue + Unknown = 0, + //! La mémoire est sur accélérateur + Device = 1, + //! La mémoire est sur l'hôte. + Host = 2, + //! La mémoire est de la mémoire managée sur accélérateur + ManagedMemoryDevice = 3, + //! La mémoire est de la mémoire managée sur l'hôte. + ManagedMemoryHost = 4, +}; +extern "C++" ARCCORE_COLLECTIONS_EXPORT std::ostream& +operator<<(std::ostream& o, eHostDeviceMemoryLocation r); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/*! + * \brief Liste des ressources mémoire disponibles. + */ +enum class eMemoryResource +{ + //! Valeur inconnue ou non initialisée + Unknown = 0, + //! Alloue sur l'hôte. + Host, + //! Alloue sur l'hôte. + HostPinned, + //! Alloue sur le device + Device, + //! Alloue en utilisant la mémoire unifiée. + UnifiedMemory +}; + +//! Nombre de valeurs valides pour eMemoryRessource +static constexpr int ARCCORE_NB_MEMORY_RESOURCE = 5; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +extern "C++" ARCCORE_COLLECTIONS_EXPORT std::ostream& +operator<<(std::ostream& o, eMemoryResource r); + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /*! diff --git a/arccore/src/collections/arccore/collections/IMemoryAllocator.h b/arccore/src/collections/arccore/collections/IMemoryAllocator.h index e23023d438..4c6e8986a7 100644 --- a/arccore/src/collections/arccore/collections/IMemoryAllocator.h +++ b/arccore/src/collections/arccore/collections/IMemoryAllocator.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// 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 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* IMemoryAllocator.h (C) 2000-2023 */ +/* IMemoryAllocator.h (C) 2000-2024 */ /* */ /* Interface d'un allocateur mémoire. */ /*---------------------------------------------------------------------------*/ @@ -139,6 +139,9 @@ class ARCCORE_COLLECTIONS_EXPORT IMemoryAllocator */ virtual void copyMemory(MemoryAllocationArgs args, AllocatedMemoryInfo destination, AllocatedMemoryInfo source); + //! Ressource mémoire fournie par l'allocateur + virtual eMemoryResource memoryRessource() const { return eMemoryResource::Unknown; } + public: // Méthodes historiques (avant 2023) sans arguments supplémentaires. diff --git a/arccore/src/collections/arccore/collections/MemoryAllocationArgs.h b/arccore/src/collections/arccore/collections/MemoryAllocationArgs.h index 04063c7555..13a79fec40 100644 --- a/arccore/src/collections/arccore/collections/MemoryAllocationArgs.h +++ b/arccore/src/collections/arccore/collections/MemoryAllocationArgs.h @@ -34,6 +34,9 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationArgs void setMemoryLocationHint(eMemoryLocationHint mem_advice) { m_memory_location_hint = mem_advice; } eMemoryLocationHint memoryLocationHint() const { return m_memory_location_hint; } + void setHostDeviceMemoryLocation(eHostDeviceMemoryLocation v) { m_host_device_memory_location = v; } + eHostDeviceMemoryLocation hostDeviceMemoryLocation() const { return m_host_device_memory_location; } + Int16 device() const { return m_device; } void setDevice(Int16 device) { m_device = device; } @@ -49,6 +52,7 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationArgs private: eMemoryLocationHint m_memory_location_hint = eMemoryLocationHint::None; + eHostDeviceMemoryLocation m_host_device_memory_location = eHostDeviceMemoryLocation::Unknown; Int16 m_device = (-1); RunQueue* m_run_queue = nullptr; ArrayDebugInfo* m_debug_info = nullptr; diff --git a/arccore/src/collections/arccore/collections/MemoryAllocationOptions.cc b/arccore/src/collections/arccore/collections/MemoryAllocationOptions.cc index 2a235fe386..fe385c207c 100644 --- a/arccore/src/collections/arccore/collections/MemoryAllocationOptions.cc +++ b/arccore/src/collections/arccore/collections/MemoryAllocationOptions.cc @@ -38,6 +38,7 @@ allocationArgs(RunQueue* queue) const { MemoryAllocationArgs x; x.setMemoryLocationHint(m_memory_location_hint); + x.setHostDeviceMemoryLocation(m_host_device_memory_location); x.setDevice(m_device); x.setDebugInfo(m_debug_info); x.setRunQueue(queue); diff --git a/arccore/src/collections/arccore/collections/MemoryAllocationOptions.h b/arccore/src/collections/arccore/collections/MemoryAllocationOptions.h index 6b60c1ef17..7100b74277 100644 --- a/arccore/src/collections/arccore/collections/MemoryAllocationOptions.h +++ b/arccore/src/collections/arccore/collections/MemoryAllocationOptions.h @@ -60,6 +60,7 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationOptions , m_debug_info(rhs.m_debug_info) , m_device(rhs.m_device) , m_memory_location_hint(rhs.m_memory_location_hint) + , m_host_device_memory_location(rhs.m_host_device_memory_location) { if (m_debug_info) _addDebugReference(); @@ -78,6 +79,7 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationOptions _removeDebugReference(); m_allocator = rhs.m_allocator; m_memory_location_hint = rhs.m_memory_location_hint; + m_host_device_memory_location = rhs.m_host_device_memory_location; m_device = rhs.m_device; m_debug_info = rhs.m_debug_info; if (m_debug_info) @@ -93,6 +95,9 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationOptions eMemoryLocationHint memoryLocationHint() const { return m_memory_location_hint; } void setMemoryLocationHint(eMemoryLocationHint mem_advice) { m_memory_location_hint = mem_advice; } + void setHostDeviceMemoryLocation(eHostDeviceMemoryLocation v) { m_host_device_memory_location = v; } + eHostDeviceMemoryLocation hostDeviceMemoryLocation() const { return m_host_device_memory_location; } + Int16 device() const { return m_device; } void setDevice(Int16 device) { m_device = device; } @@ -106,12 +111,15 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationOptions public: + // TODO: A supprimer car ne sert que pour les tests friend bool operator==(const MemoryAllocationOptions& a, const MemoryAllocationOptions& b) { if (a.m_allocator != b.m_allocator) return false; if (a.m_memory_location_hint != b.m_memory_location_hint) return false; + if (a.m_host_device_memory_location != b.m_host_device_memory_location) + return false; if (a.m_device != b.m_device) return false; if (a.m_queue != b.m_queue) @@ -125,6 +133,7 @@ class ARCCORE_COLLECTIONS_EXPORT MemoryAllocationOptions ArrayDebugInfo* m_debug_info = nullptr; Int16 m_device = -1; eMemoryLocationHint m_memory_location_hint = eMemoryLocationHint::None; + eHostDeviceMemoryLocation m_host_device_memory_location = eHostDeviceMemoryLocation::Unknown; RunQueue* m_queue = nullptr; private: diff --git a/arccore/src/collections/tests/TestArray.cc b/arccore/src/collections/tests/TestArray.cc index 57e53b92de..abcaee588c 100644 --- a/arccore/src/collections/tests/TestArray.cc +++ b/arccore/src/collections/tests/TestArray.cc @@ -23,21 +23,29 @@ void _testArraySwap(bool use_own_swap) { std::cout << "** TestArraySwap is_own=" << use_own_swap << "\n"; + String c1_name = "TestC1"; UniqueArray c1(7); - IntSubClass* x1 = c1.unguardedBasePointer(); + c1.setDebugName(c1_name); + IntSubClass* x1 = c1.data(); std::cout << "** C1_this = " << &c1 << "\n"; std::cout << "** C1_BASE = " << x1 << "\n"; UniqueArray c2(3); - IntSubClass* x2 = c2.unguardedBasePointer(); + IntSubClass* x2 = c2.data(); std::cout << "** C2_this = " << &c2 << "\n"; std::cout << "** C2_BASE = " << x2 << "\n"; + ASSERT_EQ(c1.debugName(), c1_name); + ASSERT_EQ(c2.debugName(), String{}); + if (use_own_swap) { swap(c1, c2); } else std::swap(c1, c2); + ASSERT_EQ(c2.debugName(), c1_name); + ASSERT_EQ(c1.debugName(), String{}); + IntSubClass* after_x1 = c1.data(); IntSubClass* after_x2 = c2.data(); std::cout << "** C1_BASE_AFTER = " << after_x1 << " size=" << c1.size() << "\n"; @@ -990,6 +998,9 @@ TEST(Array, AllocatorV2) } } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + TEST(Array, DebugInfo) { using namespace Arccore; @@ -1034,6 +1045,30 @@ TEST(Array, DebugInfo) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +TEST(Collections, Memory) +{ + using namespace Arccore; + std::cout << eHostDeviceMemoryLocation::Unknown << " " + << eHostDeviceMemoryLocation::Device << " " + << eHostDeviceMemoryLocation::Host << " " + << eHostDeviceMemoryLocation::ManagedMemoryDevice << " " + << eHostDeviceMemoryLocation::ManagedMemoryHost << "\n"; + + std::cout << eMemoryResource::Unknown << " " + << eMemoryResource::Host << " " + << eMemoryResource::HostPinned << " " + << eMemoryResource::Device << " " + << eMemoryResource::UnifiedMemory << "\n"; + + UniqueArray a1; + ASSERT_EQ(a1.hostDeviceMemoryLocation(), eHostDeviceMemoryLocation::Unknown); + a1._internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation::Host); + ASSERT_EQ(a1.hostDeviceMemoryLocation(), eHostDeviceMemoryLocation::Host); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + namespace Arccore { // Instancie explicitement les classes tableaux pour garantir