Arcane  v4.1.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AllCellToAllEnvCellConverter.cc
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/* AllCellToAllEnvCellConverter.cc (C) 2000-2024 */
9/* */
10/* Conversion de 'Cell' en 'AllEnvCell'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/AllCellToAllEnvCellConverter.h"
15
16#include "arcane/utils/NumArray.h"
17
18#include "arcane/core/IItemFamily.h"
20#include "arcane/core/ItemGroup.h"
21#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
22
23#include "arcane/materials/internal/AllCellToAllEnvCellContainer.h"
24
25#include "arcane/accelerator/Reduce.h"
27#include "arcane/accelerator/NumArrayViews.h"
28
29#include <algorithm>
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::Materials
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41{
42 public:
43
44 explicit Impl(IMeshMaterialMng* mm)
45 : m_material_mng(mm)
46 {
47 m_mem_pool.setDebugName("AllCellToAllEnvCellMemPool");
48 m_envcell_container.setDebugName("AllCellToAllEnvCellCells");
49 }
50
51 public:
52
53 Int32 computeMaxNbEnvPerCell();
54 void initialize();
55 void bruteForceUpdate();
56 void reset();
57 AllCellToAllEnvCell view() const { return m_all_cell_to_all_env_cell; }
58
59 public:
60
61 static void updateValues(IMeshMaterialMng* material_mng,
63 Span<Span<ComponentItemLocalId>> allcell_allenvcell,
64 Int32 max_nb_env);
65
66 private:
67
68 IMeshMaterialMng* m_material_mng = nullptr;
69 Int32 m_size = 0;
70 NumArray<Span<ComponentItemLocalId>, MDDim1> m_envcell_container;
72 Int32 m_current_max_nb_env = 0;
73 AllCellToAllEnvCell m_all_cell_to_all_env_cell;
74};
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79Int32 AllCellToAllEnvCellContainer::Impl::
80computeMaxNbEnvPerCell()
81{
82 IMeshMaterialMng* material_mng = m_material_mng;
83 CellToAllEnvCellConverter allenvcell_converter(material_mng);
84 RunQueue& queue = material_mng->_internalApi()->runQueue();
86 auto local_ids = material_mng->mesh()->allCells().internal()->itemsLocalId();
87 Int32 nb_item = local_ids.size();
88 auto select_func = [=] ARCCORE_HOST_DEVICE(Int32 i) -> Int32 {
89 CellLocalId lid(local_ids[i]);
90 AllEnvCell all_env_cell = allenvcell_converter[lid];
91 return all_env_cell.nbEnvironment();
92 };
93 reducer.applyMaxWithIndex(nb_item, select_func);
94 Int32 max_nb_env = reducer.reducedValue();
95 return max_nb_env;
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101void AllCellToAllEnvCellContainer::Impl::
102updateValues(IMeshMaterialMng* material_mng,
104 Span<Span<ComponentItemLocalId>> allcell_allenvcell,
105 Int32 max_nb_env)
106{
107 // mise a jour des valeurs
108 CellToAllEnvCellConverter all_env_cell_converter(material_mng);
109 RunQueue& queue = material_mng->_internalApi()->runQueue();
110 auto command = makeCommand(queue);
111 command << RUNCOMMAND_ENUMERATE (CellLocalId, cid, material_mng->mesh()->allCells())
112 {
113 AllEnvCell all_env_cell = all_env_cell_converter[cid];
114 Integer offset = cid * max_nb_env;
115 Int32 nb_env = all_env_cell.nbEnvironment();
116 // Initialize à zéro les indices de 'mem_pools' de ma maille.
117 for (Int32 x = 0; x < max_nb_env; ++x)
118 mem_pool[offset + x] = ComponentItemLocalId();
119 if (nb_env != 0) {
120 Integer i = 0;
121 for (EnvCell ev : all_env_cell.subEnvItems()) {
122 mem_pool[offset + i] = ComponentItemLocalId(ev._varIndex());
123 ++i;
124 }
125 allcell_allenvcell[cid] = Span<ComponentItemLocalId>(mem_pool.ptrAt(offset), nb_env);
126 }
127 else {
128 allcell_allenvcell[cid] = {};
129 }
130 };
131}
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
136void AllCellToAllEnvCellContainer::Impl::
137initialize()
138{
139 IMeshMaterialMng* mm = m_material_mng;
140 RunQueue queue = mm->_internalApi()->runQueue();
141 m_size = mm->mesh()->cellFamily()->maxLocalId() + 1;
142
143 m_envcell_container.resize(m_size);
144 m_all_cell_to_all_env_cell.m_allcell_allenvcell_ptr = m_envcell_container.to1DSpan();
145
146 // On force la valeur initiale sur tous les éléments car dans le ENUMERATE_CELL ci-dessous
147 // il se peut que m_size (qui vaut maxLocalId()+1) soit different de allCells().size()
148 m_envcell_container.fill(Span<ComponentItemLocalId>(), &queue);
149
150 m_current_max_nb_env = computeMaxNbEnvPerCell();
151 // TODO: vérifier débordement
152 Int32 pool_size = m_current_max_nb_env * m_size;
153 m_mem_pool.resize(pool_size);
154 m_mem_pool.fill(ComponentItemLocalId(), &queue);
155
156 Span<ComponentItemLocalId> mem_pool_view(m_mem_pool.to1DSpan());
157 CellToAllEnvCellConverter all_env_cell_converter(mm);
158 auto command = makeCommand(queue);
159 auto mem_pool = viewOut(command, m_mem_pool);
160 auto allcell_allenvcell = viewOut(command, m_envcell_container);
161 const Int32 max_nb_env = m_current_max_nb_env;
162 command << RUNCOMMAND_ENUMERATE (CellLocalId, cid, mm->mesh()->allCells())
163 {
164 AllEnvCell all_env_cell = all_env_cell_converter[CellLocalId(cid)];
165 Integer nb_env(all_env_cell.nbEnvironment());
166 if (nb_env != 0) {
167 Integer i = 0;
168 Integer offset(cid * max_nb_env);
169 ENUMERATE_CELL_ENVCELL (ienvcell, all_env_cell) {
170 EnvCell ev = *ienvcell;
171 mem_pool[offset + i] = ComponentItemLocalId(ev._varIndex());
172 ++i;
173 }
174 allcell_allenvcell[cid] = Span<ComponentItemLocalId>(mem_pool_view.ptrAt(offset), nb_env);
175 }
176 };
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
182void AllCellToAllEnvCellContainer::Impl::
183bruteForceUpdate()
184{
185 // Si les ids ont changé, on doit tout refaire
186 if (m_size != m_material_mng->mesh()->allCells().itemFamily()->maxLocalId() + 1) {
187 initialize();
188 return;
189 }
190
191 Int32 current_max_nb_env(computeMaxNbEnvPerCell());
192 // Si les ids n'ont pas changé, on regarde si à cet instant, le nb max d'env par maille a changé
193 // Si ca a changé, refaire le mem pool, sinon, juste update les valeurs
194 if (current_max_nb_env != m_current_max_nb_env) {
195 // On n'oublie pas de mettre a jour la nouvelle valeur !
196 m_current_max_nb_env = current_max_nb_env;
197 // on recrée le pool
198 Int32 pool_size = CheckedConvert::multiply(m_current_max_nb_env, m_size);
199 m_mem_pool.resize(pool_size);
200 }
201 // Mise a jour des valeurs
202 updateValues(m_material_mng, m_mem_pool.to1DSpan(), m_all_cell_to_all_env_cell.m_allcell_allenvcell_ptr, m_current_max_nb_env);
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208void AllCellToAllEnvCellContainer::Impl::
209reset()
210{
211 m_envcell_container.resize(0);
212 m_all_cell_to_all_env_cell.m_allcell_allenvcell_ptr = {};
213 m_mem_pool.resize(0);
214 m_material_mng = nullptr;
215 m_size = 0;
216 m_current_max_nb_env = 0;
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225AllCellToAllEnvCellContainer::
226AllCellToAllEnvCellContainer(IMeshMaterialMng* mm)
227: m_p(new Impl(mm))
228{
229}
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
233
234AllCellToAllEnvCellContainer::
235~AllCellToAllEnvCellContainer()
236{
237 delete m_p;
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243void AllCellToAllEnvCellContainer::
244reset()
245{
246 m_p->reset();
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
254{
255 return m_p->computeMaxNbEnvPerCell();
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
263{
264 m_p->initialize();
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
272{
273 m_p->bruteForceUpdate();
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
279AllCellToAllEnvCell AllCellToAllEnvCellContainer::
280view() const
281{
282 return m_p->view();
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291CellToAllEnvCellAccessor::
292CellToAllEnvCellAccessor(const IMeshMaterialMng* mm)
293{
295 if (c)
296 m_cell_allenvcell = c->view();
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
302} // End namespace Arcane::Materials
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
Types et macros pour itérer sur les entités du maillage.
Types et macros pour gérer les énumérations des entités sur les accélérateurs.
#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group,...)
Macro pour itérer sur accélérateur sur un groupe d'entités.
Algorithme générique de réduction sur accélérateur.
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
Int32ConstArrayView itemsLocalId() const
Liste des numéros locaux des entités de ce groupe.
ItemGroupImpl * internal() const
Retourne l'implémentation du groupe.
Definition ItemGroup.h:120
Table de connectivité des 'Cell' vers leur(s) 'AllEnvCell' destinée à une utilisation sur accélérateu...
Int32 computeMaxNbEnvPerCell() const
Méthode pour donner le nombre maximal d'environnements présents sur une maille à l'instant t.
void initialize()
Fonction de création alternative. Il faut attendre que les données relatives aux matériaux soient fin...
Table de connectivité des 'Cell' vers leur(s) 'AllEnvCell' destinée à une utilisation sur accélérateu...
Maille arcane avec info matériaux et milieux.
__host__ __device__ CellEnvCellEnumerator subEnvItems() const
Enumérateur sur les mailles milieux de cette maille.
__host__ __device__ Int32 nbEnvironment() const
Nombre de milieux présents dans la maille.
Maille arcane d'un milieu.
virtual RunQueue & runQueue() const =0
File d'exécution par défaut.
virtual AllCellToAllEnvCellContainer * getAllCellToAllEnvCellContainer() const =0
Renvoie la table de "connectivité" CellLocalId -> AllEnvCell destinée à être utilisée dans un RUNCOMM...
Interface du gestionnaire des matériaux et des milieux d'un maillage.
virtual IMesh * mesh()=0
Maillage associé.
virtual IMeshMaterialMngInternal * _internalApi() const =0
API interne à Arcane.
Tableaux multi-dimensionnels pour les types numériques accessibles sur accélérateurs.
constexpr __host__ __device__ pointer ptrAt(SizeType index) const
Adresse du index-ème élément.
Definition Span.h:360
Vue d'un tableau d'éléments de type T.
Definition Span.h:633
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro pour itérer sur tous les milieux d'une maille.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
auto viewOut(const ViewBuildInfo &vbi, CellMaterialVariableScalarRef< DataType > &var)
Vue en écriture pour les variables materiaux scalaire.
Active toujours les traces dans les parties Arcane concernant les matériaux.
Int32 Integer
Type représentant un entier.
ExtentsV< Int32, DynExtent > MDDim1
Constante pour un tableau dynamique de rang 1.
std::int32_t Int32
Type entier signé sur 32 bits.