Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MemoryView.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/* MemoryView.h (C) 2000-2024 */
9/* */
10/* Vues constantes ou modifiables sur une zone mémoire. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_MEMORYVIEW_H
13#define ARCANE_UTILS_MEMORYVIEW_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArrayView.h"
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace Arcane
23{
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27/*!
28 * \ingroup MemoryView
29 * \brief Vue constante sur une zone mémoire contigue contenant des
30 * éléments de taille fixe.
31 *
32 * Les fonctions makeConstMemoryView() permettent de créer des instances
33 * de cette classe.
34 *
35 * \warning API en cours de définition. Ne pas utiliser en dehors de Arcane.
36 */
37class ARCANE_UTILS_EXPORT ConstMemoryView
38{
39 friend ARCANE_UTILS_EXPORT ConstMemoryView
40 makeConstMemoryView(const void* ptr, Int32 datatype_size, Int64 nb_element);
41
42 public:
43
44 using SpanType = Span<const std::byte>;
45 friend MutableMemoryView;
46
47 public:
48
49 ConstMemoryView() = default;
50 explicit constexpr ConstMemoryView(Span<const std::byte> bytes)
51 : m_bytes(bytes)
52 , m_nb_element(bytes.size())
53 , m_datatype_size(1)
54 {}
55 template <typename DataType> explicit constexpr ConstMemoryView(Span<DataType> v)
56 : ConstMemoryView(Span<const DataType>(v), 1)
57 {}
58 template <typename DataType> explicit constexpr ConstMemoryView(Span<const DataType> v)
59 : ConstMemoryView(v, 1)
60 {}
61 template <typename DataType> explicit constexpr ConstMemoryView(ConstArrayView<DataType> v)
62 : ConstMemoryView(Span<const DataType>(v), 1)
63 {}
64 template <typename DataType> explicit constexpr ConstMemoryView(ArrayView<DataType> v)
65 : ConstMemoryView(Span<const DataType>(v), 1)
66 {}
67 template <typename DataType> constexpr ConstMemoryView(ConstArrayView<DataType> v, Int32 nb_component)
68 : ConstMemoryView(Span<const DataType>(v), nb_component)
69 {}
70 template <typename DataType> constexpr ConstMemoryView(ArrayView<DataType> v, Int32 nb_component)
71 : ConstMemoryView(Span<const DataType>(v), nb_component)
72 {}
73 template <typename DataType> constexpr ConstMemoryView(Span<DataType> v, Int32 nb_component)
74 : ConstMemoryView(Span<const DataType>(v), nb_component)
75 {
76 }
77 template <typename DataType> constexpr ConstMemoryView(Span<const DataType> v, Int32 nb_component)
78 : m_nb_element(v.size())
79 , m_datatype_size(static_cast<Int32>(sizeof(DataType)) * nb_component)
80 {
81 auto x = asBytes(v);
82 m_bytes = SpanType(x.data(), x.size() * nb_component);
83 }
84
85 public:
86
87 template <typename DataType> constexpr ConstMemoryView&
88 operator=(Span<DataType> v)
89 {
90 m_bytes = asBytes(v);
91 m_nb_element = v.size();
92 m_datatype_size = static_cast<Int32>(sizeof(DataType));
93 return (*this);
94 }
95
96 private:
97
98 constexpr ConstMemoryView(Span<const std::byte> bytes, Int32 datatype_size, Int64 nb_element)
99 : m_bytes(bytes)
100 , m_nb_element(nb_element)
101 , m_datatype_size(datatype_size)
102 {}
103
104 public:
105
106 //! Vue sous forme d'octets
107 constexpr SpanType bytes() const { return m_bytes; }
108
109 //! Pointeur sur la zone mémoire
110 constexpr const std::byte* data() const { return m_bytes.data(); }
111
112 //! Nombre d'éléments
113 constexpr Int64 nbElement() const { return m_nb_element; }
114
115 //! Taille du type de donnée associé (1 par défaut)
116 constexpr Int32 datatypeSize() const { return m_datatype_size; }
117
118 //! Sous-vue à partir de l'indice \a begin_index et contenant \a nb_element
119 constexpr ConstMemoryView subView(Int64 begin_index, Int64 nb_element) const
120 {
121 Int64 byte_offset = begin_index * m_datatype_size;
122 auto sub_bytes = m_bytes.subspan(byte_offset, nb_element * m_datatype_size);
123 return { sub_bytes, m_datatype_size, nb_element };
124 }
125
126 public:
127
128 /*!
129 * \brief Copie dans l'instance indexée les données de \a v.
130 *
131 * L'opération est équivalente au pseudo-code suivant:
132 *
133 * \code
134 * Int64 n = indexes.size();
135 * for( Int64 i=0; i<n; ++i )
136 * v[i] = this[indexes[i]];
137 * \endcode
138 *
139 * \pre this.datatypeSize() == v.datatypeSize();
140 * \pre v.nbElement() >= indexes.size();
141 */
142 void copyToIndexesHost(MutableMemoryView v, Span<const Int32> indexes) const;
143
144 /*!
145 * \brief Copie dans l'instance indexée les données de \a v.
146 *
147 * L'opération est équivalente au pseudo-code suivant:
148 *
149 * \code
150 * Int32 n = indexes.size();
151 * for( Int32 i=0; i<n; ++i )
152 * v[i] = this[indexes[i]];
153 * \endcode
154 *
155 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
156 *
157 * \pre this.datatypeSize() == v.datatypeSize();
158 * \pre v.nbElement() >= indexes.size();
159 */
160 void copyToIndexes(MutableMemoryView v, SmallSpan<const Int32> indexes,
161 RunQueue* run_queue = nullptr) const;
162
163 public:
164
165 //! Vue convertie en un Span
166 ARCANE_DEPRECATED_REASON("Use bytes() instead")
167 SpanType span() const { return m_bytes; }
168
169 ARCANE_DEPRECATED_REASON("Use bytes().size() instead")
170 constexpr Int64 size() const { return m_bytes.size(); }
171
172 private:
173
174 SpanType m_bytes;
175 Int64 m_nb_element = 0;
176 Int32 m_datatype_size = 0;
177};
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181/*!
182 * \ingroup MemoryView
183 *
184 * \brief Vue modifiable sur une zone mémoire contigue contenant des
185 * éléments de taille fixe.
186 *
187 * Les fonctions makeMutableMemoryView() permettent de créer des instances
188 * de cette classe.
189 *
190 * \warning API en cours de définition. Ne pas utiliser en dehors de Arcane.
191 */
192class ARCANE_UTILS_EXPORT MutableMemoryView
193{
194 friend ARCANE_UTILS_EXPORT MutableMemoryView
195 makeMutableMemoryView(void* ptr, Int32 datatype_size, Int64 nb_element);
196
197 public:
198
199 using SpanType = Span<std::byte>;
200
201 public:
202
203 MutableMemoryView() = default;
204 explicit constexpr MutableMemoryView(SpanType bytes)
205 : m_bytes(bytes)
206 , m_nb_element(bytes.size())
207 , m_datatype_size(1)
208 {}
209 template <typename DataType> explicit constexpr MutableMemoryView(Span<DataType> v)
210 : MutableMemoryView(v, 1)
211 {}
212 template <typename DataType> explicit constexpr MutableMemoryView(ArrayView<DataType> v)
213 : MutableMemoryView(Span<DataType>(v), 1)
214 {}
215 template <typename DataType> explicit constexpr MutableMemoryView(ArrayView<DataType> v, Int32 nb_component)
216 : MutableMemoryView(Span<DataType>(v), nb_component)
217 {}
218 template <typename DataType> constexpr MutableMemoryView(Span<DataType> v, Int32 nb_component)
219 : m_nb_element(v.size())
220 , m_datatype_size(static_cast<Int32>(sizeof(DataType)) * nb_component)
221 {
222 auto x = asWritableBytes(v);
223 m_bytes = SpanType(x.data(), x.size() * nb_component);
224 }
225
226 public:
227
228 template <typename DataType> constexpr MutableMemoryView&
229 operator=(Span<DataType> v)
230 {
231 m_bytes = asWritableBytes(v);
232 m_nb_element = v.size();
233 m_datatype_size = static_cast<Int32>(sizeof(DataType));
234 return (*this);
235 }
236
237 private:
238
239 constexpr MutableMemoryView(Span<std::byte> bytes, Int32 datatype_size, Int64 nb_element)
240 : m_bytes(bytes)
241 , m_nb_element(nb_element)
242 , m_datatype_size(datatype_size)
243 {}
244
245 public:
246
247 constexpr operator ConstMemoryView() const { return { m_bytes, m_datatype_size, m_nb_element }; }
248
249 public:
250
251 //! Vue sous forme d'octets
252 constexpr SpanType bytes() const { return m_bytes; }
253
254 //! Pointeur sur la zone mémoire
255 constexpr std::byte* data() const { return m_bytes.data(); }
256
257 //! Nombre d'éléments
258 constexpr Int64 nbElement() const { return m_nb_element; }
259
260 //! Taille du type de donnée associé (1 par défaut)
261 constexpr Int32 datatypeSize() const { return m_datatype_size; }
262
263 //! Sous-vue à partir de l'indice \a begin_index
264 constexpr MutableMemoryView subView(Int64 begin_index, Int64 nb_element) const
265 {
266 Int64 byte_offset = begin_index * m_datatype_size;
267 auto sub_bytes = m_bytes.subspan(byte_offset, nb_element * m_datatype_size);
268 return { sub_bytes, m_datatype_size, nb_element };
269 }
270
271 public:
272
273 /*!
274 * \brief Copie dans l'instance les données de \a v.
275 *
276 * Utilise std::memmove pour la copie.
277 *
278 * \pre v.bytes.size() >= bytes.size()
279 */
280 void copyHost(ConstMemoryView v) const;
281
282 /*!
283 * \brief Copie dans l'instance les données indexées de \a v.
284 *
285 * L'opération est équivalente au pseudo-code suivant:
286 *
287 * \code
288 * Int64 n = indexes.size();
289 * for( Int64 i=0; i<n; ++i )
290 * this[indexes[i]] = v[i];
291 * \endcode
292 *
293 * \pre this.datatypeSize() == v.datatypeSize();
294 * \pre this.nbElement() >= indexes.size();
295 */
296 void copyFromIndexesHost(ConstMemoryView v, Span<const Int32> indexes) const;
297
298 /*!
299 * \brief Copie dans l'instance les données indexées de \a v.
300 *
301 * L'opération est équivalente au pseudo-code suivant:
302 *
303 * \code
304 * Int32 n = indexes.size();
305 * for( Int32 i=0; i<n; ++i )
306 * this[indexes[i]] = v[i];
307 * \endcode
308 *
309 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
310 *
311 * \pre this.datatypeSize() == v.datatypeSize();
312 * \pre this.nbElement() >= indexes.size();
313 */
314 void copyFromIndexes(ConstMemoryView v, SmallSpan<const Int32> indexes,
315 RunQueue* run_queue = nullptr) const;
316
317 /*!
318 * \brief Remplit dans l'instance les données de \a v.
319 *
320 * \a v doit avoir une seule valeur. Cette valeur sera utilisée
321 * pour remplir les valeur de l'instance aux indices spécifiés par
322 * \a indexes. Elle doit être accessible depuis l'hôte.
323 *
324 * L'opération est équivalente au pseudo-code suivant:
325 *
326 * \code
327 * Int32 n = indexes.size();
328 * for( Int32 i=0; i<n; ++i )
329 * this[indexes[i]] = v[0];
330 * \endcode
331 *
332 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
333 *
334 * \pre this.datatypeSize() == v.datatypeSize();
335 * \pre this.nbElement() >= indexes.size();
336 */
337 void fillIndexes(ConstMemoryView v, SmallSpan<const Int32> indexes,
338 RunQueue* run_queue = nullptr) const;
339
340 /*!
341 * \brief Remplit les éléments de l'instance avec la valeur \a v.
342 *
343 * \a v doit avoir une seule valeur. Elle doit être accessible depuis l'hôte.
344 *
345 * L'opération est équivalente au pseudo-code suivant:
346 *
347 * \code
348 * Int32 n = nbElement();
349 * for( Int32 i=0; i<n; ++i )
350 * this[i] = v[0];
351 * \endcode
352 *
353 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
354 *
355 * \pre this.datatypeSize() == v.datatypeSize();
356 */
357 void fill(ConstMemoryView v, RunQueue* run_queue = nullptr) const;
358
359 public:
360
361 ARCANE_DEPRECATED_REASON("Use bytes() instead")
362 constexpr SpanType span() const { return m_bytes; }
363
364 ARCANE_DEPRECATED_REASON("Use bytes().size() instead")
365 constexpr Int64 size() const { return m_bytes.size(); }
366
367 private:
368
369 SpanType m_bytes;
370 Int64 m_nb_element = 0;
371 Int32 m_datatype_size = 0;
372};
373
374/*---------------------------------------------------------------------------*/
375/*---------------------------------------------------------------------------*/
376/*!
377 * \ingroup MemoryView
378 *
379 * \brief Liste de vues constantes sur des zones mémoires contigues.
380 *
381 * \warning API en cours de définition. Ne pas utiliser en dehors de Arcane.
382 */
383class ARCANE_UTILS_EXPORT ConstMultiMemoryView
384{
385 public:
386
387 ConstMultiMemoryView(SmallSpan<const Span<const std::byte>> views, Int32 datatype_size)
388 : m_views(views)
389 , m_datatype_size(datatype_size)
390 {}
391 ConstMultiMemoryView(SmallSpan<const Span<std::byte>> views, Int32 datatype_size)
392 : m_datatype_size(datatype_size)
393 {
394 auto* ptr = reinterpret_cast<const Span<const std::byte>*>(views.data());
395 m_views = { ptr, views.size() };
396 }
397
398 public:
399
400 /*!
401 * \brief Copie dans l'instance indexée les données de \a v.
402 *
403 * L'opération est équivalente au pseudo-code suivant:
404 *
405 * \code
406 * Int32 n = indexes.size();
407 * for( Int32 i=0; i<n; ++i ){
408 * Int32 index0 = indexes[ (i*2) ];
409 * Int32 index1 = indexes[ (i*2)+1 ];
410 * v[i] = this[index0][index1];
411 * }
412 * \endcode
413 *
414 * Le tableau des indexes doit avoir une taille multiple de 2. Les valeurs
415 * paires servent à indexer le premier tableau et les valeurs impaires le 2ème.
416 *
417 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
418 *
419 * \pre this.datatypeSize() == v.datatypeSize();
420 * \pre v.nbElement() >= indexes.size();
421 */
422 void copyToIndexes(MutableMemoryView v, SmallSpan<const Int32> indexes,
423 RunQueue* run_queue = nullptr);
424
425 private:
426
427 SmallSpan<const Span<const std::byte>> m_views;
428 Int32 m_datatype_size;
429};
430
431/*---------------------------------------------------------------------------*/
432/*---------------------------------------------------------------------------*/
433/*!
434 * \ingroup MemoryView
435 *
436 * \brief Liste de vues modifiables sur des zones mémoires contigues.
437 *
438 * \warning API en cours de définition. Ne pas utiliser en dehors de Arcane.
439 */
440class ARCANE_UTILS_EXPORT MutableMultiMemoryView
441{
442 public:
443
444 MutableMultiMemoryView(SmallSpan<Span<std::byte>> views, Int32 datatype_size)
445 : m_views(views)
446 , m_datatype_size(datatype_size)
447 {}
448
449 public:
450
451 /*!
452 * \brief Copie dans l'instance indexée les données de \a v.
453 *
454 * L'opération est équivalente au pseudo-code suivant:
455 *
456 * \code
457 * Int32 n = indexes.size();
458 * for( Int32 i=0; i<n; ++i ){
459 * Int32 index0 = indexes[ (i*2) ];
460 * Int32 index1 = indexes[ (i*2)+1 ];
461 * this[index0][index1] = v[i];
462 * }
463 * \endcode
464 *
465 * Le tableau des indexes doit avoir une taille multiple de 2. Les valeurs
466 * paires servent à indexer le premier tableau et les valeurs impaires le 2ème.
467 *
468 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
469 *
470 * \pre this.datatypeSize() == v.datatypeSize();
471 * \pre v.nbElement() >= indexes.size();
472 */
473 void copyFromIndexes(ConstMemoryView v, SmallSpan<const Int32> indexes,
474 RunQueue* run_queue = nullptr);
475
476 /*!
477 * \brief Remplit dans l'instance les données de \a v.
478 *
479 * \a v doit avoir une seule valeur. Cette valeur sera utilisée
480 * pour remplir les valeur de l'instance aux indices spécifiés par
481 * \a indexes. Elle doit être accessible depuis l'hôte.
482 *
483 * L'opération est équivalente au pseudo-code suivant:
484 *
485 * \code
486 * Int32 n = indexes.size();
487 * for( Int32 i=0; i<n; ++i ){
488 * Int32 index0 = indexes[ (i*2) ];
489 * Int32 index1 = indexes[ (i*2)+1 ];
490 * this[index0][index1] = v[0];
491 * }
492 *
493 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
494 *
495 * \pre this.datatypeSize() == v.datatypeSize();
496 * \pre this.nbElement() >= indexes.size();
497 */
498 void fillIndexes(ConstMemoryView v, SmallSpan<const Int32> indexes,
499 RunQueue* run_queue = nullptr);
500
501 /*!
502 * \brief Remplit les éléments de l'instance avec la valeur \a v.
503 *
504 * \a v doit avoir une seule valeur. Elle doit être accessible depuis l'hôte.
505 *
506 * L'opération est équivalente au pseudo-code suivant:
507 *
508 * \code
509 * Int32 n = nbElement();
510 * for( Int32 i=0; i<n; ++i ){
511 * Int32 index0 = (i*2);
512 * Int32 index1 = (i*2)+1;
513 * this[index0][index1] = v[0];
514 * }
515 *
516 * Si \a run_queue n'est pas nul, elle sera utilisée pour la copie.
517 *
518 * \pre this.datatypeSize() == v.datatypeSize();
519 */
520 void fill(ConstMemoryView v, RunQueue* run_queue = nullptr);
521
522 private:
523
524 SmallSpan<Span<std::byte>> m_views;
525 Int32 m_datatype_size;
526};
527
528/*---------------------------------------------------------------------------*/
529/*---------------------------------------------------------------------------*/
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
533
534//! Créé une vue mémoire constante à partir d'un \a Span
535template <typename DataType> ConstMemoryView
536makeMemoryView(Span<DataType> v)
537{
538 return ConstMemoryView(v);
539}
540
541//! Créé une vue mémoire constante sur l'adresse \a v
542template <typename DataType> ConstMemoryView
543makeMemoryView(const DataType* v)
544{
545 return ConstMemoryView(Span<const DataType>(v, 1));
546}
547
548/*---------------------------------------------------------------------------*/
549/*---------------------------------------------------------------------------*/
550
551//! Créé une vue mémoire modifiable à partir d'un \a Span
552template <typename DataType> MutableMemoryView
553makeMutableMemoryView(Span<DataType> v)
554{
555 return MutableMemoryView(v);
556}
557
558/*---------------------------------------------------------------------------*/
559/*---------------------------------------------------------------------------*/
560
561//! Créé une vue mémoire modifiable sur l'adresse \a v
562template <typename DataType> MutableMemoryView
563makeMutableMemoryView(DataType* v)
564{
565 return MutableMemoryView(Span<DataType>(v, 1));
566}
567
568/*---------------------------------------------------------------------------*/
569/*---------------------------------------------------------------------------*/
570/*!
571 * \brief Créé une vue mémoire modifiable.
572 *
573 * \param ptr adresse de la zone mémoire.
574 * \param datatype_size taille (en octet) du type de la donnée.
575 * \param nb_element nombre d'éléments de la vue.
576 *
577 * La zone mémoire aura pour taille datatype_size * nb_element octets.
578 */
579extern "C++" ARCANE_UTILS_EXPORT MutableMemoryView
580makeMutableMemoryView(void* ptr, Int32 datatype_size, Int64 nb_element);
581
582/*---------------------------------------------------------------------------*/
583/*---------------------------------------------------------------------------*/
584/*!
585 * \brief Créé une vue mémoire en lecture seule.
586 *
587 * \param ptr adresse de la zone mémoire.
588 * \param datatype_size taille (en octet) du type de la donnée.
589 * \param nb_element nombre d'éléments de la vue.
590 *
591 * La zone mémoire aura pour taille datatype_size * nb_element octets.
592 */
593extern "C++" ARCANE_UTILS_EXPORT ConstMemoryView
594makeConstMemoryView(const void* ptr, Int32 datatype_size, Int64 nb_element);
595
596/*---------------------------------------------------------------------------*/
597/*---------------------------------------------------------------------------*/
598
599} // End namespace Arcane
600
601/*---------------------------------------------------------------------------*/
602/*---------------------------------------------------------------------------*/
603
604#endif
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
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