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::
100void IncrementalComponentModifier::
101_switchCellsForMaterials(
const MeshMaterial* modified_mat,
102 SmallSpan<const Int32> ids)
104 const bool is_add = m_work_info.isAdd();
105 const bool is_device = m_queue.isAcceleratorPolicy();
106 SmallSpan<const bool> is_materials_modified = m_work_info.m_is_materials_modified.view(
false);
108 for (MeshEnvironment* true_env : m_material_mng->trueEnvironments()) {
109 for (MeshMaterial* mat : true_env->trueMaterials()) {
111 if (mat == modified_mat)
114 if (!is_materials_modified[mat->id()])
118 m_work_info.pure_local_ids.clearHost();
119 m_work_info.partial_indexes.clearHost();
122 MeshMaterialVariableIndexer* indexer = mat->variableIndexer();
124 info(4) <<
"MatTransformCells is_add?=" << is_add <<
" indexer=" << indexer->name()
125 <<
" mat_id=" << mat->id();
127 Int32 nb_transformed = _computeCellsToTransformForMaterial(mat, ids);
128 info(4) <<
"nb_transformed=" << nb_transformed;
129 if (nb_transformed == 0)
131 indexer->transformCells(m_work_info, m_queue,
false);
132 _resetTransformedCells(ids);
134 auto pure_local_ids = m_work_info.pure_local_ids.view(is_device);
135 auto partial_indexes = m_work_info.partial_indexes.view(is_device);
137 Int32 nb_pure = pure_local_ids.size();
138 Int32 nb_partial = partial_indexes.size();
139 info(4) <<
"NB_MAT_TRANSFORM pure=" << nb_pure
140 <<
" partial=" << nb_partial <<
" name=" << mat->name()
141 <<
" is_device?=" << is_device
142 <<
" is_modified?=" << is_materials_modified[mat->id()];
144 CopyBetweenPartialAndGlobalArgs args(indexer->index(), pure_local_ids,
146 m_do_copy_between_partial_and_pure,
149 _copyBetweenPartialsAndGlobals(args);
168void IncrementalComponentModifier::
169_switchCellsForEnvironments(
const IMeshEnvironment* modified_env,
170 SmallSpan<const Int32> ids)
172 const bool is_add = m_work_info.isAdd();
173 const bool is_device = m_queue.isAcceleratorPolicy();
174 SmallSpan<const bool> is_environments_modified = m_work_info.m_is_environments_modified.view(
false);
180 const bool is_copy = is_add || !(m_material_mng->isUseMaterialValueWhenRemovingPartialValue());
182 Int32 nb_transformed = _computeCellsToTransformForEnvironments(ids);
183 info(4) <<
"Compute Cells for environments nb_transformed=" << nb_transformed;
184 if (nb_transformed == 0)
187 for (
const MeshEnvironment* env : m_material_mng->trueEnvironments()) {
189 if (env == modified_env)
192 if (env->isMonoMaterial())
195 const Int32 env_id = env->id();
197 if (!is_environments_modified[env_id])
201 m_work_info.pure_local_ids.clearHost();
202 m_work_info.partial_indexes.clearHost();
205 MeshMaterialVariableIndexer* indexer = env->variableIndexer();
207 info(4) <<
"EnvTransformCells is_add?=" << is_add
208 <<
" env_id=" << env_id
209 <<
" indexer=" << indexer->name() <<
" nb_item=" << ids.size();
211 indexer->transformCells(m_work_info, m_queue,
true);
213 SmallSpan<const Int32> pure_local_ids = m_work_info.pure_local_ids.view(is_device);
214 SmallSpan<const Int32> partial_indexes = m_work_info.partial_indexes.view(is_device);
215 const Int32 nb_pure = pure_local_ids.size();
217 info(4) <<
"NB_ENV_TRANSFORM nb_pure=" << nb_pure <<
" name=" << env->name()
218 <<
" is_modified=" << is_environments_modified[env_id];
221 CopyBetweenPartialAndGlobalArgs copy_args(indexer->index(), pure_local_ids,
223 m_do_copy_between_partial_and_pure, is_add,
225 _copyBetweenPartialsAndGlobals(copy_args);
229 _resetTransformedCells(ids);
237Int32 IncrementalComponentModifier::
238_computeCellsToTransformForMaterial(
const MeshMaterial* mat, SmallSpan<const Int32> ids)
240 const MeshEnvironment* env = mat->trueEnvironment();
241 const Int16 env_id = env->componentId();
242 bool is_add = m_work_info.isAdd();
244 ConstituentConnectivityList* connectivity = m_all_env_data->componentConnectivityList();
245 SmallSpan<bool> transformed_cells = m_work_info.transformedCells();
246 return connectivity->fillCellsToTransform(ids, env_id, transformed_cells, is_add, m_queue);
264void IncrementalComponentModifier::
265_removeItemsFromEnvironment(MeshEnvironment* env, MeshMaterial* mat,
266 SmallSpan<const Int32> local_ids,
bool update_env_indexer)
268 info(4) <<
"MeshEnvironment::removeItemsDirect mat=" << mat->name();
270 Int32 nb_to_remove = local_ids.size();
273 env->addToTotalNbCellMat(-nb_to_remove);
275 mat->variableIndexer()->endUpdateRemove(m_work_info, nb_to_remove, m_queue);
277 if (update_env_indexer) {
282 env->variableIndexer()->endUpdateRemove(m_work_info, nb_to_remove, m_queue);
296void IncrementalComponentModifier::
297_addItemsToEnvironment(MeshEnvironment* env, MeshMaterial* mat,
298 SmallSpan<const Int32> local_ids,
bool update_env_indexer)
300 info(4) <<
"MeshEnvironment::addItemsDirect"
301 <<
" mat=" << mat->name();
303 MeshMaterialVariableIndexer* var_indexer = mat->variableIndexer();
304 const Int32 nb_to_add = local_ids.size();
307 env->addToTotalNbCellMat(nb_to_add);
309 const Int16 env_id = env->componentId();
310 m_work_info.m_cells_is_partial.resize(nb_to_add);
311 ConstituentConnectivityList* connectivity = m_all_env_data->componentConnectivityList();
312 connectivity->fillCellsIsPartial(local_ids, env_id, m_work_info.m_cells_is_partial.to1DSmallSpan(), m_queue);
314 _addItemsToIndexer(var_indexer, local_ids);
316 if (update_env_indexer) {
321 _addItemsToIndexer(env->variableIndexer(), local_ids);
328void IncrementalComponentModifier::
329_addItemsToIndexer(MeshMaterialVariableIndexer* var_indexer,
330 SmallSpan<const Int32> local_ids)
333 ComponentItemListBuilder& list_builder = m_work_info.list_builder;
334 list_builder.setIndexer(var_indexer);
336 const Int32 nb_id = local_ids.size();
337 list_builder.preAllocate(nb_id);
339 _computeItemsToAdd(list_builder, local_ids);
341 if (traceMng()->verbosityLevel() >= 5)
342 info() <<
"ADD_MATITEM_TO_INDEXER component=" << var_indexer->name()
343 <<
" nb_pure=" << list_builder.pureIndexes().size()
344 <<
" nb_partial=" << list_builder.partialIndexes().size()
345 <<
"\n pure=(" << list_builder.pureIndexes() <<
")"
346 <<
"\n partial=(" << list_builder.partialIndexes() <<
")";
351 var_indexer->endUpdateAdd(list_builder, m_queue);
354 _resizeVariablesIndexer(var_indexer->index());
358 if (m_do_init_new_items) {
359 IMeshMaterialMng* mm = m_material_mng;
360 bool init_with_zero = mm->isDataInitialisationWithZero();
362 Accelerator::ProfileRegion ps(m_queue,
"InitializeNewItems", 0xFFFF00);
364 SmallSpan<Int32> partial_indexes = list_builder.partialIndexes();
365 if (init_with_zero) {
366 RunQueue::ScopedAsync sc(&m_queue);
367 InitializeWithZeroArgs init_args(var_indexer->index(), partial_indexes, m_queue);
369 bool do_one_command = (m_use_generic_copy_between_pure_and_partial == 2);
370 UniqueArray<CopyBetweenDataInfo>& copy_data = m_work_info.m_host_variables_copy_data;
371 if (do_one_command) {
373 copy_data.reserve(m_material_mng->nbVariable());
374 init_args.m_copy_data = ©_data;
377 auto func_zero = [&](IMeshMaterialVariable* mv) {
378 mv->_internalApi()->initializeNewItemsWithZero(init_args);
380 functor::apply(mm, &IMeshMaterialMng::visitVariables, func_zero);
383 MDSpan<CopyBetweenDataInfo, MDDim1> x(copy_data.data(), MDIndex<1>(copy_data.size()));
384 m_work_info.m_variables_copy_data.copy(x, &m_queue);
385 _applyInitializeWithZero(init_args);
390 SmallSpan<Int32> partial_local_ids = list_builder.partialLocalIds();
392 CopyBetweenPartialAndGlobalArgs args(var_indexer->index(), partial_local_ids,
393 partial_indexes,
true,
true, m_queue);
394 _copyBetweenPartialsAndGlobals(args);
404void IncrementalComponentModifier::
405_resizeVariablesIndexer(Int32 var_index)
407 Accelerator::ProfileRegion ps(m_queue,
"ResizeVariableIndexer", 0xFF00FF);
408 ResizeVariableIndexerArgs resize_args(var_index, m_queue);
412 bool do_one_command = (m_use_generic_copy_between_pure_and_partial == 2);
414 if (m_force_multiple_command_for_resize)
415 do_one_command =
false;
417 UniqueArray<CopyBetweenDataInfo>& copy_data = m_work_info.m_host_variables_copy_data;
418 if (do_one_command) {
420 copy_data.reserve(m_material_mng->nbVariable());
421 resize_args.m_copy_data = ©_data;
424 if (m_force_multiple_command_for_resize) {
430 auto func2 = [&](IMeshMaterialVariable* mv) {
431 Accelerator::ProfileRegion ps2(m_queue, String(
"Resize_") + mv->name());
432 auto* mvi = mv->_internalApi();
433 mvi->resizeForIndexer(resize_args);
436 functor::apply(m_material_mng, &MeshMaterialMng::visitVariables, func2);
439 RunQueue::ScopedAsync sc(&m_queue);
440 auto func1 = [&](IMeshMaterialVariable* mv) {
441 auto* mvi = mv->_internalApi();
442 mvi->resizeForIndexer(resize_args);
444 functor::apply(m_material_mng, &MeshMaterialMng::visitVariables, func1);
447 if (do_one_command) {
449 MDSpan<CopyBetweenDataInfo, MDDim1> x(copy_data.data(), MDIndex<1>(copy_data.size()));
450 m_work_info.m_variables_copy_data.copy(x, &m_queue);
451 _applyCopyVariableViews(m_queue);
466void IncrementalComponentModifier::
467_copyBetweenPartialsAndGlobals(
const CopyBetweenPartialAndGlobalArgs& args)
469 if (args.m_local_ids.empty())
471 const bool do_copy = args.m_do_copy_between_partial_and_pure;
472 const bool is_add_operation = args.m_is_global_to_partial;
473 RunQueue queue(args.m_queue);
474 RunQueue::ScopedAsync sc(&queue);
480 Accelerator::RunQueuePool& queue_pool = m_material_mng->_internalApi()->asyncRunQueuePool();
483 if (is_add_operation) {
484 _resizeVariablesIndexer(args.m_var_index);
488 bool do_one_command = (m_use_generic_copy_between_pure_and_partial == 2);
489 UniqueArray<CopyBetweenDataInfo>& copy_data = m_work_info.m_host_variables_copy_data;
491 copy_data.reserve(m_material_mng->nbVariable());
494 CopyBetweenPartialAndGlobalArgs args2(args);
495 args2.m_use_generic_copy = (m_use_generic_copy_between_pure_and_partial >= 1);
497 args2.m_copy_data = ©_data;
498 auto func2 = [&](IMeshMaterialVariable* mv) {
499 auto* mvi = mv->_internalApi();
501 args2.m_queue = queue_pool[index];
502 mvi->copyBetweenPartialAndGlobal(args2);
505 functor::apply(m_material_mng, &MeshMaterialMng::visitVariables, func2);
506 if (do_one_command) {
508 MDSpan<CopyBetweenDataInfo, MDDim1> x(copy_data.data(), MDIndex<1>(copy_data.size()));
509 m_work_info.m_variables_copy_data.copy(x, &queue);
510 _applyCopyBetweenPartialsAndGlobals(args2, queue);
513 queue_pool.barrier();
Active toujours les traces dans les parties Arcane concernant les matériaux.