14#include "arcane/utils/ITraceMng.h"
15#include "arcane/utils/ValueChecker.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ArgumentException.h"
18#include "arcane/utils/NotSupportedException.h"
19#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/ValueConvert.h"
23#include "arcane/materials/internal/MeshMaterialVariableIndexer.h"
24#include "arcane/materials/internal/ComponentItemListBuilder.h"
25#include "arcane/materials/internal/ConstituentModifierWorkInfo.h"
27#include "arcane/accelerator/Filter.h"
39MeshMaterialVariableIndexer::
40MeshMaterialVariableIndexer(ITraceMng* tm,
const String& name)
47 m_matvar_indexes.setDebugName(String(
"VariableIndexerMatVarIndexes")+name);
48 m_local_ids.setDebugName(String(
"VariableIndexerLocalIdsIndexes")+name);
57void MeshMaterialVariableIndexer::
60 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_PRINT_USELESS_TRANSFORMATION",
true))
61 m_is_print_useless_transform = (v.value() != 0);
67void MeshMaterialVariableIndexer::
68endUpdate(
const ComponentItemListBuilderOld& builder)
70 ConstArrayView<MatVarIndex> pure_matvar = builder.pureMatVarIndexes();
71 ConstArrayView<MatVarIndex> partial_matvar = builder.partialMatVarIndexes();
73 Integer nb_pure = pure_matvar.size();
74 Integer nb_partial = partial_matvar.size();
75 m_matvar_indexes.resize(nb_pure + nb_partial);
77 m_matvar_indexes.subView(0, nb_pure).copy(pure_matvar);
78 m_matvar_indexes.subView(nb_pure, nb_partial).copy(partial_matvar);
83 m_local_ids.resize(nb_pure + nb_partial);
85 for (Integer i = 0, n = nb_pure; i < n; ++i) {
86 m_local_ids[index] = pure_matvar[i].valueIndex();
89 for (Integer i = 0, n = nb_partial; i < n; ++i) {
90 m_local_ids[index] = local_ids_in_multiple[i];
98 Int32 max_index_in_multiple = (-1);
99 for (Integer i = 0; i < nb_partial; ++i) {
100 max_index_in_multiple = math::max(partial_matvar[i].valueIndex(), max_index_in_multiple);
102 m_max_index_in_multiple_array = max_index_in_multiple;
105 info(4) <<
"END_UPDATE max_index=" << m_max_index_in_multiple_array;
111void MeshMaterialVariableIndexer::
112endUpdateAdd(
const ComponentItemListBuilder& builder, RunQueue& queue)
114 SmallSpan<const Int32> pure_indexes = builder.pureIndexes();
115 SmallSpan<const Int32> partial_indexes = builder.partialIndexes();
117 Integer nb_pure_to_add = pure_indexes.size();
118 Integer nb_partial_to_add = partial_indexes.size();
119 Integer total_to_add = nb_pure_to_add + nb_partial_to_add;
120 Integer current_nb_item = nbItem();
121 const Int32 new_size = current_nb_item + total_to_add;
123 MemoryUtils::checkResizeArrayWithCapacity(m_matvar_indexes, new_size,
false);
124 MemoryUtils::checkResizeArrayWithCapacity(m_local_ids, new_size,
false);
126 SmallSpan<const Int32> local_ids_in_multiple = builder.partialLocalIds();
127 SmallSpan<Int32> local_ids_view = m_local_ids.subView(current_nb_item, total_to_add);
128 SmallSpan<MatVarIndex> matvar_indexes = m_matvar_indexes.subView(current_nb_item, total_to_add);
130 Int32 max_index_in_multiple = m_max_index_in_multiple_array;
133 Arcane::Accelerator::ReducerMax2<Int32> max_index_reducer(command);
134 Int32 max_to_add = math::max(nb_pure_to_add, nb_partial_to_add);
135 const Int32 component_index = m_index + 1;
139 if (i < nb_pure_to_add) {
140 Int32 index = pure_indexes[i];
141 local_ids_view[i] = index;
142 matvar_indexes[i] = MatVarIndex(0, index);
144 if (i < nb_partial_to_add) {
145 Int32 index = partial_indexes[i];
146 local_ids_view[nb_pure_to_add + i] = local_ids_in_multiple[i];
147 matvar_indexes[nb_pure_to_add + i] = MatVarIndex(component_index, index);
148 max_index_reducer.combine(index);
151 max_index_in_multiple = math::max(max_index_reducer.reducedValue(), m_max_index_in_multiple_array);
153 m_max_index_in_multiple_array = max_index_in_multiple;
155 info(4) <<
"END_UPDATE_ADD max_index=" << m_max_index_in_multiple_array
156 <<
" nb_partial_to_add=" << nb_partial_to_add;
162void MeshMaterialVariableIndexer::
163endUpdateRemove(ConstituentModifierWorkInfo& work_info, Integer nb_remove, RunQueue& queue)
165 endUpdateRemoveV2(work_info, nb_remove, queue);
171void MeshMaterialVariableIndexer::
172endUpdateRemoveV2(ConstituentModifierWorkInfo& work_info, Integer nb_remove, RunQueue& queue)
178 Integer orig_nb_item = nb_item;
180 info(4) <<
"EndUpdateRemoveV2 nb_remove=" << nb_remove <<
" nb_item=" << nb_item;
182 if (nb_remove == nb_item) {
183 m_matvar_indexes.clear();
189 auto saved_matvar_indexes_modifier = work_info.m_saved_matvar_indexes.modifier(is_device);
190 auto saved_local_ids_modifier = work_info.m_saved_local_ids.modifier(is_device);
192 saved_matvar_indexes_modifier.resize(nb_remove);
193 saved_local_ids_modifier.resize(nb_remove);
195 Accelerator::GenericFilterer filterer(queue);
196 SmallSpan<const bool> removed_cells = work_info.removedCells();
197 Span<MatVarIndex> last_matvar_indexes(saved_matvar_indexes_modifier.view());
198 Span<Int32> last_local_ids(saved_local_ids_modifier.view());
199 Span<Int32> local_ids(m_local_ids);
200 Span<MatVarIndex> matvar_indexes(m_matvar_indexes);
204 Int32 last_index = nb_item - 1;
205 auto select_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) ->
bool {
206 Int32 lid = local_ids[last_index - index];
207 return !removed_cells[lid];
209 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 input_index, Int32 output_index) {
210 Int32 true_index = (last_index - input_index);
211 if (output_index < nb_remove) {
212 last_matvar_indexes[output_index] = matvar_indexes[true_index];
213 last_local_ids[output_index] = local_ids[true_index];
216 filterer.applyWithIndex(orig_nb_item, select_lambda, setter_lambda, A_FUNCINFO);
217 filterer.nbOutputElement();
222 auto select_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) ->
bool {
223 Int32 lid = local_ids[index];
224 return removed_cells[lid];
226 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 input_index, Int32 output_index) {
227 matvar_indexes[input_index] = last_matvar_indexes[output_index];
228 local_ids[input_index] = last_local_ids[output_index];
230 filterer.applyWithIndex(orig_nb_item - nb_remove, select_lambda, setter_lambda, A_FUNCINFO);
231 filterer.nbOutputElement();
233 nb_item -= nb_remove;
234 m_matvar_indexes.resize(nb_item);
235 m_local_ids.resize(nb_item);
238 Integer nb_remove_computed = (orig_nb_item - nb_item);
239 if (nb_remove_computed != nb_remove)
240 ARCANE_FATAL(
"Bad number of removed material items expected={0} v={1} name={2}",
241 nb_remove, nb_remove_computed, name());
242 info(4) <<
"END_UPDATE_REMOVE nb_removed=" << nb_remove;
251void MeshMaterialVariableIndexer::
252changeLocalIds(Int32ConstArrayView old_to_new_ids)
254 this->_changeLocalIdsV2(
this, old_to_new_ids);
260void MeshMaterialVariableIndexer::
261_changeLocalIdsV2(MeshMaterialVariableIndexer* var_indexer, Int32ConstArrayView old_to_new_ids)
266 ITraceMng* tm = var_indexer->traceMng();
268 tm->info(4) <<
"ChangeLocalIdsV2 name=" << var_indexer->name();
270 UniqueArray<Int32> ids_copy(var_indexer->localIds());
271 UniqueArray<MatVarIndex> matvar_indexes_copy(var_indexer->matvarIndexes());
273 var_indexer->m_local_ids.clear();
274 var_indexer->m_matvar_indexes.clear();
278 tm->info(4) <<
"-- -- BEGIN_PROCESSING N=" << ids_copy.size();
280 for (Integer i = 0; i < nb; ++i) {
281 Int32 lid = ids_copy[i];
282 Int32 new_lid = old_to_new_ids[lid];
283 tm->info(5) <<
"I=" << i <<
" lid=" << lid <<
" new_lid=" << new_lid;
285 if (new_lid != NULL_ITEM_LOCAL_ID) {
286 MatVarIndex mvi = matvar_indexes_copy[i];
287 tm->info(5) <<
"I=" << i <<
" new_lid=" << new_lid <<
" mv=" << mvi;
288 Int32 value_index = mvi.valueIndex();
289 if (mvi.arrayIndex() == 0) {
299 var_indexer->m_matvar_indexes.add(MatVarIndex(0, value_index));
300 var_indexer->m_local_ids.add(value_index);
304 var_indexer->m_matvar_indexes.add(mvi);
305 var_indexer->m_local_ids.add(new_lid);
311 tm->info(4) <<
"-- -- ChangeLocalIdsV2 END_PROCESSING (V4)"
312 <<
" indexer_name=" << var_indexer->name()
313 <<
" nb_ids=" << var_indexer->m_local_ids.size();
332void MeshMaterialVariableIndexer::
333transformCells(ConstituentModifierWorkInfo& work_info, RunQueue& queue,
bool is_from_env)
335 bool is_pure_to_partial = work_info.isAdd();
339 auto pure_local_ids_modifier = work_info.pure_local_ids.modifier(is_device);
340 auto partial_indexes_modifier = work_info.partial_indexes.modifier(is_device);
341 pure_local_ids_modifier.resize(nb);
342 partial_indexes_modifier.resize(nb);
344 SmallSpan<Int32> pure_local_ids = pure_local_ids_modifier.view();
345 SmallSpan<Int32> partial_indexes = partial_indexes_modifier.view();
346 SmallSpan<MatVarIndex> matvar_indexes = m_matvar_indexes.view();
347 SmallSpan<Int32> local_ids = m_local_ids.view();
348 SmallSpan<const bool> transformed_cells = work_info.transformedCells();
350 Accelerator::GenericFilterer filterer(queue);
352 if (is_pure_to_partial) {
354 auto select_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) ->
bool {
355 MatVarIndex mvi = matvar_indexes[index];
356 if (mvi.arrayIndex() != 0)
358 Int32 local_id = local_ids[index];
359 bool do_transform = transformed_cells[local_id];
363 Int32 max_index_in_multiple_array = m_max_index_in_multiple_array + 1;
364 const Int32 var_index = m_index + 1;
365 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 input_index, Int32 output_index) {
366 Int32 current_index = max_index_in_multiple_array + output_index;
367 Int32 local_id = local_ids[input_index];
368 pure_local_ids[output_index] = local_id;
369 partial_indexes[output_index] = current_index;
370 matvar_indexes[input_index] = MatVarIndex(var_index, current_index);
372 filterer.applyWithIndex(nb, select_lambda, setter_lambda,
373 A_FUNCINFO1(
"ConstituentsTranformCellsFromPureToPartial"));
377 auto select_lambda = [=] ARCCORE_HOST_DEVICE(Int32 index) ->
bool {
378 MatVarIndex mvi = matvar_indexes[index];
379 if (mvi.arrayIndex() == 0)
381 Int32 local_id = local_ids[index];
382 bool do_transform = transformed_cells[local_id];
385 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 input_index, Int32 output_index) {
386 MatVarIndex mvi = matvar_indexes[input_index];
387 Int32 local_id = local_ids[input_index];
388 Int32 var_index = mvi.valueIndex();
389 pure_local_ids[output_index] = local_id;
390 partial_indexes[output_index] = var_index;
391 matvar_indexes[input_index] = MatVarIndex(0, local_id);
393 filterer.applyWithIndex(nb, select_lambda, setter_lambda,
394 A_FUNCINFO1(
"ConstituentsTranformCellsFromPartialToPure"));
397 const Int32 nb_out = filterer.nbOutputElement();
398 pure_local_ids_modifier.resize(nb_out);
399 partial_indexes_modifier.resize(nb_out);
401 ++m_nb_transform_called;
408 if (is_pure_to_partial)
409 ++m_nb_useless_add_transform;
411 ++m_nb_useless_remove_transform;
412 if (m_is_print_useless_transform)
413 info() <<
"VarIndex null transformation modified_name=" << name()
414 <<
" is_add=" << is_pure_to_partial <<
" is_from_env=" << is_from_env;
417 if (is_pure_to_partial)
418 m_max_index_in_multiple_array += nb_out;
424void MeshMaterialVariableIndexer::
427 ValueChecker vc(A_FUNCINFO);
431 vc.areEqual(nb_item, m_matvar_indexes.size(),
"Incoherent size for local ids and matvar indexes");
440void MeshMaterialVariableIndexer::
443 if (m_nb_transform_called == 0)
445 Int32 nb_useless_call = m_nb_useless_add_transform + m_nb_useless_remove_transform;
446 Int32 nb_useful_call = m_nb_transform_called - nb_useless_call;
447 info() <<
"VariableIndexer name=" << name()
448 <<
" nb_useful_transform=" << nb_useful_call
449 <<
" nb_useless_add=" << m_nb_useless_add_transform
450 <<
" nb_useless_remove=" << m_nb_useless_remove_transform;
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions de gestion mémoire et des allocateurs.
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_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indique si exec_policy correspond à un accélérateur.
Active toujours les traces dans les parties Arcane concernant les matériaux.
IMemoryAllocator * getDefaultDataAllocator()
Allocateur par défaut pour les données.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Int32 Integer
Type représentant un entier.