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"
21#include "arcane/utils/MemoryUtils.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.
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.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Int32 Integer
Type représentant un entier.