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"
28#include "arcane/accelerator/Reduce.h"
29#include "arcane/accelerator/RunCommandLoop.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::
85 for (
Integer i = 0, n = nb_pure; i < n; ++i) {
89 for (
Integer i = 0, n = nb_partial; i < n; ++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);
111void MeshMaterialVariableIndexer::
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;
130 Int32 max_index_in_multiple = m_max_index_in_multiple_array;
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;
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::
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);
352 if (is_pure_to_partial) {
354 auto select_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
bool {
358 Int32 local_id = local_ids[index];
359 bool do_transform = transformed_cells[local_id];
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);
373 A_FUNCINFO1(
"ConstituentsTranformCellsFromPureToPartial"));
377 auto select_lambda = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
bool {
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) {
387 Int32 local_id = local_ids[input_index];
389 pure_local_ids[output_index] = local_id;
390 partial_indexes[output_index] = var_index;
391 matvar_indexes[input_index] =
MatVarIndex(0, local_id);
394 A_FUNCINFO1(
"ConstituentsTranformCellsFromPartialToPure"));
398 pure_local_ids_modifier.resize(nb_out);
399 partial_indexes_modifier.resize(nb_out);
408 if (is_pure_to_partial)
411 ++m_nb_useless_remove_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)
424void MeshMaterialVariableIndexer::
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 throwing a FatalErrorException.
Memory and allocator management functions.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
1D loop on accelerator with additional arguments.
Generic filtering algorithm on accelerator.
void applyWithIndex(Int32 nb_value, const SelectLambda &select_lambda, const SetterLambda &setter_lambda, const TraceInfo &trace_info=TraceInfo())
Applies a filter with selection based on an index.
Int32 nbOutputElement()
Number of output elements.
Class to perform a 'max' reduction.
Execution queue for an accelerator.
eExecutionPolicy executionPolicy() const
Execution policy of the queue.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Helper class for building a list of ComponentItems for a MeshMaterialVariableIndexer.
Helper class for building a list of ComponentItems for a MeshMaterialVariableIndexer.
Working structure used during the modification of constituents (via MeshMaterialModifier).
DualUniqueArray< Int32 > pure_local_ids
List of pure cells of a constituent added/removed by the current operation.
bool isAdd() const
Indicates if the current operation is an addition (true) or a removal (false) of cells.
DualUniqueArray< Int32 > partial_indexes
List of partial cells of a constituent added/removed by the current operation.
Represents an index on material and environment variables.
constexpr __host__ __device__ Int32 arrayIndex() const
Returns the index of the value array in the list of variables.
constexpr __host__ __device__ Int32 valueIndex() const
Returns the index in the value array.
bool m_is_print_useless_transform
Indicates whether a message is displayed during a useless transformation.
Integer m_index
Index of this instance in the list of indexers.
Int32 m_nb_transform_called
Number of calls to transformation methods.
UniqueArray< MatVarIndex > m_matvar_indexes
List of indices for material variables.
UniqueArray< Int32 > m_local_ids
List of localId() of entities corresponding to m_matvar_indexes. NOTE: eventually,...
Int32 m_nb_useless_add_transform
Number of useless calls to transformation methods.
const String & name() const
Name of the indexer.
Integer m_max_index_in_multiple_array
Max index plus 1 in the multiple values array.
View of an array of elements of type T.
constexpr __host__ __device__ SmallSpan< T > subView(Int32 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
TraceMessage info() const
Flow for an information message.
Checking the validity of certain values.
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indicates if exec_policy corresponds to an accelerator.
Always enables tracing in Arcane parts concerning materials.
Int32 checkResizeArrayWithCapacity(Array< DataType > &array, Int64 new_size, bool force_resize)
Resizes an array by adding a memory reserve.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
std::int32_t Int32
Signed integer type of 32 bits.