14#include "arcane/materials/internal/IncrementalComponentModifier.h"
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FunctorUtils.h"
19#include "arcane/core/internal/ItemGroupImplInternal.h"
20#include "arcane/core/materials/IMeshMaterialVariable.h"
22#include "arcane/materials/internal/MeshMaterialMng.h"
23#include "arcane/materials/internal/MaterialModifierOperation.h"
24#include "arcane/materials/internal/ConstituentConnectivityList.h"
25#include "arcane/materials/internal/AllEnvData.h"
28#include "arcane/accelerator/Filter.h"
30#include "arcane/accelerator/core/ProfileRegion.h"
41void IncrementalComponentModifier::
42apply(MaterialModifierOperation* operation)
44 const char* str_add =
"ApplyConstituentOperationAdd";
45 const char* str_remove =
"ApplyConstituentOperationRemove";
46 bool is_add = operation->isAdd();
47 Int32 color = (is_add) ? 0x00FFFF : 0x007FFF;
48 Accelerator::ProfileRegion ps(m_queue, is_add ? str_add : str_remove, color);
50 IMeshMaterial* mat = operation->material();
51 SmallSpan<const Int32> orig_ids = operation->ids();
52 SmallSpan<const Int32> ids = orig_ids;
56 const IMeshEnvironment* env = mat->environment();
57 MeshEnvironment* true_env = true_mat->trueEnvironment();
58 const Integer nb_mat = env->nbMaterial();
60 info(4) <<
"-- ** -- Using optimisation updateMaterialDirect is_add=" << is_add
61 <<
" mat=" << mat->name() <<
" nb_item=" << orig_ids.size()
62 <<
" mat_id=" << mat->id() <<
" env_id=" << env->id();
64 ConstituentConnectivityList* connectivity = m_all_env_data->componentConnectivityList();
81 connectivity->fillModifiedConstituents(orig_ids, mat_modifier.view(), env_modifier.view(), mat->id(), is_add, m_queue);
83 connectivity->printConstituents(orig_ids);
88 info(4) <<
"ModifiedInfosAfter: mats=" << is_mat_modified <<
" envs=" << is_env_modified;
105 const Int32 nb_id = ids.size();
106 cells_unchanged_in_env.resize(nb_id);
107 cells_changed_in_env.resize(nb_id);
108 cells_current_nb_material.resize(nb_id);
109 const Int32 ref_nb_mat = is_add ? 0 : 1;
110 const Int16 env_id = true_env->componentId();
111 info(4) <<
"Using optimisation updateMaterialDirect is_add?=" << is_add;
113 connectivity->fillCellsNbMaterial(ids, env_id, cells_current_nb_material.view(), m_queue);
116 Accelerator::GenericFilterer filterer(m_queue);
117 SmallSpan<Int32> cells_unchanged_in_env_view = cells_unchanged_in_env.view();
118 SmallSpan<Int32> cells_changed_in_env_view = cells_changed_in_env.view();
121 auto select_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
bool {
122 Int16 current_cell_nb_mat = cells_current_nb_material_view[index];
123 return current_cell_nb_mat != ref_nb_mat;
125 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 input_index,
Int32 output_index) {
126 cells_unchanged_in_env_view[output_index] = ids[input_index];
128 filterer.applyWithIndex(nb_id, select_lambda, setter_lambda, A_FUNCINFO);
129 cells_unchanged_in_env.resize(filterer.nbOutputElement());
132 auto select_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
bool {
133 Int16 current_cell_nb_mat = cells_current_nb_material_view[index];
134 return current_cell_nb_mat == ref_nb_mat;
136 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 input_index,
Int32 output_index) {
137 cells_changed_in_env_view[output_index] = ids[input_index];
139 filterer.applyWithIndex(nb_id, select_lambda, setter_lambda, A_FUNCINFO);
140 cells_changed_in_env.resize(filterer.nbOutputElement());
144 Integer nb_unchanged_in_env = cells_unchanged_in_env.size();
145 info(4) <<
"Cells unchanged in environment n=" << nb_unchanged_in_env;
147 Int16 mat_id = true_mat->componentId();
149 mat->cells().addItems(cells_unchanged_in_env, check_if_present);
150 connectivity->addCellsToMaterial(mat_id, cells_unchanged_in_env.view(), m_queue);
154 flagRemovedCells(cells_unchanged_in_env,
true);
155 _removeItemsInGroup(mat->cells(), cells_unchanged_in_env);
156 connectivity->removeCellsToMaterial(mat_id, cells_unchanged_in_env.view(), m_queue);
158 flagRemovedCells(cells_unchanged_in_env,
false);
164 ids = cells_changed_in_env.view();
171 Int16 env_id = true_env->componentId();
172 Int16 mat_id = true_mat->componentId();
174 connectivity->addCellsToEnvironment(env_id, ids, m_queue);
175 connectivity->addCellsToMaterial(mat_id, ids, m_queue);
178 connectivity->removeCellsToEnvironment(env_id, ids, m_queue);
179 connectivity->removeCellsToMaterial(mat_id, ids, m_queue);
187 info(4) <<
"Transform PartialPure for material name=" << true_mat->name();
189 info(4) <<
"Transform PartialPure for environment name=" << env->name();
194 bool need_update_env = (nb_mat != 1);
197 mat->cells().addItems(ids.smallView(), check_if_present);
199 env->cells().addItems(ids.smallView(), check_if_present);
203 flagRemovedCells(ids,
true);
204 _removeItemsInGroup(mat->cells(), ids);
206 _removeItemsInGroup(env->cells(), ids);
209 flagRemovedCells(ids,
false);
227 const Int32 n = ids.size();
253void IncrementalComponentModifier::
278 auto select_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) ->
bool {
285 filterer.applyWithIndex(nb_id, select_lambda, setter_lambda, A_FUNCINFO);
286 nb_pure_added = filterer.nbOutputElement();
290 auto select_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
bool {
291 return cells_is_partial[index];
293 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 input_index,
Int32 output_index) {
294 Int32 local_id = local_ids[input_index];
295 partial_indexes[output_index] = index_in_partial + output_index;
296 partial_local_ids[output_index] = local_id;
298 filterer.applyWithIndex(nb_id, select_lambda, setter_lambda, A_FUNCINFO);
299 nb_partial_added = filterer.nbOutputElement();
302 list_builder.resize(nb_pure_added, nb_partial_added);
308void IncrementalComponentModifier::
309flagRemovedCells(SmallSpan<const Int32> local_ids,
bool value_to_set)
311 const Int32 nb_item = local_ids.size();
312 SmallSpan<bool> removed_cells = m_work_info.removedCells();
321 removed_cells[local_ids[i]] = value_to_set;
328void IncrementalComponentModifier::
329_resetTransformedCells(SmallSpan<const Int32> local_ids)
331 const Int32 nb_item = local_ids.size();
333 SmallSpan<bool> transformed_cells = m_work_info.transformedCells();
337 Int32 lid = local_ids[i];
338 transformed_cells[lid] =
false;
345void IncrementalComponentModifier::
346_removeItemsInGroup(ItemGroup cells, SmallSpan<const Int32> removed_ids)
348 const Int32 nb_removed = removed_ids.size();
352 const bool do_old =
false;
354 cells.removeItems(removed_ids.smallView(),
false);
360 ItemGroupImplInternal* impl_internal = cells._internalApi();
361 SmallSpan<Int32> items_local_id(impl_internal->itemsLocalId());
365 SmallSpan<const Int32> input_ids(items_local_id);
366 SmallSpan<Int32> output_ids_view(items_local_id);
367 SmallSpan<const bool> filtered_cells(m_work_info.removedCells());
368 Accelerator::GenericFilterer filterer(m_queue);
369 auto select_filter = [=] ARCCORE_HOST_DEVICE(
Int32 local_id) ->
bool {
370 return !filtered_cells[local_id];
372 filterer.applyIf(input_ids, output_ids_view, select_filter, A_FUNCINFO);
374 Int32 current_nb_item = items_local_id.size();
375 Int32 nb_remaining = filterer.nbOutputElement();
376 if ((nb_remaining + nb_removed) != current_nb_item)
377 ARCANE_FATAL(
"Internal error in removing nb_remaining={0} nb_removed={1} original_size={2}",
378 nb_remaining, nb_removed, current_nb_item);
379 impl_internal->notifyDirectRemoveItems(removed_ids, nb_remaining);
409 for (Int32 i = 0; i <
nb_copy; ++i) {
422 auto [
icopy, i] = iter();
428 for (Int32
j = 0;
j < dim2_size; ++
j)
436void IncrementalComponentModifier::
441 const RunQueue& queue = args.m_queue;
449 for (Int32 i = 0; i <
nb_copy; ++i) {
460 auto [
icopy, i] = iter();
464 for (Int32
j = 0;
j < dim2_size; ++
j)
494 for (Int32 i = 0; i <
nb_copy; ++i) {
505 auto [
icopy, i] = iter();
508 output[i] =
input[i];
#define ARCANE_CHECK_ACCESSIBLE_POINTER(queue_or_runner_or_policy, ptr)
Macro qui vérifie en mode check si ptr est accessible pour une RunQueue ou un Runner.
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#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.
#define RUNCOMMAND_LOOP2(iter_name, x1, x2)
Boucle sur accélérateur.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
Algorithme générique de filtrage sur accélérateur.
Classe pour effectuer une réduction 'somme'.
File d'exécution pour un accélérateur.
bool isAcceleratorPolicy() const
Indique si l'instance est associée à un accélérateur.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Classe d'aide à la construction d'une liste de ComponentItem pour un MeshMaterialVariableIndexer.
Gestion des listes de connectivité des constituants.
UniqueArray< Int32 > cells_unchanged_in_env
Liste des mailles d'un milieu qui sont déjà présentes dans un milieu lors d'une opération.
UniqueArray< Int16 > m_cells_current_nb_material
Nombre de matériaux pour le milieu en cours d'évaluation.
UniqueArray< CopyBetweenDataInfo > m_host_variables_copy_data
Informations pour les copies entre valeurs partielles et globales.
DualUniqueArray< bool > m_is_materials_modified
Tableau dimensionné aux matériaux qui est vrai si un matériau est concerné par la modification en cou...
UniqueArray< Int32 > cells_changed_in_env
Liste des mailles d'un milieu qui vont être ajoutées ou supprimées lors d'une opération.
NumArray< CopyBetweenDataInfo, MDDim1 > m_variables_copy_data
Informations pour les copies entre valeurs partielles et globales.
bool isAdd() const
Indique si l'opération courante est un ajout (true) ou une suppression (false) de mailles.
DualUniqueArray< bool > m_is_environments_modified
Tableau dimensionné aux milieux qui est vrai si un milieu est concerné par la modification en cours.
Arguments des méthodes de copie entre valeurs partielles et globales.
void _switchCellsForMaterials(const MeshMaterial *modified_mat, SmallSpan< const Int32 > ids)
Transforme les entités pour un milieu.
Int32 _computeCellsToTransformForEnvironments(SmallSpan< const Int32 > ids)
Calcule les mailles à transformer lorsqu'on modifie les mailles d'un milieu.
void _switchCellsForEnvironments(const IMeshEnvironment *modified_env, SmallSpan< const Int32 > ids)
Transforme les entités pour les milieux.
void _applyCopyVariableViews(RunQueue &queue)
Effectue la copie des vues pour les variables.
void _addItemsToEnvironment(MeshEnvironment *env, MeshMaterial *mat, SmallSpan< const Int32 > local_ids, bool update_env_indexer)
Ajoute les mailles d'un matériau du milieu.
void _applyCopyBetweenPartialsAndGlobals(const CopyBetweenPartialAndGlobalArgs &args, RunQueue &queue)
Effectue la copie entre les valeurs partielles et globales.
void _removeItemsFromEnvironment(MeshEnvironment *env, MeshMaterial *mat, SmallSpan< const Int32 > local_ids, bool update_env_indexer)
Supprime les mailles d'un matériau du milieu.
Arguments des méthodes de copie entre valeurs partielles et globales.
Indexer pour les variables materiaux.
UniqueArray< CopyBetweenDataInfo > * m_copy_data
Informations de copie si on n'utilise qu'une seule commande.
ArrayView< T > view() const
Vue mutable sur ce tableau.
TraceMessage info() const
Flot pour un message d'information.
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.
Int32 Integer
Type représentant un entier.
Informations pour la copie entre deux zones mémoire.