Arcane  v4.1.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AcceleratorMemoryAllocatorBase.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* AcceleratorMemoryAllocatorBase.cc (C) 2000-2025 */
9/* */
10/* Classe de base d'un allocateur spécifique pour accélérateur. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/accelerator/core/internal/AcceleratorMemoryAllocatorBase.h"
15
16#include "arccore/base/Convert.h"
17#include "arccore/trace/ITraceMng.h"
18
19#include "arcane/utils/PlatformUtils.h"
20
21#include <iostream>
22#include <sstream>
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane::Accelerator
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33void BlockAllocatorWrapper::
34dumpStats(std::ostream& ostr, const String& name)
35{
36 ostr << "Allocator '" << name << "' : nb_allocate=" << m_nb_allocate
37 << " nb_unaligned=" << m_nb_unaligned_allocate
38 << "\n";
39}
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47AcceleratorMemoryAllocatorBase::
48AcceleratorMemoryAllocatorBase(const String& allocator_name, IUnderlyingAllocator* underlying_allocator)
49: AlignedMemoryAllocator3(128)
50, m_direct_sub_allocator(underlying_allocator)
51, m_memory_pool(m_direct_sub_allocator.get(), allocator_name)
52, m_sub_allocator(m_direct_sub_allocator.get())
53, m_allocator_name(allocator_name)
54{
55 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_MEMORY_PRINT_LEVEL", true))
56 m_print_level = v.value();
57}
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62void AcceleratorMemoryAllocatorBase::
63finalize(ITraceMng* tm)
64{
65 if (m_print_level >= 1) {
66 std::ostringstream ostr;
67 if (m_use_memory_pool) {
68 m_memory_pool.dumpStats(ostr);
69 m_memory_pool.dumpFreeMap(ostr);
70 }
71 ostr << "Allocator '" << m_allocator_name << "' nb_realloc=" << m_nb_reallocate
72 << " realloc_copy=" << m_reallocate_size << "\n";
73 m_block_wrapper.dumpStats(ostr, m_allocator_name);
74 if (tm)
75 tm->info() << ostr.str();
76 else
77 std::cout << ostr.str();
78 }
79
80 m_memory_pool.freeCachedMemory();
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86AllocatedMemoryInfo AcceleratorMemoryAllocatorBase::
87reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_info, Int64 new_size)
88{
89 ++m_nb_reallocate;
90 Int64 current_size = current_info.size();
91 m_reallocate_size += current_size;
92 String array_name = args.arrayName();
93 const bool do_print = (m_print_level >= 2);
94 if (do_print) {
95 std::cout << "Reallocate allocator=" << m_allocator_name
96 << " current_size=" << current_size
97 << " current_capacity=" << current_info.capacity()
98 << " new_capacity=" << new_size
99 << " ptr=" << current_info.baseAddress();
100 if (array_name.null() && m_print_level >= 3) {
101 std::cout << " stack=" << platform::getStackTrace();
102 }
103 else {
104 std::cout << " name=" << array_name;
105 if (m_print_level >= 4)
106 std::cout << " stack=" << platform::getStackTrace();
107 }
108 std::cout << "\n";
109 }
110 if (m_use_memory_pool)
111 _removeHint(current_info.baseAddress(), current_size, args);
112 AllocatedMemoryInfo a = allocate(args, new_size);
113 // TODO: supprimer les Hint après le deallocate car la zone mémoire peut être réutilisée.
114 m_direct_sub_allocator->doMemoryCopy(a.baseAddress(), current_info.baseAddress(), current_size);
115 deallocate(args, current_info);
116 return a;
117}
118
120void AcceleratorMemoryAllocatorBase::
121_doInitializeUVM()
122{
123 bool do_page_allocate = true;
124 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_CUDA_UM_PAGE_ALLOC", true))
125 do_page_allocate = (v.value() != 0);
126 Int64 page_size = platform::getPageSize();
127 m_block_wrapper.initialize(page_size, do_page_allocate);
128
129 bool use_memory_pool = false;
130 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_MEMORY_POOL", true))
131 use_memory_pool = (v.value() & static_cast<int>(MemoryPoolFlags::UVM)) != 0;
132 _setUseMemoryPool(use_memory_pool);
133}
134
136void AcceleratorMemoryAllocatorBase::
137_doInitializeHostPinned()
138{
139 bool use_memory_pool = false;
140 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_MEMORY_POOL", true))
141 use_memory_pool = (v.value() & static_cast<int>(MemoryPoolFlags::HostPinned)) != 0;
142 _setUseMemoryPool(use_memory_pool);
143 m_block_wrapper.initialize(128, use_memory_pool);
144}
145
147void AcceleratorMemoryAllocatorBase::
148_doInitializeDevice()
149{
150 bool use_memory_pool = false;
151 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_MEMORY_POOL", true))
152 use_memory_pool = (v.value() & static_cast<int>(MemoryPoolFlags::Device)) != 0;
153 _setUseMemoryPool(use_memory_pool);
154 m_block_wrapper.initialize(128, use_memory_pool);
155}
156
157// IMPORTANT: doit être appelé avant toute allocation et ne plus être modifié ensuite.
158void AcceleratorMemoryAllocatorBase::
159_setUseMemoryPool(bool is_used)
160{
161 IMemoryPoolAllocator* mem_pool = &m_memory_pool;
162 IMemoryPoolAllocator* direct = m_direct_sub_allocator.get();
163 m_sub_allocator = (is_used) ? mem_pool : direct;
164 m_use_memory_pool = is_used;
165 if (is_used) {
166 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_MEMORY_POOL_MAX_BLOCK_SIZE", true)) {
167 if (v.value() < 0)
168 ARCANE_FATAL("Invalid value '{0}' for memory pool max block size");
169 size_t block_size = static_cast<size_t>(v.value());
170 m_memory_pool.setMaxCachedBlockSize(block_size);
171 }
172 }
173}
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
178} // namespace Arcane::Accelerator
179
180 /*---------------------------------------------------------------------------*/
181 /*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) final
Alloue de la mémoire pour new_size octets et retourne le pointeur.
void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo mem_info) final
Libère la mémoire dont l'adresse de base est ptr.
std::atomic< Int32 > m_nb_allocate
Nombre d'allocations.
std::atomic< Int32 > m_nb_unaligned_allocate
Nombre d'allocations non alignées.
Informations sur une zone mémoire allouée.
void * baseAddress() const
Adresse du début de la zone allouée.
Int64 size() const
Taille en octets de la zone mémoire utilisée. (-1) si inconnue.
Int64 capacity() const
Taille en octets de la zone mémoire allouée. (-1) si inconnue.
Classe template pour convertir un type.
Classe contenant des informations pour spécialiser les allocations.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:305
Interface d'un allocateur pour un MemoryPool.
Definition MemoryPool.h:39
Espace de nom pour l'utilisation des accélérateurs.
ARCCORE_BASE_EXPORT String getStackTrace()
Retourne une chaîne de caractere contenant la pile d'appel.
Int64 getPageSize()
Taille des pages du système hôte en octets.
std::int64_t Int64
Type entier signé sur 64 bits.