Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MemoryRessourceMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MemoryRessourceMng.cc (C) 2000-2024 */
9/* */
10/* Gestion des ressources mémoire pour les CPU et accélérateurs. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/internal/MemoryRessourceMng.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/Array.h"
19#include "arcane/utils/MemoryView.h"
20#include "arcane/utils/MemoryAllocator.h"
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25namespace Arcane
26{
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace
32{
33 const char* _toName(eMemoryRessource r)
34 {
35 switch (r) {
37 return "Unknown";
39 return "Host";
41 return "HostPinned";
43 return "Device";
45 return "UnifiedMemory";
46 }
47 return "Invalid";
48 }
49
50 inline bool _isHost(eMemoryRessource r)
51 {
52 // Si on sait pas, considère qu'on est accessible de puis l'hôte.
54 return true;
56 return true;
57 return false;
58 }
59
60} // namespace
61
62extern "C++" ARCANE_UTILS_EXPORT std::ostream&
63operator<<(std::ostream& o, eMemoryRessource r)
64{
65 o << _toName(r);
66 return o;
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
73: public IMemoryCopier
74{
75 public:
76
77 void copy(ConstMemoryView from, eMemoryRessource from_mem,
78 MutableMemoryView to, eMemoryRessource to_mem,
79 [[maybe_unused]] const RunQueue* queue) override
80 {
81 // Sans support accélérateur, on peut juste faire un 'memcpy' si la mémoire
82 // est accessible depuis le CPU
83
84 if (!_isHost(from_mem))
85 ARCANE_FATAL("Source buffer is not accessible from host and no copier provided (location={0})",
86 from_mem);
87
88 if (!_isHost(to_mem))
89 ARCANE_FATAL("Destination buffer is not accessible from host and no copier provided (location={0})",
90 to_mem);
91
92 to.copyHost(from);
93 }
94};
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99MemoryRessourceMng::
100MemoryRessourceMng()
101: m_default_memory_copier(new DefaultHostMemoryCopier())
102, m_copier(m_default_memory_copier.get())
103{
104 // Par défaut on utilise l'allocateur CPU. Les allocateurs spécifiques pour
105 // les accélérateurs seront positionnés lorsqu'on aura choisi le runtime
106 // accélérateur
108 setAllocator(eMemoryRessource::Host, a);
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114int MemoryRessourceMng::
115_checkValidRessource(eMemoryRessource r)
116{
117 int x = (int)r;
118 if (x <= 0 || x >= NB_MEMORY_RESSOURCE)
119 ARCANE_FATAL("Invalid value '{0}'. Valid range is '1' to '{1}'", x, NB_MEMORY_RESSOURCE - 1);
120 return x;
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126IMemoryAllocator* MemoryRessourceMng::
127getAllocator(eMemoryRessource r, bool throw_if_not_found)
128{
129 int x = _checkValidRessource(r);
130 IMemoryAllocator* a = m_allocators[x];
131
132 // Si pas d'allocateur spécifique et qu'on n'est pas sur accélérateur,
133 // utilise platform::getAcceleratorHostMemoryAllocator().
134 if (!a && !m_is_accelerator) {
137 if (!a)
138 a = m_allocators[(int)eMemoryRessource::Host];
139 }
140 }
141
142 if (!a && throw_if_not_found)
143 ARCANE_FATAL("Allocator for ressource '{0}' is not available", r);
144
145 return a;
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
151IMemoryAllocator* MemoryRessourceMng::
152getAllocator(eMemoryRessource r)
153{
154 return getAllocator(r, true);
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
160void MemoryRessourceMng::
161setAllocator(eMemoryRessource r, IMemoryAllocator* allocator)
162{
163 int x = _checkValidRessource(r);
164 m_allocators[x] = allocator;
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170void MemoryRessourceMng::
171copy(ConstMemoryView from, eMemoryRessource from_mem,
172 MutableMemoryView to, eMemoryRessource to_mem, const RunQueue* queue)
173{
174 Int64 from_size = from.bytes().size();
175 Int64 to_size = to.bytes().size();
176 if (from_size > to_size)
177 ARCANE_FATAL("Destination copy is too small (to_size={0} from_size={1})", to_size, from_size);
178
179 m_copier->copy(from, from_mem, to, to_mem, queue);
180}
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
184
185void MemoryRessourceMng::
186genericCopy(ConstMemoryView from, MutableMemoryView to)
187{
188 IMemoryRessourceMng* mrm = platform::getDataMemoryRessourceMng();
190 mrm->_internal()->copy(from, mem_type, to, mem_type, nullptr);
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
196} // End namespace Arcane
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
File d'exécution pour un accélérateur.
static AlignedMemoryAllocator * Simd()
Allocateur garantissant l'alignement pour utiliser la vectorisation sur la plateforme cible.
IMemoryRessourceMng * getDataMemoryRessourceMng()
Gestionnaire de ressource mémoire pour les données.
IMemoryAllocator * getAcceleratorHostMemoryAllocator()
Allocateur spécifique pour les accélérateurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
eMemoryRessource
Liste des ressources mémoire disponibles.
@ HostPinned
Alloue sur l'hôte.
@ Unknown
Valeur inconnue ou non initialisée.
@ Host
Alloue sur l'hôte.
@ UnifiedMemory
Alloue en utilisant la mémoire unifiée.
@ Device
Alloue sur le device.
std::ostream & operator<<(std::ostream &ostr, eItemKind item_kind)
Opérateur de sortie sur un flot.