14#include "arcane/materials/internal/IncrementalComponentModifier.h"
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FunctorUtils.h"
18#include "arcane/utils/ValueConvert.h"
20#include "arcane/core/IItemFamily.h"
21#include "arcane/core/materials/IMeshMaterialVariable.h"
23#include "arcane/materials/internal/MeshMaterialMng.h"
24#include "arcane/materials/internal/ConstituentConnectivityList.h"
25#include "arcane/materials/internal/AllEnvData.h"
27#include "arcane/accelerator/core/ProfileRegion.h"
38IncrementalComponentModifier::
39IncrementalComponentModifier(
AllEnvData* all_env_data,
const RunQueue& queue)
40: TraceAccessor(all_env_data->traceMng())
41, m_all_env_data(all_env_data)
42, m_material_mng(all_env_data->m_material_mng)
43, m_work_info(queue.allocationOptions(), queue.memoryRessource())
49 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_USE_GENERIC_COPY_BETWEEN_PURE_AND_PARTIAL",
true)) {
50 m_use_generic_copy_between_pure_and_partial = v.value();
55 if (queue.executionPolicy() != Accelerator::eExecutionPolicy::Sequential)
56 m_use_generic_copy_between_pure_and_partial = 2;
58 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_FORCE_MULTIPLE_COMMAND_FOR_MATERIAL_RESIZE",
true)) {
59 m_force_multiple_command_for_resize = (v.value());
60 info() <<
"Force using multiple command for resize = " << m_force_multiple_command_for_resize;
67void IncrementalComponentModifier::
68initialize(
bool is_debug)
70 m_is_debug = is_debug;
71 Int32 max_local_id = m_material_mng->mesh()->cellFamily()->maxLocalId();
72 Int32 nb_mat = m_material_mng->materials().size();
73 Int32 nb_env = m_material_mng->environments().size();
74 m_work_info.initialize(max_local_id, nb_mat, nb_env, m_queue);
75 m_work_info.is_verbose = is_debug || (traceMng()->verbosityLevel() >= 5);
81void IncrementalComponentModifier::
101void IncrementalComponentModifier::
102_switchCellsForMaterials(
const MeshMaterial* modified_mat,
105 const bool is_add = m_work_info.isAdd();
106 const bool is_device = m_queue.isAcceleratorPolicy();
112 if (mat == modified_mat)
115 if (!is_materials_modified[mat->id()])
119 m_work_info.pure_local_ids.clearHost();
120 m_work_info.partial_indexes.clearHost();
125 info(4) <<
"MatTransformCells is_add?=" << is_add <<
" indexer=" << indexer->
name()
126 <<
" mat_id=" << mat->id();
129 info(4) <<
"nb_transformed=" << nb_transformed;
130 if (nb_transformed == 0)
133 _resetTransformedCells(ids);
135 auto pure_local_ids = m_work_info.pure_local_ids.view(is_device);
136 auto partial_indexes = m_work_info.partial_indexes.view(is_device);
138 Int32 nb_pure = pure_local_ids.size();
139 Int32 nb_partial = partial_indexes.size();
140 info(4) <<
"NB_MAT_TRANSFORM pure=" << nb_pure
141 <<
" partial=" << nb_partial <<
" name=" << mat->name()
142 <<
" is_device?=" << is_device
143 <<
" is_modified?=" << is_materials_modified[mat->id()];
147 m_do_copy_between_partial_and_pure,
170void IncrementalComponentModifier::
174 const bool is_add = m_work_info.isAdd();
175 const bool is_device = m_queue.isAcceleratorPolicy();
182 const bool is_copy = is_add || !(m_material_mng->isUseMaterialValueWhenRemovingPartialValue());
185 info(4) <<
"Compute Cells for environments nb_transformed=" << nb_transformed;
186 if (nb_transformed == 0)
189 for (
const MeshEnvironment* env : m_material_mng->trueEnvironments()) {
191 if (env == modified_env)
194 if (env->isMonoMaterial())
197 const Int32 env_id = env->id();
199 if (!is_environments_modified[env_id])
203 m_work_info.pure_local_ids.clearHost();
204 m_work_info.partial_indexes.clearHost();
209 info(4) <<
"EnvTransformCells is_add?=" << is_add
210 <<
" env_id=" << env_id
211 <<
" indexer=" << indexer->
name() <<
" nb_item=" << ids.
size();
217 const Int32 nb_pure = pure_local_ids.
size();
219 info(4) <<
"NB_ENV_TRANSFORM nb_pure=" << nb_pure <<
" name=" << env->name()
220 <<
" is_modified=" << is_environments_modified[env_id];
225 m_do_copy_between_partial_and_pure, is_add,
231 _resetTransformedCells(ids);
244 const Int16 env_id = env->componentId();
245 bool is_add = m_work_info.isAdd();
268void IncrementalComponentModifier::
272 info(4) <<
"MeshEnvironment::removeItemsDirect mat=" << mat->
name();
277 env->addToTotalNbCellMat(-nb_to_remove);
279 mat->variableIndexer()->endUpdateRemove(m_work_info, nb_to_remove, m_queue);
281 if (update_env_indexer) {
286 env->variableIndexer()->endUpdateRemove(m_work_info, nb_to_remove, m_queue);
301void IncrementalComponentModifier::
305 info(4) <<
"MeshEnvironment::addItemsDirect"
306 <<
" mat=" << mat->
name();
309 const Int32 nb_to_add = local_ids.
size();
312 env->addToTotalNbCellMat(nb_to_add);
314 const Int16 env_id = env->componentId();
315 m_work_info.m_cells_is_partial.resize(nb_to_add);
317 connectivity->
fillCellsIsPartial(local_ids, env_id, m_work_info.m_cells_is_partial.to1DSmallSpan(), m_queue);
319 _addItemsToIndexer(var_indexer, local_ids);
321 if (update_env_indexer) {
326 _addItemsToIndexer(env->variableIndexer(), local_ids);
333void IncrementalComponentModifier::
339 list_builder.setIndexer(var_indexer);
342 list_builder.preAllocate(nb_id);
344 _computeItemsToAdd(list_builder, local_ids);
346 if (traceMng()->verbosityLevel() >= 5)
347 info() <<
"ADD_MATITEM_TO_INDEXER component=" << var_indexer->
name()
348 <<
" nb_pure=" << list_builder.pureIndexes().
size()
349 <<
" nb_partial=" << list_builder.partialIndexes().
size()
350 <<
"\n pure=(" << list_builder.pureIndexes() <<
")"
351 <<
"\n partial=(" << list_builder.partialIndexes() <<
")";
356 var_indexer->endUpdateAdd(list_builder, m_queue);
359 _resizeVariablesIndexer(var_indexer->index());
363 if (m_do_init_new_items) {
370 if (init_with_zero) {
374 bool do_one_command = (m_use_generic_copy_between_pure_and_partial == 2);
376 if (do_one_command) {
378 copy_data.
reserve(m_material_mng->nbVariable());
379 init_args.m_copy_data = ©_data;
383 mv->_internalApi()->initializeNewItemsWithZero(init_args);
385 functor::apply(mm, &IMeshMaterialMng::visitVariables, func_zero);
387 if (do_one_command) {
388 MDSpan<CopyBetweenDataInfo, MDDim1> x(copy_data.
data(), MDIndex<1>(copy_data.
size()));
389 m_work_info.m_variables_copy_data.copy(x, &m_queue);
390 _applyInitializeWithZero(init_args);
395 SmallSpan<Int32> partial_local_ids = list_builder.partialLocalIds();
397 CopyBetweenPartialAndGlobalArgs args(var_indexer->index(), partial_local_ids,
398 partial_indexes,
true,
true, m_queue);
399 _copyBetweenPartialsAndGlobals(args);
410void IncrementalComponentModifier::
411_resizeVariablesIndexer(
Int32 var_index)
421 do_one_command =
false;
424 if (do_one_command) {
426 copy_data.
reserve(m_material_mng->nbVariable());
438 auto* mvi = mv->_internalApi();
439 mvi->resizeForIndexer(resize_args);
447 auto* mvi = mv->_internalApi();
448 mvi->resizeForIndexer(resize_args);
453 if (do_one_command) {
456 m_work_info.m_variables_copy_data.copy(x, &m_queue);
473void IncrementalComponentModifier::
476 if (args.m_local_ids.
empty())
478 const bool do_copy = args.m_do_copy_between_partial_and_pure;
479 const bool is_add_operation = args.m_is_global_to_partial;
490 if (is_add_operation) {
498 copy_data.
reserve(m_material_mng->nbVariable());
506 auto* mvi = mv->_internalApi();
508 args2.m_queue = queue_pool[index];
509 mvi->copyBetweenPartialAndGlobal(args2);
513 if (do_one_command) {
516 m_work_info.m_variables_copy_data.copy(x, &queue);
Integer size() const
Number of elements in the vector.
void barrier() const
Forces waiting for all RunQueues.
Execution queue for an accelerator.
void clear()
Removes the elements from the array.
const T * data() const
Access to the root of the array without any protection.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
Base class for multi-dimensional views.
Information on environment values.
Helper class for building a list of ComponentItems for a MeshMaterialVariableIndexer.
Management of constituent connectivity lists.
Int32 fillCellsToTransform(SmallSpan< const Int32 > cells_local_id, Int16 env_id, SmallSpan< bool > cells_do_transform, bool is_add, RunQueue &queue)
Fills cells_do_transform indicating if the cell transitions from pure to partial.
void fillCellsIsPartial(SmallSpan< const Int32 > cells_local_id, Int16 env_id, SmallSpan< bool > cells_is_partial, RunQueue &queue)
Fills cells_is_partial indicating if the cell is partial for environment env_id.
Arguments for methods copying between partial and global values.
Interface of a mesh environment.
Interface for the material and environment manager of a mesh.
virtual bool isDataInitialisationWithZero() const =0
Indicates how to initialize new values in material and environment cells.
Interface of a material variable on a mesh.
Int32 _computeCellsToTransformForEnvironments(SmallSpan< const Int32 > ids)
Calculates the cells to transform when modifying the cells of an environment.
void _applyCopyVariableViews(RunQueue &queue)
Performs the copy of views for variables.
bool m_force_multiple_command_for_resize
True if we force the use of a single command for resizing.
void _applyCopyBetweenPartialsAndGlobals(const CopyBetweenPartialAndGlobalArgs &args, RunQueue &queue)
Performs the copy between partial and global values.
void _resizeVariablesIndexer(Int32 var_index)
Resizes the variable index var_index.
void _copyBetweenPartialsAndGlobals(const CopyBetweenPartialAndGlobalArgs &args)
Copies between partial and global values.
Int32 m_use_generic_copy_between_pure_and_partial
1 or 2 if we use a generic version for copies between pure and partial
Int32 _computeCellsToTransformForMaterial(const MeshMaterial *mat, SmallSpan< const Int32 > ids)
Calculates the cells to transform for material \at mat.
Arguments for methods copying between partial and global values.
void visitVariables(IFunctorWithArgumentT< IMeshMaterialVariable * > *functor) override
Applies the functor functor to all material variables.
Indexer for material variables.
void transformCells(ConstituentModifierWorkInfo &args, RunQueue &queue, bool is_from_env)
Transforme des mailles entre pure et partielle.
const String & name() const
Name of the indexer.
String name() const override
Component name.
Arguments for methods copying between partial and global values.
UniqueArray< CopyBetweenDataInfo > * m_copy_data
Copy information if only one command is used.
View of an array of elements of type T.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Unicode character string.
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
constexpr __host__ __device__ bool empty() const noexcept
Returns true if the array is empty (zero dimension).
Always enables tracing in Arcane parts concerning materials.
std::int16_t Int16
Signed integer type of 16 bits.
std::int32_t Int32
Signed integer type of 32 bits.