Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
ArrayExtents.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/* ArrayExtents.h (C) 2000-2024 */
9/* */
10/* Gestion du nombre d'éléments par dimension pour les tableaux N-dimensions.*/
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_ARRAYEXTENTS_H
13#define ARCANE_UTILS_ARRAYEXTENTS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArrayView.h"
18#include "arcane/utils/ArrayIndex.h"
19#include "arcane/utils/ArrayLayout.h"
20#include "arcane/utils/ArrayExtentsValue.h"
21
22#include "arccore/base/Span.h"
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32/*!
33 * \brief Spécialisation de ArrayStrideBase pour les tableaux de dimension 0 (les scalaires)
34 */
35template <>
37{
38 public:
39
40 ArrayStridesBase() = default;
41 //! Valeur du pas de la \a i-ème dimension.
42 ARCCORE_HOST_DEVICE SmallSpan<const Int32> asSpan() const { return {}; }
43 //! Value totale du pas
44 ARCCORE_HOST_DEVICE Int64 totalStride() const { return 1; }
45 ARCCORE_HOST_DEVICE static ArrayStridesBase<0> fromSpan([[maybe_unused]] Span<const Int32> strides)
46 {
47 // TODO: vérifier la taille de \a strides
48 return {};
49 }
50};
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54/*!
55 * \brief Classe pour conserver le pas dans chaque dimension.
56 *
57 * Le pas pour une dimension est la distance en mémoire entre deux éléments
58 * du tableau pour cette dimension. En général le pas est égal au nombre
59 * d'éléments dans la dimension sauf si on utilise des marges (padding) par
60 * exemple pour aligner certaines dimensions.
61 */
62template <int RankValue>
64{
65 public:
66
67 ArrayStridesBase() = default;
68 //! Valeur du pas de la \a i-ème dimension.
69 ARCCORE_HOST_DEVICE Int32 stride(int i) const { return m_strides[i]; }
70 ARCCORE_HOST_DEVICE Int32 operator()(int i) const { return m_strides[i]; }
71 ARCCORE_HOST_DEVICE SmallSpan<const Int32> asSpan() const { return { m_strides.data(), RankValue }; }
72 //! Valeur totale du pas
73 ARCCORE_HOST_DEVICE Int64 totalStride() const
74 {
75 Int64 nb_element = 1;
76 for (int i = 0; i < RankValue; i++)
77 nb_element *= m_strides[i];
78 return nb_element;
79 }
80 // Instance contenant les dimensions après la première
81 ARCCORE_HOST_DEVICE ArrayStridesBase<RankValue - 1> removeFirstStride() const
82 {
83 return ArrayStridesBase<RankValue - 1>::fromSpan({ m_strides.data() + 1, RankValue - 1 });
84 }
85 /*!
86 * \brief Construit une instance à partir des valeurs données dans \a stride.
87 * \pre stride.size() == RankValue.
88 */
89 ARCCORE_HOST_DEVICE static ArrayStridesBase<RankValue> fromSpan(Span<const Int32> strides)
90 {
92 // TODO: vérifier la taille
93 for (int i = 0; i < RankValue; ++i)
94 v.m_strides[i] = strides[i];
95 return v;
96 }
97
98 protected:
99
100 std::array<Int32, RankValue> m_strides = {};
101};
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108/*!
109 * \brief Spécialisation de ArrayExtentsBase pour les tableaux de dimension 0 (les scalaires)
110 */
111template <>
113{
114 public:
115
116 ArrayExtentsBase() = default;
117 //! Nombre d'élément de la \a i-ème dimension.
118 constexpr ARCCORE_HOST_DEVICE SmallSpan<const Int32> asSpan() const { return {}; }
119 //! Nombre total d'eléments
120 constexpr ARCCORE_HOST_DEVICE Int32 totalNbElement() const { return 1; }
121 ARCCORE_HOST_DEVICE static ArrayExtentsBase<ExtentsV<>> fromSpan([[maybe_unused]] Span<const Int32> extents)
122 {
123 // TODO: vérifier la taille de \a extents
124 return {};
125 }
126};
127
128/*---------------------------------------------------------------------------*/
129/*---------------------------------------------------------------------------*/
130/*!
131 * \brief Classe pour conserver le nombre d'éléments dans chaque dimension.
132 */
133template <typename Extents>
135: protected Extents::ArrayExtentsValueType
136{
137 protected:
138
139 using BaseClass = typename Extents::ArrayExtentsValueType;
141 using DynamicDimsType = typename Extents::DynamicDimsType;
142
143 public:
144
145 using BaseClass::asStdArray;
146 using BaseClass::constExtent;
147 using BaseClass::dynamicExtents;
148 using BaseClass::getIndices;
149 using BaseClass::totalNbElement;
150
151 public:
152
153 ARCCORE_HOST_DEVICE constexpr ArrayExtentsBase()
154 : BaseClass()
155 {}
156
157 protected:
158
159 explicit constexpr ARCCORE_HOST_DEVICE ArrayExtentsBase(SmallSpan<const Int32> extents)
160 : BaseClass(extents)
161 {
162 }
163
164 explicit constexpr ARCCORE_HOST_DEVICE ArrayExtentsBase(DynamicDimsType extents)
165 : BaseClass(extents)
166 {
167 }
168
169 public:
170
171 //! TEMPORARY: Positionne à \a v le nombre d'éléments de la dimension 0.
172 ARCCORE_HOST_DEVICE void setExtent0(Int32 v) { this->m_extent0.v = v; }
173
174 // Instance contenant les dimensions après la première
175 ARCCORE_HOST_DEVICE ArrayExtentsPreviousRank removeFirstExtent() const
176 {
177 auto x = BaseClass::_removeFirstExtent();
178 return ArrayExtentsPreviousRank::fromSpan(x);
179 }
180
181 // Nombre d'éléments de la \a I-éme dimension convertie en un 'Int64'.
182 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int64 constLargeExtent() const
183 {
184 return BaseClass::template constExtent<I>();
185 }
186
187 /*!
188 * \brief Construit une instance à partir des valeurs données dans \a extents.
189 */
191 {
192 return ArrayExtentsBase<Extents>(extents);
193 }
194};
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198/*!
199 * \brief Extent pour les tableaux à 1 dimension.
200 */
201template <typename SizeType_, int X0>
202class ArrayExtents<ExtentsV<SizeType_, X0>>
203: public ArrayExtentsBase<ExtentsV<SizeType_, X0>>
204{
205 public:
206
207 using ExtentsType = ExtentsV<SizeType_, X0>;
209 using BaseClass::totalNbElement;
210 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
211
212 public:
213
214 ArrayExtents() = default;
215 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const BaseClass& rhs)
216 : BaseClass(rhs)
217 {}
218 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const DynamicDimsType& extents)
219 : BaseClass(extents)
220 {
221 }
222 // TODO: A supprimer
223 constexpr ARCCORE_HOST_DEVICE explicit ArrayExtents(Int32 dim1_size)
224 {
225 static_assert(ExtentsType::nb_dynamic == 1, "This method is only allowed for full dynamic extents");
226 this->m_extent0.v = dim1_size;
227 }
228};
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232/*!
233 * \brief Extent pour les tableaux à 2 dimensions.
234 */
235template <typename SizeType_, int X0, int X1>
236class ArrayExtents<ExtentsV<SizeType_, X0, X1>>
237: public ArrayExtentsBase<ExtentsV<SizeType_, X0, X1>>
238{
239 public:
240
241 using ExtentsType = ExtentsV<SizeType_, X0, X1>;
243 using BaseClass::totalNbElement;
244 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
245
246 public:
247
248 ArrayExtents() = default;
249 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const BaseClass& rhs)
250 : BaseClass(rhs)
251 {}
252 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const DynamicDimsType& extents)
253 : BaseClass(extents)
254 {
255 }
256 // TODO: A supprimer
257 constexpr ARCCORE_HOST_DEVICE ArrayExtents(Int32 dim1_size, Int32 dim2_size)
258 {
259 static_assert(ExtentsType::nb_dynamic == 2, "This method is only allowed for full dynamic extents");
260 this->m_extent0.v = dim1_size;
261 this->m_extent1.v = dim2_size;
262 }
263};
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267/*!
268 * \brief Extent pour les tableaux à 3 dimensions.
269 */
270template <typename SizeType_, int X0, int X1, int X2>
271class ArrayExtents<ExtentsV<SizeType_, X0, X1, X2>>
272: public ArrayExtentsBase<ExtentsV<SizeType_, X0, X1, X2>>
273{
274 public:
275
276 using ExtentsType = ExtentsV<SizeType_, X0, X1, X2>;
278 using BaseClass::totalNbElement;
279 using DynamicDimsType = typename BaseClass::DynamicDimsType;
280
281 public:
282
283 ArrayExtents() = default;
284 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const BaseClass& rhs)
285 : BaseClass(rhs)
286 {}
287 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const DynamicDimsType& extents)
288 : BaseClass(extents)
289 {
290 }
291 // TODO: A supprimer
292 constexpr ARCCORE_HOST_DEVICE ArrayExtents(Int32 dim1_size, Int32 dim2_size, Int32 dim3_size)
293 {
294 static_assert(ExtentsType::nb_dynamic == 3, "This method is only allowed for full dynamic extents");
295 this->m_extent0.v = dim1_size;
296 this->m_extent1.v = dim2_size;
297 this->m_extent2.v = dim3_size;
298 }
299};
300
301/*---------------------------------------------------------------------------*/
302/*---------------------------------------------------------------------------*/
303/*!
304 * \brief Extent pour les tableaux à 4 dimensions.
305 */
306template <typename SizeType_, int X0, int X1, int X2, int X3>
307class ArrayExtents<ExtentsV<SizeType_, X0, X1, X2, X3>>
308: public ArrayExtentsBase<ExtentsV<SizeType_, X0, X1, X2, X3>>
309{
310 public:
311
312 using ExtentsType = ExtentsV<SizeType_, X0, X1, X2, X3>;
314 using BaseClass::totalNbElement;
315 using DynamicDimsType = typename BaseClass::DynamicDimsType;
316
317 public:
318
319 ArrayExtents() = default;
320 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const BaseClass& rhs)
321 : BaseClass(rhs)
322 {}
323 constexpr ARCCORE_HOST_DEVICE ArrayExtents(const DynamicDimsType& extents)
324 : BaseClass(extents)
325 {
326 }
327 // TODO: A supprimer
328 constexpr ARCCORE_HOST_DEVICE ArrayExtents(Int32 dim1_size, Int32 dim2_size, Int32 dim3_size, Int32 dim4_size)
329 {
330 static_assert(ExtentsType::nb_dynamic == 4, "This method is only allowed for full dynamic extents");
331 this->m_extent0.v = dim1_size;
332 this->m_extent1.v = dim2_size;
333 this->m_extent2.v = dim3_size;
334 this->m_extent3.v = dim4_size;
335 }
336};
337
338/*---------------------------------------------------------------------------*/
339/*---------------------------------------------------------------------------*/
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343/*!
344 * \brief Extent et Offset pour les tableaux à 1 dimension.
345 */
346template <typename SizeType_, int X0, typename LayoutType>
347class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0>, LayoutType>
348: private ArrayExtents<ExtentsV<SizeType_, X0>>
349{
350 public:
351
352 using ExtentsType = ExtentsV<SizeType_, X0>;
354 using BaseClass::asStdArray;
355 using BaseClass::extent0;
356 using BaseClass::getIndices;
357 using BaseClass::totalNbElement;
358 using Layout = typename LayoutType::Layout1Type;
359 using DynamicDimsType = typename BaseClass::DynamicDimsType;
360 using MDIndexType = typename BaseClass::MDIndexType;
361
362 // TODO: Rendre obsolète mi-2024
363 using IndexType = typename BaseClass::IndexType;
364
365 public:
366
367 ArrayExtentsWithOffset() = default;
368 // TODO: a supprimer
369 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const ArrayExtents<ExtentsType>& rhs)
370 : BaseClass(rhs)
371 {
372 }
373 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
374 : BaseClass(rhs)
375 {
376 }
377 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i) const
378 {
379 BaseClass::_checkIndex(i);
380 return i;
381 }
382 constexpr ARCCORE_HOST_DEVICE Int64 offset(IndexType idx) const
383 {
384 BaseClass::_checkIndex(idx.id0());
385 return idx.id0();
386 }
387 constexpr BaseClass extents() const
388 {
389 const BaseClass* b = this;
390 return *b;
391 }
392};
393
394/*---------------------------------------------------------------------------*/
395/*---------------------------------------------------------------------------*/
396/*!
397 * \brief Extent et Offset pour les tableaux à 2 dimensions.
398 */
399template <typename SizeType_, int X0, int X1, typename LayoutType>
400class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0, X1>, LayoutType>
401: private ArrayExtents<ExtentsV<SizeType_, X0, X1>>
402{
403 public:
404
405 using ExtentsType = ExtentsV<SizeType_, X0, X1>;
407 using BaseClass::asStdArray;
408 using BaseClass::extent0;
409 using BaseClass::extent1;
410 using BaseClass::getIndices;
411 using BaseClass::totalNbElement;
412 using Layout = typename LayoutType::Layout2Type;
413 using DynamicDimsType = typename BaseClass::DynamicDimsType;
414 using MDIndexType = typename BaseClass::MDIndexType;
415
416 // TODO: Rendre obsolète mi-2024
417 using IndexType = typename BaseClass::IndexType;
418
419 public:
420
421 ArrayExtentsWithOffset() = default;
422 // TODO: a supprimer
423 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(ArrayExtents<ExtentsType> rhs)
424 : BaseClass(rhs)
425 {
426 }
427 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
428 : BaseClass(rhs)
429 {
430 }
431 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i, Int32 j) const
432 {
433 return offset({ i, j });
434 }
435 constexpr ARCCORE_HOST_DEVICE Int64 offset(IndexType idx) const
436 {
437 BaseClass::_checkIndex(idx);
438 return Layout::offset(idx, this->template constExtent<Layout::LastExtent>());
439 }
440 constexpr BaseClass extents() const
441 {
442 const BaseClass* b = this;
443 return *b;
444 }
445};
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
449/*!
450 * \brief Extent et Offset pour les tableaux à 3 dimensions.
451 */
452template <typename SizeType_, int X0, int X1, int X2, typename LayoutType>
453class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0, X1, X2>, LayoutType>
454: private ArrayExtents<ExtentsV<SizeType_, X0, X1, X2>>
455{
456 public:
457
458 using ExtentsType = ExtentsV<SizeType_, X0, X1, X2>;
460 using BaseClass::asStdArray;
461 using BaseClass::extent0;
462 using BaseClass::extent1;
463 using BaseClass::extent2;
464 using BaseClass::getIndices;
465 using BaseClass::totalNbElement;
466 using Layout = typename LayoutType::Layout3Type;
467 using DynamicDimsType = typename BaseClass::DynamicDimsType;
468 using MDIndexType = typename BaseClass::MDIndexType;
469
470 // TODO: Rendre obsolète mi-2024
471 using IndexType = typename BaseClass::IndexType;
472
473 public:
474
475 ArrayExtentsWithOffset() = default;
476 // TODO: a supprimer
477 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(ArrayExtents<ExtentsType> rhs)
478 : BaseClass(rhs)
479 {
480 _computeOffsets();
481 }
482 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
483 : BaseClass(rhs)
484 {
485 _computeOffsets();
486 }
487 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i, Int32 j, Int32 k) const
488 {
489 return offset({ i, j, k });
490 }
491 constexpr ARCCORE_HOST_DEVICE Int64 offset(IndexType idx) const
492 {
493 this->_checkIndex(idx);
494 return Layout::offset(idx, this->template constExtent<Layout::LastExtent>(), m_dim23_size);
495 }
496 constexpr BaseClass extents() const
497 {
498 const BaseClass* b = this;
499 return *b;
500 }
501
502 protected:
503
504 ARCCORE_HOST_DEVICE void _computeOffsets()
505 {
506 const BaseClass& b = *this;
507 m_dim23_size = Layout::computeOffsetIndexes(b);
508 }
509
510 private:
511
512 Int64 m_dim23_size = 0;
513};
514
515/*---------------------------------------------------------------------------*/
516/*---------------------------------------------------------------------------*/
517/*!
518 * \brief Extent et Offset pour les tableaux à 4 dimensions.
519 */
520template <typename SizeType_, int X0, int X1, int X2, int X3, typename LayoutType>
521class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0, X1, X2, X3>, LayoutType>
522: private ArrayExtents<ExtentsV<SizeType_, X0, X1, X2, X3>>
523{
524 public:
525
526 using ExtentsType = ExtentsV<SizeType_, X0, X1, X2, X3>;
528 using BaseClass::asStdArray;
529 using BaseClass::extent0;
530 using BaseClass::extent1;
531 using BaseClass::extent2;
532 using BaseClass::extent3;
533 using BaseClass::getIndices;
534 using BaseClass::totalNbElement;
535 using Layout = typename LayoutType::Layout4Type;
536 using DynamicDimsType = typename BaseClass::DynamicDimsType;
537 using MDIndexType = typename BaseClass::MDIndexType;
538
539 // TODO: Rendre obsolète mi-2024
540 using IndexType = typename BaseClass::IndexType;
541
542 public:
543
544 ArrayExtentsWithOffset() = default;
545 // TODO: a supprimer
546 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(ArrayExtents<ExtentsType> rhs)
547 : BaseClass(rhs)
548 {
549 _computeOffsets();
550 }
551 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
552 : BaseClass(rhs)
553 {
554 _computeOffsets();
555 }
556 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i, Int32 j, Int32 k, Int32 l) const
557 {
558 return offset({ i, j, k, l });
559 }
560 constexpr ARCCORE_HOST_DEVICE Int64 offset(IndexType idx) const
561 {
562 this->_checkIndex(idx);
563 return (m_dim234_size * idx.largeId0()) + m_dim34_size * idx.largeId1() + this->m_extent3.v * idx.largeId2() + idx.largeId3();
564 }
565 BaseClass extents() const
566 {
567 const BaseClass* b = this;
568 return *b;
569 }
570
571 protected:
572
573 ARCCORE_HOST_DEVICE void _computeOffsets()
574 {
575 m_dim34_size = Int64(this->m_extent2.v) * Int64(this->m_extent3.v);
576 m_dim234_size = Int64(m_dim34_size) * Int64(this->m_extent1.v);
577 }
578
579 private:
580
581 Int64 m_dim34_size = 0; //!< dim3 * dim4
582 Int64 m_dim234_size = 0; //!< dim2 * dim3 * dim4
583};
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
588} // namespace Arcane
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
592
593#endif
constexpr __host__ __device__ SmallSpan< const Int32 > asSpan() const
Nombre d'élément de la i-ème dimension.
constexpr __host__ __device__ Int32 totalNbElement() const
Nombre total d'eléments.
Classe pour conserver le nombre d'éléments dans chaque dimension.
__host__ __device__ void setExtent0(Int32 v)
TEMPORARY: Positionne à v le nombre d'éléments de la dimension 0.
__host__ static __device__ ArrayExtentsBase< Extents > fromSpan(SmallSpan< const Int32 > extents)
Construit une instance à partir des valeurs données dans extents.
__host__ __device__ SmallSpan< const Int32 > asSpan() const
Valeur du pas de la i-ème dimension.
__host__ __device__ Int64 totalStride() const
Value totale du pas.
Classe pour conserver le pas dans chaque dimension.
__host__ static __device__ ArrayStridesBase< RankValue > fromSpan(Span< const Int32 > strides)
Construit une instance à partir des valeurs données dans stride.
__host__ __device__ Int64 totalStride() const
Valeur totale du pas.
__host__ __device__ Int32 stride(int i) const
Valeur du pas de la i-ème dimension.
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 -*-