Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
DualUniqueArray.h
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/* DualUniqueArray.h (C) 2000-2024 */
9/* */
10/* Tableau 1D alloué à la fois sur CPU et accélérateur. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_DUALUNIQUEARRAY_H
13#define ARCANE_UTILS_DUALUNIQUEARRAY_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arccore/collections/Array.h"
18#include "arcane/utils/NumArray.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28/*!
29 * \brief Classe de base des DualUniqueArray
30 *
31 * \warning API en cours de définition. Ne pas utiliser en dehors de Arcane.
32 */
33class ARCANE_UTILS_EXPORT DualUniqueArrayBase
34{
35 protected:
36
37 static void _memoryCopy(Span<const std::byte> from, Span<std::byte> to);
38};
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42/*!
43 * \brief Représente un tableau ayant une vue à la fois sur CPU et accélérateur.
44 *
45 * \warning API en cours de définition. Ne pas utiliser en dehors de Arcane.
46 */
47template <typename DataType>
50{
51 using NumArrayType = NumArray<DataType, MDDim1>;
53
54 private:
55
56 class IModifierImpl
57 {
58 protected:
59
60 virtual ~IModifierImpl() = default;
61
62 public:
63
64 virtual SmallSpan<DataType> view() = 0;
65 virtual void resize(Int32 new_size) = 0;
66 virtual void endUpdate() = 0;
67 };
68
69 public:
70
72 {
73 friend class DualUniqueArray<DataType>;
74
75 private:
76
77 explicit Modifier(IModifierImpl* p)
78 : m_p(p)
79 {}
80
81 public:
82
83 ~Modifier()
84 {
85 m_p->endUpdate();
86 }
87
88 public:
89
90 SmallSpan<DataType> view() { return m_p->view(); }
91 void resize(Int32 new_size) { m_p->resize(new_size); }
92
93 private:
94
95 IModifierImpl* m_p = nullptr;
96 };
97
99 : public Modifier
100 {
101 friend class DualUniqueArray<DataType>;
102
103 private:
104
105 explicit HostModifier(ThatClass* data)
106 : Modifier(&data->m_array_modifier)
107 , m_data(data)
108 {}
109
110 public:
111
112 Array<DataType>& container() { return m_data->m_array; }
113
114 private:
115
116 ThatClass* m_data = nullptr;
117 };
118
119 private:
120
121 class NumArrayModifierImpl
122 : public IModifierImpl
123 {
124 friend class DualUniqueArray<DataType>;
125
126 private:
127
128 NumArrayModifierImpl(ThatClass* v)
129 : m_data(v)
130 {}
131 SmallSpan<DataType> view() override
132 {
133 SmallSpan<DataType> v = *(m_data->m_device_array);
134 return v;
135 }
136 void resize(Int32 new_size) override
137 {
138 m_data->resizeDevice(new_size);
139 }
140 void endUpdate() override
141 {
142 m_data->endUpdate(true);
143 }
144
145 private:
146
147 ThatClass* m_data = nullptr;
148 };
149
150 class UniqueArrayModifierImpl
151 : public IModifierImpl
152 {
153 friend class DualUniqueArray<DataType>;
154
155 public:
156
157 UniqueArrayModifierImpl(ThatClass* v)
158 : m_data(v)
159 {}
160 SmallSpan<DataType> view() override
161 {
162 return m_data->m_array.view();
163 }
164 void resize(Int32 new_size) override
165 {
166 m_data->m_array.resize(new_size);
167 }
168 void endUpdate() override
169 {
170 m_data->endUpdate(false);
171 }
172
173 private:
174
175 ThatClass* m_data = nullptr;
176 };
177
178 public:
179
180 DualUniqueArray()
181 : m_numarray_modifier(this)
182 , m_array_modifier(this)
183 {
184 }
185 explicit DualUniqueArray(IMemoryAllocator* a)
186 : DualUniqueArray()
187 {
188 m_array = UniqueArray<DataType>(a);
189 }
190
191 public:
192
193 SmallSpan<const DataType> hostSmallSpan() const { return m_array.view(); }
194 ConstArrayView<DataType> hostView() const { return m_array.view(); }
195
196 void reserve(Int64 capacity)
197 {
198 m_array.reserve(capacity);
199 }
200 void resizeHost(Int32 new_size)
201 {
202 m_array.resize(new_size);
203 m_is_valid_numarray = false;
204 }
205 void fillHost(const DataType& value)
206 {
207 m_array.fill(value);
208 m_is_valid_numarray = false;
209 }
210 void resizeDevice(Int32 new_size)
211 {
212 _checkCreateNumArray();
213 m_device_array->resize(new_size);
214 m_is_valid_array = false;
215 }
216 void clearHost()
217 {
218 m_array.clear();
219 m_is_valid_numarray = false;
220 }
221 Int64 size() const { return m_array.size(); }
222 SmallSpan<const DataType> view(bool is_device)
223 {
224 sync(is_device);
225 if (is_device) {
226 SmallSpan<const DataType> v = *(m_device_array.get());
227 return v;
228 }
229 else {
230 return hostSmallSpan();
231 }
232 }
233 void sync(bool is_device)
234 {
235 if (is_device) {
236 _checkUpdateDeviceView();
237 }
238 else {
239 _checkUpdateHostView();
240 }
241 }
242 void endUpdateHost()
243 {
244 m_is_valid_array = true;
245 m_is_valid_numarray = false;
246 }
247 void endUpdate(bool is_device)
248 {
249 m_is_valid_array = !is_device;
250 m_is_valid_numarray = is_device;
251 }
252 Modifier modifier(bool is_device)
253 {
254 if (is_device) {
255 _checkCreateNumArray();
256 return Modifier(&m_numarray_modifier);
257 }
258 return Modifier(&m_array_modifier);
259 }
260 HostModifier hostModifier()
261 {
262 return HostModifier(this);
263 }
264
265 private:
266
267 UniqueArray<DataType> m_array;
268 std::unique_ptr<NumArrayType> m_device_array;
269 SmallSpan<DataType> m_device_view;
270 NumArrayModifierImpl m_numarray_modifier;
271 UniqueArrayModifierImpl m_array_modifier;
272 bool m_is_valid_array = true;
273 bool m_is_valid_numarray = false;
274
275 private:
276
277 void _checkUpdateDeviceView()
278 {
279 if (!m_is_valid_numarray) {
280 _checkCreateNumArray();
281 MDSpan<DataType, MDDim1> s(m_array.data(), ArrayIndex<1>(m_array.size()));
282 m_device_array->copy(s);
283 m_is_valid_numarray = true;
284 }
285 m_device_view = *(m_device_array.get());
286 }
287 void _checkUpdateHostView()
288 {
289 if (!m_is_valid_array) {
290 _checkCreateNumArray();
291 SmallSpan<const DataType> device_view = *(m_device_array.get());
292 m_array.resize(device_view.size());
293 _memoryCopy(asBytes(device_view), asWritableBytes(m_array.span()));
294 m_is_valid_array = true;
295 }
296 }
297 void _checkCreateNumArray()
298 {
299 if (!m_device_array) {
300 m_device_array = std::make_unique<NumArrayType>(eMemoryRessource::Device);
301 if (m_is_valid_array)
302 m_device_array->resize(m_array.size());
303 }
304 }
305};
306
307/*---------------------------------------------------------------------------*/
308/*---------------------------------------------------------------------------*/
309
310} // namespace Arcane
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
314
315#endif
Classe de base des DualUniqueArray.
Représente un tableau ayant une vue à la fois sur CPU et accélérateur.
Tableaux multi-dimensionnels pour les types numériques accessibles sur accélérateurs.
Integer size() const
Nombre d'éléments du vecteur.
Classe de base des vecteurs 1D de données.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > view() const
Vue mutable sur ce tableau.
void fill(ConstReferenceType value)
Remplit le tableau avec la valeur value.
void clear()
Supprime les éléments du tableau.
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
Vue d'un tableau d'éléments de type T.
Definition Span.h:510
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ Device
Alloue sur le device.
detail::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets non modifiables.
Definition Span.h:881
detail::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets modifiables.
Definition Span.h:916