Arcane  v3.14.10.0
Documentation développeur
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/*---------------------------------------------------------------------------*/
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/*---------------------------------------------------------------------------*/
47template <typename DataType>
50{
53
54 private:
55
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
122 : public IModifierImpl
123 {
124 friend class DualUniqueArray<DataType>;
125
126 private:
127
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
151 : public IModifierImpl
152 {
153 friend class DualUniqueArray<DataType>;
154
155 public:
156
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
181 : m_numarray_modifier(this)
182 , m_array_modifier(this)
183 {
184 }
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.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Integer size() const
Nombre d'éléments du vecteur.
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.
-*- 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