Arcane  v3.15.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ConstituentItemVectorImpl.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/* ConstituentItemVectorImpl.cc (C) 2000-2024 */
9/* */
10/* Implémentation de 'IConstituentItemVectorImpl'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/ConstituentItemVectorImpl.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/FatalErrorException.h"
18
19#include "arcane/core/materials/IMeshMaterialMng.h"
21#include "arcane/core/materials/internal/IMeshComponentInternal.h"
22#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
23
24#include "arcane/accelerator/core/RunQueue.h"
27#include "arcane/accelerator/Partitioner.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane::Materials
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39ConstituentItemVectorImpl::
40ConstituentItemVectorImpl(IMeshComponent* component)
41: m_material_mng(component->materialMng())
42, m_component(component)
43, m_matvar_indexes(platform::getDefaultDataAllocator())
44, m_items_local_id(platform::getDefaultDataAllocator())
45, m_part_data(std::make_unique<MeshComponentPartData>(component, String()))
46, m_recompute_part_data_functor(this, &ConstituentItemVectorImpl::_recomputePartData)
47{
48 Int32 level = -1;
49 if (component->isMaterial())
50 level = LEVEL_MATERIAL;
51 else if (component->isEnvironment())
52 level = LEVEL_ENVIRONMENT;
53 else
54 ARCANE_FATAL("Bad internal type of component");
55 m_component_shared_info = m_material_mng->_internalApi()->componentItemSharedInfo(level);
56 m_constituent_list = std::make_unique<ConstituentItemLocalIdList>(m_component_shared_info, String());
57 m_part_data->setRecomputeFunctor(&m_recompute_part_data_functor);
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63ConstituentItemVectorImpl::
64ConstituentItemVectorImpl(const ComponentItemVectorView& rhs)
65: ConstituentItemVectorImpl(rhs.component())
66{
67 RunQueue& queue = m_material_mng->_internalApi()->runQueue();
68 m_constituent_list->copy(rhs._constituentItemListView());
69 m_matvar_indexes.copy(rhs._matvarIndexes());
70 m_items_local_id.copy(rhs._internalLocalIds());
71 m_part_data->_setFromMatVarIndexes(rhs._matvarIndexes(), queue);
72}
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
83{
84 public:
85
87 : m_use_new_impl(use_new_impl)
88 {}
89
90 public:
91
92 template <typename ConstituentGetterLambda>
96
97 private:
98
99 bool m_use_new_impl = true;
100};
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
105template <typename ConstituentGetterLambda> void
106ConstituentItemVectorImpl::SetItemHelper::
109{
110 SmallSpan<ConstituentItemIndex> item_indexes = vector_impl->m_constituent_list->_mutableItemIndexList();
111 SmallSpan<MatVarIndex> matvar_indexes = vector_impl->m_matvar_indexes.smallSpan();
112 SmallSpan<Int32> items_local_id = vector_impl->m_items_local_id.smallSpan();
114 const bool is_env = vector_impl->m_component->isEnvironment();
115 const Int32 component_id = vector_impl->m_component->id();
116
117 const Int32 nb_pure = vector_impl->m_nb_pure;
118
119 Int32 pure_index = 0;
120 Int32 impure_index = nb_pure;
121
122 const Int32 nb_id = local_ids.size();
123
124 // Pas besoin de conserver les informations pour les mailles pour lesquelles
125 // le constituant est absent.
126 auto setter_unselected = [=] ARCCORE_HOST_DEVICE(Int32, Int32) {
127 };
128 auto generic_setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index, ComponentCell cc) {
129 MatVarIndex idx = cc._varIndex();
130 ConstituentItemIndex cii = cc._constituentItemIndex();
131 item_indexes[index] = cii;
132 matvar_indexes[index] = idx;
133 items_local_id[index] = cc.globalCellId();
134 };
135
136 // Implémentation utilisant l'API accélérateur
137 if (m_use_new_impl) {
138 // Lambda pour sélectionner les mailles pures
139 auto select_pure = [=] ARCCORE_HOST_DEVICE(Int32 index) {
141 if (cc.null())
142 return false;
143 return (cc._varIndex().arrayIndex() == 0);
144 };
145 // Lambda pour sélectionner les mailles impures
146 auto select_impure = [=] ARCCORE_HOST_DEVICE(Int32 index) {
147 ComponentCell cc = constituent_getter_lambda(index);
148 if (cc.null())
149 return false;
150 return (cc._varIndex().arrayIndex() != 0);
151 };
152 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index, Int32 output_index) {
153 ComponentCell cc = constituent_getter_lambda(index);
154 if (!cc.null())
155 generic_setter_lambda(output_index, cc);
156 };
157 auto setter_pure = [=] ARCCORE_HOST_DEVICE(Int32 index, Int32 output_index) {
158 setter_lambda(index, output_index);
159 };
160 auto setter_impure = [=] ARCCORE_HOST_DEVICE(Int32 index, Int32 output_index) {
161 setter_lambda(index, output_index + nb_pure);
162 };
163 Arcane::Accelerator::GenericPartitioner generic_partitioner(queue);
164 generic_partitioner.applyWithIndex(nb_id, setter_pure, setter_impure, setter_unselected,
165 select_pure, select_impure, A_FUNCINFO);
166 //SmallSpan<const Int32> nb_parts = generic_partitioner.nbParts();
167 //std::cout << "NB_PART=" << nb_parts[0] << " " << nb_parts[1] << "\n";
168 }
169 else {
170 // Ancien mécanisme qui n'utilise pas l'API accélérateur
171 if (is_env) {
172 ENUMERATE_ALLENVCELL (iallenvcell, all_env_cell_view) {
173 AllEnvCell all_env_cell = *iallenvcell;
174 for (EnvCell ec : all_env_cell.subEnvItems()) {
175 if (ec.componentId() == component_id) {
176 MatVarIndex idx = ec._varIndex();
177 ConstituentItemIndex cii = ec._constituentItemIndex();
178 Int32& base_index = (idx.arrayIndex() == 0) ? pure_index : impure_index;
179 item_indexes[base_index] = cii;
180 matvar_indexes[base_index] = idx;
181 items_local_id[base_index] = all_env_cell.globalCellId();
182 ++base_index;
183 }
184 }
185 }
186 }
187 else {
188 // Filtre les matériaux correspondants aux local_ids
189 ENUMERATE_ALLENVCELL (iallenvcell, all_env_cell_view) {
190 AllEnvCell all_env_cell = *iallenvcell;
191 for (EnvCell env_cell : all_env_cell.subEnvItems()) {
192 for (MatCell mc : env_cell.subMatItems()) {
193 if (mc.componentId() == component_id) {
194 MatVarIndex idx = mc._varIndex();
195 ConstituentItemIndex cii = mc._constituentItemIndex();
196 Int32& base_index = (idx.arrayIndex() == 0) ? pure_index : impure_index;
197 item_indexes[base_index] = cii;
198 matvar_indexes[base_index] = idx;
199 items_local_id[base_index] = all_env_cell.globalCellId();
200 ++base_index;
201 }
202 }
203 }
204 }
205 }
206 }
207}
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
217void ConstituentItemVectorImpl::
219{
220 const bool do_new_impl = m_material_mng->_internalApi()->isUseAcceleratorForConstituentItemVector();
221
222 RunQueue queue = m_material_mng->_internalApi()->runQueue();
223
224 if (do_new_impl)
225 _computeNbPureAndImpure(local_ids, queue);
226 else
227 _computeNbPureAndImpureLegacy(local_ids);
228
229 const Int32 nb_pure = m_nb_pure;
230 const Int32 nb_impure = m_nb_impure;
232
233 // Tableau qui contiendra les indices des mailles pures et partielles.
234 // La première partie de 0 à nb_pure contiendra la partie pure.
235 // La seconde partie de nb_pure à (nb_pure+nb_impure) contiendra les mailles partielles
236 // A noter que (nb_pure + nb_impure) peut être différent de local_ids.size()
237 // si certaines mailles de \a local_ids n'ont pas le constituant.
238 m_constituent_list->resize(total_nb_pure_and_impure);
239
240 // TODO: Ne pas remettre à jour systématiquement les
241 // 'm_items_local_id' mais ne le faire qu'à la demande
242 // car ils ne sont pas utilisés souvent.
243
244 m_matvar_indexes.resize(total_nb_pure_and_impure);
245 m_items_local_id.resize(total_nb_pure_and_impure);
246
247 const bool is_env = m_component->isEnvironment();
248 AllEnvCellVectorView all_env_cell_view = m_material_mng->view(local_ids);
249 const Int32 component_id = m_component->id();
250
251 // Lambda pour récupérer le milieu associé à la maille
252 auto env_component_getter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) -> ComponentCell {
254 for (EnvCell ec : all_env_cell.subEnvItems()) {
255 if (ec.componentId() == component_id)
256 return ec;
257 }
258 return {};
259 };
260
261 // Lambda pour récupérer le matériau associé à la maille
262 auto mat_component_getter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) -> ComponentCell {
264 for (EnvCell ec : all_env_cell.subEnvItems()) {
265 for (MatCell mc : ec.subMatItems())
266 if (mc.componentId() == component_id)
267 return mc;
268 }
269 return {};
270 };
271
272 {
274 if (is_env)
275 helper.setItems(this, env_component_getter_lambda, local_ids, queue);
276 else
277 helper.setItems(this, mat_component_getter_lambda, local_ids, queue);
278 }
279
280 // Mise à jour de MeshComponentPartData
281 const bool do_lazy_evaluation = true;
283 m_part_data->setNeedRecompute();
284 else
285 _recomputePartData();
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291void ConstituentItemVectorImpl::
292_computeNbPureAndImpure(SmallSpan<const Int32> local_ids, RunQueue& queue)
293{
294 IMeshComponent* component = m_component;
295 const bool is_env = component->isEnvironment();
296 AllEnvCellVectorView all_env_cell_view = m_material_mng->view(local_ids);
297 const Int32 component_id = m_component->id();
298
299 auto command = makeCommand(queue);
302
303 // Calcule le nombre de mailles pures et partielles
304 if (is_env) {
306 {
307 for (EnvCell ec : all_env_cell.subEnvItems()) {
308 if (ec.componentId() == component_id) {
309 MatVarIndex idx = ec._varIndex();
310 if (idx.arrayIndex() == 0)
311 nb_pure.combine(1);
312 else
313 nb_impure.combine(1);
314 }
315 }
316 };
317 }
318 else {
319 command << RUNCOMMAND_MAT_ENUMERATE(AllEnvCell, all_env_cell, all_env_cell_view, nb_pure, nb_impure)
320 {
321 for (EnvCell env_cell : all_env_cell.subEnvItems()) {
322 for (MatCell mc : env_cell.subMatItems()) {
323 if (mc.componentId() == component_id) {
324 MatVarIndex idx = mc._varIndex();
325 if (idx.arrayIndex() == 0)
326 nb_pure.combine(1);
327 else
328 nb_impure.combine(1);
329 }
330 }
331 }
332 };
333 }
334
335 m_nb_pure = nb_pure.reducedValue();
336 m_nb_impure = nb_impure.reducedValue();
337}
338
339/*---------------------------------------------------------------------------*/
340/*---------------------------------------------------------------------------*/
344void ConstituentItemVectorImpl::
345_computeNbPureAndImpureLegacy(SmallSpan<const Int32> local_ids)
346{
347 IMeshComponent* component = m_component;
348 const bool is_env = component->isEnvironment();
349 AllEnvCellVectorView all_env_cell_view = m_material_mng->view(local_ids);
350 const Int32 component_id = m_component->id();
351
352 Int32 nb_pure = 0;
353 Int32 nb_impure = 0;
354
355 // Calcule le nombre de mailles pures et partielles
356 if (is_env) {
359 for (EnvCell ec : all_env_cell.subEnvItems()) {
360 if (ec.componentId() == component_id) {
361 MatVarIndex idx = ec._varIndex();
362 if (idx.arrayIndex() == 0)
363 ++nb_pure;
364 else
365 ++nb_impure;
366 }
367 }
368 }
369 }
370 else {
373 for (EnvCell env_cell : all_env_cell.subEnvItems()) {
374 for (MatCell mc : env_cell.subMatItems()) {
375 if (mc.componentId() == component_id) {
376 MatVarIndex idx = mc._varIndex();
377 if (idx.arrayIndex() == 0)
378 ++nb_pure;
379 else
380 ++nb_impure;
381 }
382 }
383 }
384 }
385 }
386
387 m_nb_pure = nb_pure;
388 m_nb_impure = nb_impure;
389}
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393
394void ConstituentItemVectorImpl::
395_recomputePartData()
396{
397 // Mise à jour de MeshComponentPartData
398 auto mvi_pure_view = m_matvar_indexes.subView(0, m_nb_pure);
399 auto mvi_impure_view = m_matvar_indexes.subView(m_nb_pure, m_nb_impure);
400 m_part_data->_setFromMatVarIndexes(mvi_pure_view, mvi_impure_view);
401}
402
403/*---------------------------------------------------------------------------*/
404/*---------------------------------------------------------------------------*/
405
406ComponentItemVectorView ConstituentItemVectorImpl::
407_view() const
408{
409 return { m_component, m_matvar_indexes,
410 m_constituent_list->view(), m_items_local_id };
411}
412
413/*---------------------------------------------------------------------------*/
414/*---------------------------------------------------------------------------*/
415
416} // End namespace Arcane::Materials
417
418/*---------------------------------------------------------------------------*/
419/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et fonctions pour gérer les synchronisations sur les accélérateurs.
Types et macros pour gérer les boucles sur les accélérateurs.
Types et macros pour gérer les énumérations des matériaux et milieux sur les accélérateurs.
#define RUNCOMMAND_MAT_ENUMERATE(ConstituentItemNameType, iter_name, env_or_mat_container,...)
Macro pour itérer sur un matériau ou un milieu.
Algorithme générique de partitionnement d'une liste.
Classe pour effectuer une réduction 'somme'.
Definition Reduce.h:755
File d'exécution pour un accélérateur.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
Vue sur une liste de mailles avec infos sur les milieux.
Maille arcane avec info matériaux et milieux.
Vue sur un vecteur sur les entités d'un composant.
Index d'une entité constituant dans la liste des entités constituants.
Implémentation de ComponentItemVector.
Représente un composant d'une maille multi-matériau.
Maille arcane d'un milieu.
Interface d'un composant (matériau ou milieu) d'un maillage.
virtual bool isEnvironment() const =0
Vrai si le composant est un milieu.
Représente un matériau d'une maille multi-matériau.
Représente un index sur les variables matériaux et milieux.
constexpr ARCCORE_HOST_DEVICE Int32 arrayIndex() const
Retourne l'indice du tableau de valeur dans la liste des variables.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro pour itérer sur toutes les mailles AllEnvCell d'un groupe.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
Active toujours les traces dans les parties Arcane concernant les matériaux.
IMemoryAllocator * getDefaultDataAllocator()
Allocateur par défaut pour les données.