Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
SimdItem.h
Aller à la documentation de ce fichier.
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/* SimdItem.h (C) 2000-2024 */
9/* */
10/* Types des entités et des énumérateurs des entités pour la vectorisation. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_SIMDITEM_H
13#define ARCANE_SIMDITEM_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Simd.h"
18
19// La macro ARCANE_SIMD_BENCH n'est définie que pour le bench
20// Simd (dans contribs/Simd) et permet d'éviter d'inclure la gestion des
21// entités.
22
23#ifndef ARCANE_SIMD_BENCH
24#include "arcane/ItemEnumerator.h"
25#endif
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29/*!
30 * \file SimdItem.h
31 *
32 * Ce fichier contient les déclarations des types pour gérer
33 * la vectorisation avec les entités (Item) du maillage.
34 */
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane
39{
40
41template<typename ItemType>
42class SimdItemEnumeratorT;
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46/*!
47 * TODO:
48 * - Faire une version de SimdItem par taille de vecteur (2,4,8).
49 * - Utiliser un mask si possible.
50 * - aligned SimdItemBase
51 * - faire une version du constructeur de SimdItemBase sans (nb_valid)
52 * pour le cas ou le vecteur est complet.
53 */
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56/*!
57 * \ingroup ArcaneSimd
58 * \brief Classe gérant un vecteur SIMD d'entité.
59 *
60 * Cette classe conserve \a N entités du maillage, \a N étant dépendant
61 * de la taille des registres SIMD et est vaut SimdInfo::Int32IndexSize.
62 *
63 * Cette classe ne s'utilise pas directement. Il faut utiliser SimdItem ou
64 * SimdItemT
65 */
66class ARCANE_CORE_EXPORT SimdItemBase
67{
68 protected:
69
71
72 public:
73
75
76 public:
77
78 /*!
79 * \brief Construit une instance.
80 * \warning \a ids doit avoir l'alignement requis pour un SimdIndexType.
81 */
82 ARCANE_DEPRECATED_REASON("Y2022: Use another constructor")
83 SimdItemBase(const ItemInternalPtr* items, const SimdIndexType* ids)
84 : m_simd_local_ids(*ids), m_shared_info(ItemInternalCompatibility::_getSharedInfo(items,1)) { }
85
86 protected:
87
88 SimdItemBase(ItemSharedInfo* shared_info,const SimdIndexType* ids)
89 : m_simd_local_ids(*ids), m_shared_info(shared_info) { }
90
91 public:
92
93 //! Partie interne (pour usage interne uniquement)
94 ARCANE_DEPRECATED_REASON("Y2022: Use method SimdItem::item() instead")
95 ItemInternal* item(Integer si) const { return m_shared_info->m_items_internal[localId(si)]; }
96
97 ARCANE_DEPRECATED_REASON("Y2022: Use method SimdItem::operator[]() instead")
98 ItemInternal* operator[](Integer si) const { return m_shared_info->m_items_internal[localId(si)]; }
99
100 //! Liste des numéros locaux des entités de l'instance
101 const SimdIndexType& ARCANE_RESTRICT simdLocalIds() const { return m_simd_local_ids; }
102
103 //! Liste des numéros locaux des entités de l'instance
104 const Int32* ARCANE_RESTRICT localIds() const { return (const Int32*)&m_simd_local_ids; }
105
106 //! Numéro local de l'entité d'indice \a index.
107 Int32 localId(Int32 index) const { return m_simd_local_ids[index]; }
108
109 protected:
110
111 SimdIndexType m_simd_local_ids;
112 ItemSharedInfo* m_shared_info = ItemSharedInfo::nullInstance();
113};
114
115/*---------------------------------------------------------------------------*/
116/*---------------------------------------------------------------------------*/
117
119{
120 protected:
121
123
124 public:
125
126 ARCANE_DEPRECATED_REASON("Y2022: Use another constructor")
127 SimdItemDirectBase(const ItemInternalPtr* items,Int32 base_local_id,Integer nb_valid)
128 : m_base_local_id(base_local_id), m_nb_valid(nb_valid),
129 m_shared_info(ItemInternalCompatibility::_getSharedInfo(items,nb_valid)) { }
130
131 protected:
132
133 SimdItemDirectBase(ItemSharedInfo* shared_info,Int32 base_local_id,Integer nb_valid)
134 : m_base_local_id(base_local_id), m_nb_valid(nb_valid), m_shared_info(shared_info) {}
135
136 // TEMPORAIRE pour éviter le deprecated
137 SimdItemDirectBase(Int32 base_local_id,Integer nb_valid,const ItemInternalPtr* items)
138 : m_base_local_id(base_local_id), m_nb_valid(nb_valid),
139 m_shared_info(ItemInternalCompatibility::_getSharedInfo(items,nb_valid)) { }
140
141 public:
142
143 //! Nombre d'entités valides de l'instance.
144 inline Integer nbValid() const { return m_nb_valid; }
145
146 //! Liste des numéros locaux des entités de l'instance
147 inline Int32 baseLocalId() const { return m_base_local_id; }
148
149 protected:
150
151 Int32 m_base_local_id;
152 Integer m_nb_valid;
153 ItemSharedInfo* m_shared_info = ItemSharedInfo::nullInstance();
154};
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158/*!
159 * \brief Index vectoriel avec indirection pour un type d'entité.
160 * TODO: stocker les index dans un registre vectoriel pour pouvoir
161 * faire le gather rapidement. Pour cela, faire l'equivalent de AVXSimdReal
162 * pour les Int32.
163 */
164template<typename ItemType>
166{
167 public:
169 public:
170 SimdItemIndexT(const SimdIndexType& ARCANE_RESTRICT local_ids)
171 : m_local_ids(local_ids){}
172 SimdItemIndexT(const SimdIndexType* ARCANE_RESTRICT local_ids)
173 : m_local_ids(*local_ids){}
174 public:
175 //! Liste des numéros locaux des entités de l'instance
176 const SimdIndexType& ARCANE_RESTRICT simdLocalIds() const { return m_local_ids; }
177 private:
178 const SimdIndexType& ARCANE_RESTRICT m_local_ids;
179};
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183/*!
184 * \brief Index vectoriel sans indirection pour un type d'entité
185 */
186template<typename ItemType>
188{
189 public:
190 SimdItemDirectIndexT(Int32 base_local_id)
191 : m_base_local_id(base_local_id){}
192 public:
193 inline Int32 baseLocalId() const { return m_base_local_id; }
194 private:
195 Int32 m_base_local_id;
196};
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200/*!
201 * \ingroup ArcaneSimd
202 * \brief Gère un vecteur d'entité \a Item.
203 */
205: public SimdItemBase
206{
207 public:
208
209 ARCANE_DEPRECATED_REASON("Y2022: Use another constructor")
211 : SimdItemBase(ItemInternalCompatibility::_getSharedInfo(items,1),ids) { }
212
213 protected:
214
216 : SimdItemBase(shared_info,ids) { }
217
218 public:
219
220 //! inline \a si-ième entité de l'instance
221 inline Item item(Int32 si) const { return Item(localId(si),m_shared_info); }
222
223 //! inline \a si-ième entité de l'instance
224 inline Item operator[](Int32 si) const { return Item(localId(si),m_shared_info); }
225};
226
227/*---------------------------------------------------------------------------*/
228/*---------------------------------------------------------------------------*/
229/*!
230 * \ingroup ArcaneSimd
231 * \brief Gère un vecteur d'entité \a ItemType.
232 */
233template<typename ItemType>
235: public SimdItem
236{
237 friend class SimdItemEnumeratorT<ItemType>;
238
239 protected:
240
242
243 public:
244
245#if 0
246 ARCANE_DEPRECATED_REASON("Y2022: Use another constructor")
248 : SimdItem(items,ids) { }
249#endif
250
251 private:
252
254 : SimdItem(shared_info,ids) { }
255
256 public:
257
258 //! Retourne la \a si-ième entité de l'instance
259 ItemType item(Integer si) const
260 {
261 return ItemType(localId(si),m_shared_info);
262 }
263
264 //! Retourne la \a si-ième entité de l'instance
265 ItemType operator[](Integer si) const
266 {
267 return ItemType(localId(si),m_shared_info);
268 }
269
270 operator SimdItemIndexT<ItemType>()
271 {
273 }
274};
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278/*!
279 * \ingroup ArcaneSimd
280 * \brief Gère un vecteur d'entité \a ItemType.
281 */
282template<typename ItemType>
284: public SimdItemDirectBase
285{
286 friend class SimdItemEnumeratorT<ItemType>;
287
288 protected:
289
291
292 public:
293
294 ARCANE_DEPRECATED_REASON("Y2022: Use another constructor")
295 SimdItemDirectT(const ItemInternalPtr* items,Int32 base_local_id,Integer nb_valid)
296 : SimdItemDirectBase(base_local_id,nb_valid,items) {}
297
298 private:
299
300 SimdItemDirectT(ItemSharedInfo* shared_info,Int32 base_local_id,Integer nb_valid)
301 : SimdItemDirectBase(shared_info,base_local_id,nb_valid) {}
302
303 public:
304
306 {
307 return SimdItemDirectIndexT<ItemType>(this->m_base_local_id);
308 }
309};
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313/*!
314 * \internal
315 * \ingroup ArcaneSimd
316 * \brief Objet permettant de positionner les valeurs d'un vecteur SIMD.
317 */
318template<typename DataType>
320{
321 typedef typename SimdTypeTraits<DataType>::SimdType SimdType;
322 public:
323 SimdSetter(DataType* ARCANE_RESTRICT _data,
324 const SimdInfo::SimdInt32IndexType& ARCANE_RESTRICT _indexes)
325 : idx(_indexes), m_data(_data)
326 {
327 }
328 public:
329 void operator=(const SimdType& vr)
330 {
331 vr.set(m_data,idx);
332 }
333 void operator=(const DataType& v)
334 {
335 SimdType vr(v);
336 vr.set(m_data,idx);
337 }
338 private:
339 const SimdInfo::SimdInt32IndexType& ARCANE_RESTRICT idx;
340 DataType* ARCANE_RESTRICT m_data;
341};
342
343/*---------------------------------------------------------------------------*/
344/*---------------------------------------------------------------------------*/
345/*!
346 * \ingroup ArcaneSimd
347 * \brief Objet permettant de positionner les valeurs d'un vecteur SIMD.
348 */
349template<typename DataType>
351{
352 typedef typename SimdTypeTraits<DataType>::SimdType SimdType;
353 public:
354 SimdDirectSetter(DataType* ARCANE_RESTRICT _data)
355 : m_data(_data) { }
356 public:
357 void operator=(const SimdType& vr)
358 {
359 vr.set(m_data);
360 }
361 private:
362 DataType* ARCANE_RESTRICT m_data;
363};
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368/*---------------------------------------------------------------------------*/
369/*---------------------------------------------------------------------------*/
370/*!
371 * \ingroup ArcaneSimd
372 * \brief Classe de base des énumérateurs sur les entités vectortielles (SimdItem).
373 */
374class ARCANE_CORE_EXPORT SimdItemEnumeratorBase
375: public SimdEnumeratorBase
376{
377 protected:
378
380
381 public:
382
384
385 public:
386
387 // TODO: Gérer les m_local_id_offset pour cette classe
388
389 // TODO: Fin 2024, rendre certains constructeurs internes à Arcane et rendre
390 // obsolètes les autres.
391 // Faire de même avec les classes dérivées
392
393 SimdItemEnumeratorBase() = default;
394
395 // TODO: Rendre interne à Arcane
397 : SimdEnumeratorBase(view.localIds()), m_shared_info(view.m_shared_info) {}
398 // TODO: Rendre interne à Arcane
400 : SimdEnumeratorBase(rhs.m_view.m_local_ids,rhs.count()), m_shared_info(rhs.m_item.m_shared_info) {}
401
402 // TODO: rendre obsolète
403 SimdItemEnumeratorBase(const ItemInternalPtr* items,const Int32* local_ids,Integer n)
404 : SimdEnumeratorBase(local_ids,n), m_shared_info(ItemInternalCompatibility::_getSharedInfo(items,n)) { }
405 // TODO: rendre obsolète
407 : SimdEnumeratorBase(local_ids), m_shared_info(ItemInternalCompatibility::_getSharedInfo(items.data(),local_ids.size())) { }
408
409 public:
410
411 // TODO: rendre obsolète
412 //! Liste des entités
413 const ItemInternalPtr* unguardedItems() const { return m_shared_info->m_items_internal.data(); }
414
415 protected:
416
417 ItemSharedInfo* m_shared_info = ItemSharedInfo::nullInstance();
418};
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422/*!
423 * \ingroup ArcaneSimd
424 * \brief Enumérateur sur une liste d'entités.
425 */
426template<typename ItemType>
429{
430 protected:
431
433
434 public:
435
436 typedef SimdItemT<ItemType> SimdItemType;
437
445 : SimdItemEnumeratorBase(rhs) {}
446
447 // TODO: rendre obsolète
448 SimdItemEnumeratorT(const ItemInternalPtr* items,const Int32* local_ids,Integer n)
449 : SimdItemEnumeratorBase(items,local_ids,n){}
450 // TODO: rendre obsolète
452 : SimdItemEnumeratorBase(items,local_ids) {}
453
454 public:
455
456 SimdItemType operator*() const
457 {
458 return SimdItemType(m_shared_info,_currentSimdIndex());
459 }
460
461 SimdItemDirectT<ItemType> direct() const
462 {
463 return SimdItemDirectT<ItemType>(m_shared_info,m_index,nbValid());
464 }
465
466 operator SimdItemIndexT<ItemType>()
467 {
468 return SimdItemIndexT<ItemType>(_currentSimdIndex());
469 }
470
471#ifndef ARCANE_SIMD_BENCH
472 inline ItemEnumeratorT<ItemType> enumerator() const
473 {
474 return ItemEnumeratorT<ItemType>(m_shared_info,Int32ConstArrayView(nbValid(),m_local_ids+m_index));
475 }
476#endif
477
478 protected:
479};
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
484#ifndef ARCANE_SIMD_BENCH
485/*!
486 * \ingroup ArcaneSimd
487 * \brief Vecteur SIMD de \a Node.
488 */
490/*!
491 * \ingroup ArcaneSimd
492 * \brief Vecteur SIMD de \a Edge.
493 */
495/*!
496 * \ingroup ArcaneSimd
497 * \brief Vecteur SIMD de \a Face.
498 */
500/*!
501 * \ingroup ArcaneSimd
502 * \brief Vecteur SIMD de \a Cell.
503 */
505/*!
506 * \ingroup ArcaneSimd
507 * \brief Vecteur SIMD de \a Particle.
508 */
510#else
511/*!
512 * \ingroup ArcaneSimd
513 * \brief Vecteur SIMD de \a Cell.
514 */
516#endif
517
518/*---------------------------------------------------------------------------*/
519/*---------------------------------------------------------------------------*/
520
521template <typename ItemType>
523{
524 public:
525
526 static SimdItemEnumeratorT<ItemType> getSimdEnumerator(const ItemGroupT<ItemType>& g)
527 {
528 return g._simdEnumerator();
529 }
530 // Créé un itérateur à partir d'un ItemVectorView. Il faut que ce dernier ait un padding
531 // de la taille du vecteur.
532 static SimdItemEnumeratorT<ItemType> getSimdEnumerator(const ItemVectorViewT<ItemType>& g)
533 {
534 return g.enumerator();
535 }
536
537 // Pour compatibilité avec l'existant
538 // Si on est ici cela signifie que le type 'T' n'est pas un type Arcane.
539 // Il faudrait à terme interdire cet appel (par exemple fin 2025)
540 template <typename T>
541 static SimdItemEnumeratorT<ItemType> getSimdEnumerator(const T& g)
542 {
543 return g.enumerator();
544 }
545};
546
547/*---------------------------------------------------------------------------*/
548/*---------------------------------------------------------------------------*/
549
550#define ENUMERATE_SIMD_(type, iname, view) \
551 for (A_TRACE_ITEM_ENUMERATOR(SimdItemEnumeratorT<type>) iname(::Arcane::SimdItemEnumeratorContainerTraits<type>::getSimdEnumerator(view) A_TRACE_ENUMERATOR_WHERE); iname.hasNext(); ++iname)
552
553// TODO: A supprimer. Utiliser ENUMERATE_SIMD_ à la place
554#define ENUMERATE_SIMD_GENERIC(type, iname, view) \
555 ENUMERATE_SIMD_(type,iname,view)
556
557/*!
558 * \ingroup ArcaneSimd
559 * \brief Enumérateur SIMD sur un groupe ou liste de noeuds.
560 */
561#define ENUMERATE_SIMD_NODE(name, group) ENUMERATE_SIMD_(::Arcane::Node, name, group)
562
563/*!
564 * \ingroup ArcaneSimd
565 * \brief Enumérateur SIMD sur un groupe ou liste d'arêtes.
566 */
567#define ENUMERATE_SIMD_EDGE(name, group) ENUMERATE_SIMD_(::Arcane::Edge, name, group)
568
569/*!
570 * \ingroup ArcaneSimd
571 * \brief Enumérateur SIMD sur un groupe ou liste de faces.
572 */
573#define ENUMERATE_SIMD_FACE(name, group) ENUMERATE_SIMD_(::Arcane::Face, name, group)
574
575/*!
576 * \ingroup ArcaneSimd
577 * \brief Enumérateur SIMD sur un groupe ou liste de mailles.
578 */
579#define ENUMERATE_SIMD_CELL(name, group) ENUMERATE_SIMD_(::Arcane::Cell, name, group)
580
581/*!
582 * \ingroup ArcaneSimd
583 * \brief Enumérateur SIMD sur un groupe ou liste de particles.
584 */
585#define ENUMERATE_SIMD_PARTICLE(name, group) ENUMERATE_SIMD_(::Arcane::Particle, name, group)
586
587/*---------------------------------------------------------------------------*/
588/*---------------------------------------------------------------------------*/
589
590} // End namespace Arcane
591
592/*---------------------------------------------------------------------------*/
593/*---------------------------------------------------------------------------*/
594
595#endif
Vectorisation des entiers en utilisant une émulation.
Definition SimdEMUL.h:35
constexpr Integer count() const
Nombre d'éléments de l'énumérateur.
Enumérateur sur une liste typée d'entités de type ItemType.
Enumérateur sur une liste d'entités.
Référence à un groupe d'un genre donné.
Definition ItemGroup.h:398
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
Vue sur un tableau typé d'entités.
Classe de base d'un élément de maillage.
Definition Item.h:83
Objet permettant de positionner les valeurs d'un vecteur SIMD.
Definition SimdItem.h:351
Classe de base des énumérateurs vectoriels avec indirection.
Definition Simd.h:380
Integer nbValid() const
Nombre de valeurs valides pour l'itérateur courant.
Definition Simd.h:409
Classe gérant un vecteur SIMD d'entité.
Definition SimdItem.h:67
const Int32 *ARCANE_RESTRICT localIds() const
Liste des numéros locaux des entités de l'instance.
Definition SimdItem.h:104
const SimdIndexType &ARCANE_RESTRICT simdLocalIds() const
Liste des numéros locaux des entités de l'instance.
Definition SimdItem.h:101
Int32 localId(Int32 index) const
Numéro local de l'entité d'indice index.
Definition SimdItem.h:107
Int32 baseLocalId() const
Liste des numéros locaux des entités de l'instance.
Definition SimdItem.h:147
Integer nbValid() const
Nombre d'entités valides de l'instance.
Definition SimdItem.h:144
Index vectoriel sans indirection pour un type d'entité
Definition SimdItem.h:188
Gère un vecteur d'entité ItemType.
Definition SimdItem.h:285
Classe de base des énumérateurs sur les entités vectortielles (SimdItem).
Definition SimdItem.h:376
const ItemInternalPtr * unguardedItems() const
Liste des entités.
Definition SimdItem.h:413
Enumérateur sur une liste d'entités.
Definition SimdItem.h:429
Index vectoriel avec indirection pour un type d'entité. TODO: stocker les index dans un registre vect...
Definition SimdItem.h:166
const SimdIndexType &ARCANE_RESTRICT simdLocalIds() const
Liste des numéros locaux des entités de l'instance.
Definition SimdItem.h:176
Gère un vecteur d'entité ItemType.
Definition SimdItem.h:236
ItemType operator[](Integer si) const
Retourne la si-ième entité de l'instance.
Definition SimdItem.h:265
ItemType item(Integer si) const
Retourne la si-ième entité de l'instance.
Definition SimdItem.h:259
Gère un vecteur d'entité Item.
Definition SimdItem.h:206
Item item(Int32 si) const
inline si-ième entité de l'instance
Definition SimdItem.h:221
Item operator[](Int32 si) const
inline si-ième entité de l'instance
Definition SimdItem.h:224
Vue constante d'un tableau de type T.
SimdItemT< Edge > SimdEdge
Vecteur SIMD de Edge.
Definition SimdItem.h:494
SimdItemT< Cell > SimdCell
Vecteur SIMD de Cell.
Definition SimdItem.h:504
SimdItemT< Face > SimdFace
Vecteur SIMD de Face.
Definition SimdItem.h:499
SimdItemT< Particle > SimdParticle
Vecteur SIMD de Particle.
Definition SimdItem.h:509
SimdItemT< Node > SimdNode
Vecteur SIMD de Node.
Definition SimdItem.h:489
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640