Arcane  v3.16.9.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArrayExtents.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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-2025 */
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/*---------------------------------------------------------------------------*/
35template <>
36class ArrayStridesBase<0>
37{
38 public:
39
40 ArrayStridesBase() = default;
42 ARCCORE_HOST_DEVICE SmallSpan<const Int32> asSpan() const { return {}; }
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/*---------------------------------------------------------------------------*/
62template <int RankValue>
63class ArrayStridesBase
64{
65 public:
66
67 ArrayStridesBase() = default;
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 }; }
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 }
89 ARCCORE_HOST_DEVICE static ArrayStridesBase<RankValue> fromSpan(Span<const Int32> strides)
90 {
91 ArrayStridesBase<RankValue> v;
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/*---------------------------------------------------------------------------*/
111template <>
112class ArrayExtentsBase<ExtentsV<>>
113{
114 public:
115
116 ArrayExtentsBase() = default;
118 constexpr ARCCORE_HOST_DEVICE SmallSpan<const Int32> asSpan() const { return {}; }
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/*---------------------------------------------------------------------------*/
133template <typename Extents>
134class ArrayExtentsBase
135: protected Extents::ArrayExtentsValueType
136{
137 protected:
138
139 using BaseClass = typename Extents::ArrayExtentsValueType;
140 using ArrayExtentsPreviousRank = ArrayExtentsBase<typename Extents::RemovedFirstExtentsType>;
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
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();
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
190 ARCCORE_HOST_DEVICE static ArrayExtentsBase<Extents> fromSpan(SmallSpan<const Int32> extents)
191 {
192 return ArrayExtentsBase<Extents>(extents);
193 }
194};
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
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>;
208 using BaseClass = ArrayExtentsBase<ExtentsType>;
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/*---------------------------------------------------------------------------*/
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>;
242 using BaseClass = ArrayExtentsBase<ExtentsType>;
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/*---------------------------------------------------------------------------*/
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>;
277 using BaseClass = ArrayExtentsBase<ExtentsType>;
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/*---------------------------------------------------------------------------*/
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>;
313 using BaseClass = ArrayExtentsBase<ExtentsType>;
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/*---------------------------------------------------------------------------*/
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>;
353 using BaseClass = ArrayExtents<ExtentsType>;
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 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = typename BaseClass::MDIndexType;
363
364 public:
365
366 ArrayExtentsWithOffset() = default;
367 // TODO: a supprimer
368 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const ArrayExtents<ExtentsType>& rhs)
369 : BaseClass(rhs)
370 {
371 }
372 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
373 : BaseClass(rhs)
374 {
375 }
376 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i) const
377 {
378 BaseClass::_checkIndex(i);
379 return i;
380 }
381 constexpr ARCCORE_HOST_DEVICE Int64 offset(MDIndexType idx) const
382 {
383 BaseClass::_checkIndex(idx.id0());
384 return idx.id0();
385 }
386 constexpr BaseClass extents() const
387 {
388 const BaseClass* b = this;
389 return *b;
390 }
391};
392
393/*---------------------------------------------------------------------------*/
394/*---------------------------------------------------------------------------*/
398template <typename SizeType_, int X0, int X1, typename LayoutType>
399class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0, X1>, LayoutType>
400: private ArrayExtents<ExtentsV<SizeType_, X0, X1>>
401{
402 public:
403
404 using ExtentsType = ExtentsV<SizeType_, X0, X1>;
405 using BaseClass = ArrayExtents<ExtentsType>;
406 using BaseClass::asStdArray;
407 using BaseClass::extent0;
408 using BaseClass::extent1;
409 using BaseClass::getIndices;
410 using BaseClass::totalNbElement;
411 using Layout = typename LayoutType::Layout2Type;
412 using DynamicDimsType = typename BaseClass::DynamicDimsType;
413 using MDIndexType = typename BaseClass::MDIndexType;
414
415 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = typename BaseClass::MDIndexType;
416
417 public:
418
419 ArrayExtentsWithOffset() = default;
420 // TODO: a supprimer
421 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(ArrayExtents<ExtentsType> rhs)
422 : BaseClass(rhs)
423 {
424 }
425 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
426 : BaseClass(rhs)
427 {
428 }
429 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i, Int32 j) const
430 {
431 return offset({ i, j });
432 }
433 constexpr ARCCORE_HOST_DEVICE Int64 offset(MDIndexType idx) const
434 {
435 BaseClass::_checkIndex(idx);
436 return Layout::offset(idx, this->template constExtent<Layout::LastExtent>());
437 }
438 constexpr BaseClass extents() const
439 {
440 const BaseClass* b = this;
441 return *b;
442 }
443};
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
450template <typename SizeType_, int X0, int X1, int X2, typename LayoutType>
451class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0, X1, X2>, LayoutType>
452: private ArrayExtents<ExtentsV<SizeType_, X0, X1, X2>>
453{
454 public:
455
456 using ExtentsType = ExtentsV<SizeType_, X0, X1, X2>;
457 using BaseClass = ArrayExtents<ExtentsType>;
458 using BaseClass::asStdArray;
459 using BaseClass::extent0;
460 using BaseClass::extent1;
461 using BaseClass::extent2;
462 using BaseClass::getIndices;
463 using BaseClass::totalNbElement;
464 using Layout = typename LayoutType::Layout3Type;
465 using DynamicDimsType = typename BaseClass::DynamicDimsType;
466 using MDIndexType = typename BaseClass::MDIndexType;
467
468 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = typename BaseClass::MDIndexType;
469
470 public:
471
472 ArrayExtentsWithOffset() = default;
473 // TODO: a supprimer
474 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(ArrayExtents<ExtentsType> rhs)
475 : BaseClass(rhs)
476 {
477 _computeOffsets();
478 }
479 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
480 : BaseClass(rhs)
481 {
482 _computeOffsets();
483 }
484 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i, Int32 j, Int32 k) const
485 {
486 return offset({ i, j, k });
487 }
488 constexpr ARCCORE_HOST_DEVICE Int64 offset(MDIndexType idx) const
489 {
490 this->_checkIndex(idx);
491 return Layout::offset(idx, this->template constExtent<Layout::LastExtent>(), m_dim23_size);
492 }
493 constexpr BaseClass extents() const
494 {
495 const BaseClass* b = this;
496 return *b;
497 }
498
499 protected:
500
501 ARCCORE_HOST_DEVICE void _computeOffsets()
502 {
503 const BaseClass& b = *this;
504 m_dim23_size = Layout::computeOffsetIndexes(b);
505 }
506
507 private:
508
509 Int64 m_dim23_size = 0;
510};
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
517template <typename SizeType_, int X0, int X1, int X2, int X3, typename LayoutType>
518class ArrayExtentsWithOffset<ExtentsV<SizeType_, X0, X1, X2, X3>, LayoutType>
519: private ArrayExtents<ExtentsV<SizeType_, X0, X1, X2, X3>>
520{
521 public:
522
523 using ExtentsType = ExtentsV<SizeType_, X0, X1, X2, X3>;
524 using BaseClass = ArrayExtents<ExtentsType>;
525 using BaseClass::asStdArray;
526 using BaseClass::extent0;
527 using BaseClass::extent1;
528 using BaseClass::extent2;
529 using BaseClass::extent3;
530 using BaseClass::getIndices;
531 using BaseClass::totalNbElement;
532 using Layout = typename LayoutType::Layout4Type;
533 using DynamicDimsType = typename BaseClass::DynamicDimsType;
534 using MDIndexType = typename BaseClass::MDIndexType;
535
536 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = typename BaseClass::MDIndexType;
537
538 public:
539
540 ArrayExtentsWithOffset() = default;
541 // TODO: a supprimer
542 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(ArrayExtents<ExtentsType> rhs)
543 : BaseClass(rhs)
544 {
545 _computeOffsets();
546 }
547 constexpr ARCCORE_HOST_DEVICE ArrayExtentsWithOffset(const DynamicDimsType& rhs)
548 : BaseClass(rhs)
549 {
550 _computeOffsets();
551 }
552 constexpr ARCCORE_HOST_DEVICE Int64 offset(Int32 i, Int32 j, Int32 k, Int32 l) const
553 {
554 return offset({ i, j, k, l });
555 }
556 constexpr ARCCORE_HOST_DEVICE Int64 offset(MDIndexType idx) const
557 {
558 this->_checkIndex(idx);
559 return (m_dim234_size * idx.largeId0()) + m_dim34_size * idx.largeId1() + this->m_extent3.v * idx.largeId2() + idx.largeId3();
560 }
561 BaseClass extents() const
562 {
563 const BaseClass* b = this;
564 return *b;
565 }
566
567 protected:
568
569 ARCCORE_HOST_DEVICE void _computeOffsets()
570 {
571 m_dim34_size = Int64(this->m_extent2.v) * Int64(this->m_extent3.v);
572 m_dim234_size = Int64(m_dim34_size) * Int64(this->m_extent1.v);
573 }
574
575 private:
576
579};
580
581/*---------------------------------------------------------------------------*/
582/*---------------------------------------------------------------------------*/
583
584} // namespace Arcane
585
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
589#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:673
Vue d'un tableau d'éléments de type T.
Definition Span.h:513
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
std::int32_t Int32
Type entier signé sur 32 bits.