14#include "arcane/utils/NotImplementedException.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/FunctorUtils.h"
17#include "arcane/utils/ArgumentException.h"
18#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/ArraySimdPadder.h"
22#include "arcane/core/IMesh.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/VariableBuildInfo.h"
25#include "arcane/core/ItemGroupObserver.h"
26#include "arcane/core/internal/ItemGroupImplInternal.h"
27#include "arcane/core/materials/internal/IMeshMaterialVariableInternal.h"
28#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
30#include "arcane/materials/IMeshMaterialMng.h"
31#include "arcane/materials/MatItemEnumerator.h"
32#include "arcane/materials/ComponentItemVectorView.h"
33#include "arcane/materials/IMeshMaterialVariable.h"
34#include "arcane/materials/ComponentPartItemVectorView.h"
36#include "arcane/materials/internal/MeshEnvironment.h"
37#include "arcane/materials/internal/MeshMaterial.h"
38#include "arcane/materials/internal/ComponentItemListBuilder.h"
39#include "arcane/materials/internal/ComponentItemInternalData.h"
40#include "arcane/materials/internal/ConstituentConnectivityList.h"
41#include "arcane/materials/internal/ConstituentItemVectorImpl.h"
42#include "arcane/materials/internal/MeshComponentPartData.h"
44#include "arcane/accelerator/RunQueue.h"
45#include "arcane/accelerator/RunCommandLoop.h"
46#include "arcane/accelerator/Scan.h"
47#include "arcane/accelerator/SpanViews.h"
58class MeshEnvironmentObserver
64 MeshEnvironmentObserver(MeshEnvironment* env,
ITraceMng* tm)
75 if (m_environment->materialMng()->isInMeshMaterialExchange())
76 info() <<
"EXTEND_ENV_IN_LOADBALANCE " << m_environment->name()
77 <<
" ids=" << (*info1);
84 if (m_environment->materialMng()->isInMeshMaterialExchange())
85 info() <<
"REDUCE_ENV_IN_LOADBALANCE " << m_environment->name()
86 <<
" ids=" << (*info1);
91 info(4) <<
"COMPACT_ENV " << m_environment->name();
95 m_environment->notifyLocalIdsChanged(old_to_new_ids);
99 info() <<
"WARNING: invalidate() is invalid on an environment group! partial values may be corrupted"
100 <<
" env=" << m_environment->name();
106 MeshEnvironment* m_environment;
119, m_data(this, name, env_id, mm->_internalApi()->componentItemSharedInfo(LEVEL_ENVIRONMENT), false)
120, m_non_const_this(this)
121, m_internal_api(this)
131void MeshEnvironment::
134 IMesh* mesh = m_material_mng->mesh();
135 IItemFamily* cell_family = mesh->cellFamily();
136 String group_name = m_material_mng->name() +
"_" + name();
137 CellGroup cells = cell_family->findGroup(group_name,
true);
140 if (m_material_mng->isMeshModificationNotified()) {
141 m_group_observer =
new MeshEnvironmentObserver(
this, traceMng());
142 cells.internal()->attachObserver(
this, m_group_observer);
145 m_data._setItems(cells);
151void MeshEnvironment::
152addMaterial(MeshMaterial* mm)
155 m_true_materials.add(mm);
161void MeshEnvironment::
162setVariableIndexer(MeshMaterialVariableIndexer* idx)
164 m_data._setVariableIndexer(idx);
165 idx->setCells(m_data.items());
166 idx->setIsEnvironment(
true);
173 if (m_true_materials.size() == 1)
174 m_true_materials[0]->componentData()->_setItems(m_data.items());
175 m_data._buildPartData();
176 for (MeshMaterial* mat : m_true_materials)
177 mat->componentData()->_buildPartData();
183void MeshEnvironment::
186 info(4) <<
"ComputeNbMatPerCell env=" << name();
187 Integer nb_mat = m_materials.size();
189 for (
Integer i = 0; i < nb_mat; ++i) {
192 total += mat_cells.
size();
194 m_total_nb_cell_mat = total;
207void MeshEnvironment::
208computeMaterialIndexes(ComponentItemInternalData* item_internal_data, RunQueue& queue)
210 info(4) <<
"Compute (V2) indexes for environment name=" << name();
211 const bool is_mono_mat = isMonoMaterial();
213 _computeMaterialIndexesMonoMat(item_internal_data, queue);
216 _computeMaterialIndexes(item_internal_data, queue);
222void MeshEnvironment::
223_computeMaterialIndexes(ComponentItemInternalData* item_internal_data, RunQueue& queue)
225 IItemFamily* cell_family = cells().itemFamily();
226 Integer max_local_id = cell_family->maxLocalId();
228 ComponentItemInternalRange mat_items_internal_range = m_mat_internal_data_range;
231 cells_index.resize(max_local_id);
233 cells_pos.resize(max_local_id);
238 cells_env.resize(max_local_id);
242 const bool do_old =
false;
245 for (
Integer z = 0, nb = local_ids.size(); z < nb; ++z) {
246 Int32 lid = local_ids[z];
249 cells_index[lid] = cell_index;
250 cell_index += nb_mat;
255 Int32 nb_id = local_ids.size();
257 Accelerator::GenericScanner scanner(queue);
258 auto cells_index_view =
viewOut(queue, cells_index);
260 auto getter = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
Int32 {
261 return constituent_item_list_view._constituenItemBase(index).nbSubItem();
263 auto setter = [=] ARCCORE_HOST_DEVICE(
Int32 index,
Int32 value) {
264 Int32 lid = local_ids[index];
265 cells_index_view[lid] = value;
267 Accelerator::ScannerSumOperator<Int32> op;
268 scanner.applyWithIndexExclusive(nb_id, 0, getter, setter, op, A_FUNCINFO);
273 auto cells_env_view =
viewOut(command, cells_env);
274 auto cells_index_view =
viewIn(command, cells_index);
275 auto cells_pos_view =
viewOut(command, cells_pos);
276 Int32 nb_id = local_ids.size();
280 Int32 lid = local_ids[z];
283 Int32 cell_index = cells_index_view[lid];
284 cells_pos_view[lid] = cell_index;
286 env_item._setFirstSubItem(mat_items_internal_range[cell_index]);
288 cells_env_view[lid] = env_item.constituentItemIndex();
292 Integer nb_mat = m_true_materials.size();
293 ComponentItemInternalRange mat_item_internal_range = m_mat_internal_data_range;
294 for (
Integer i = 0; i < nb_mat; ++i) {
295 MeshMaterial* mat = m_true_materials[i];
296 Int16 mat_id = mat->componentId();
297 const MeshMaterialVariableIndexer* var_indexer = mat->variableIndexer();
299 info(4) <<
"COMPUTE (V2) mat_cells mat=" << mat->
name() <<
" nb_cell=" << mat_cells.size()
300 <<
" mat_id=" << mat_id <<
" index=" << var_indexer->index() <<
" is_async=" << queue.isAsync();
302 mat->resizeItemsInternal(var_indexer->nbItem());
305 auto matvar_indexes =
viewIn(command, var_indexer->matvarIndexes());
306 auto local_ids =
viewIn(command, var_indexer->localIds());
307 SmallSpan<Int32> cells_pos_view(cells_pos);
308 auto cells_env_view =
viewIn(command, cells_env);
309 ComponentItemSharedInfo* mat_shared_info = item_internal_data->matSharedInfo();
310 SmallSpan<ConstituentItemIndex> mat_id_list = mat->componentData()->m_constituent_local_id_list.mutableLocalIds();
311 const Int32 nb_id = local_ids.size();
312 Span<Int32> mat_cells_local_id = mat_cells._internalApi()->itemsLocalId();
317 Int32 lid = local_ids[z];
318 Int32 pos = cells_pos_view[lid];
319 ++cells_pos_view[lid];
322 mat_id_list[z] = cii;
323 ref_ii._setSuperAndGlobalItem(cells_env_view[lid], ItemLocalId(lid));
324 ref_ii._setComponent(mat_id);
325 ref_ii._setVariableIndex(mvi);
328 ArraySimdPadder::applySimdPaddingView(mat_cells_local_id);
330 mat_cells._internalApi()->notifySimdPaddingDone();
346void MeshEnvironment::
347_computeMaterialIndexesMonoMat(ComponentItemInternalData* item_internal_data, RunQueue& queue)
351 MeshMaterial* mat = m_true_materials[0];
352 const Int16 mat_id = mat->componentId();
353 const MeshMaterialVariableIndexer* var_indexer = mat->variableIndexer();
355 info(4) <<
"COMPUTE (V2) mat_cells mat=" << mat->
name() <<
" nb_cell=" << mat_cells.size()
356 <<
" mat_id=" << mat_id <<
" index=" << var_indexer->index();
358 mat->resizeItemsInternal(var_indexer->nbItem());
361 auto matvar_indexes =
viewIn(command, var_indexer->matvarIndexes());
362 auto local_ids =
viewIn(command, var_indexer->localIds());
363 ComponentItemSharedInfo* mat_shared_info = item_internal_data->matSharedInfo();
364 ComponentItemInternalRange mat_item_internal_range = m_mat_internal_data_range;
365 SmallSpan<ConstituentItemIndex> mat_id_list = mat->componentData()->m_constituent_local_id_list.mutableLocalIds();
366 const Int32 nb_id = local_ids.size();
367 Span<Int32> mat_cells_local_id = mat_cells._internalApi()->itemsLocalId();
372 const Int32 lid = local_ids[z];
376 env_item._setFirstSubItem(cii);
379 mat_id_list[z] = cii;
380 ref_ii._setSuperAndGlobalItem(env_item.constituentItemIndex(), ItemLocalId(lid));
381 ref_ii._setComponent(mat_id);
382 ref_ii._setVariableIndex(mvi);
385 ArraySimdPadder::applySimdPaddingView(mat_cells_local_id);
387 mat_cells._internalApi()->notifySimdPaddingDone();
397void MeshEnvironment::
398computeItemListForMaterials(
const ConstituentConnectivityList& connectivity_list)
400 info(4) <<
"ComputeItemListForMaterials (V2)";
401 ConstArrayView<Int16> nb_env_per_cell = connectivity_list.cellsNbEnvironment();
402 const Int16 env_id = componentId();
405 for (MeshMaterial* mat : m_true_materials) {
406 MeshMaterialVariableIndexer* var_indexer = mat->variableIndexer();
410 ComponentItemListBuilderOld list_builder(var_indexer, 0);
412 info(4) <<
"MAT_INDEXER mat=" << mat->name() <<
" NB_CELL=" << var_nb_cell <<
" name=" << cells.name();
414 Int32 lid = icell.itemLocalId();
417 if (nb_env_per_cell[lid] > 1 || connectivity_list.cellNbMaterial(icell, env_id) > 1)
418 list_builder.addPartialItem(lid);
420 list_builder.addPureItem(lid);
423 if (traceMng()->verbosityLevel() >= 5)
424 info() <<
"MAT_NB_MULTIPLE_CELL (V2) mat=" << var_indexer->name()
425 <<
" nb_in_global=" << list_builder.pureMatVarIndexes().size()
426 <<
" (ids=" << list_builder.pureMatVarIndexes() <<
")"
427 <<
" nb_in_multiple=" << list_builder.partialMatVarIndexes().size()
428 <<
" (ids=" << list_builder.partialLocalIds() <<
")";
429 var_indexer->endUpdate(list_builder);
436void MeshEnvironment::
451 info(4) <<
"Changing (V3) local ids references env=" << name();
452 info(4) <<
"CurrentCells name=" << cells().name()
453 <<
" n=" << cells().view().localIds().size();
454 info(4) <<
"MatVarIndex name=" << cells().name()
455 <<
" n=" << variableIndexer()->matvarIndexes().size();
456 Integer nb_mat = m_true_materials.size();
457 info(4) <<
"NotifyLocalIdsChanged env=" << name() <<
" nb_mat=" << nb_mat
458 <<
" old_to_new_ids.size=" << old_to_new_ids.size();
470 m_data._changeLocalIdsForInternalList(old_to_new_ids);
471 MeshMaterial* true_mat = m_true_materials[0];
472 _changeIds(true_mat->componentData(), old_to_new_ids);
476 for (
Integer i = 0; i < nb_mat; ++i) {
477 MeshMaterial* true_mat = m_true_materials[i];
478 info(4) <<
"ChangeIds MAT i=" << i <<
" MAT=" << true_mat->name();
479 _changeIds(true_mat->componentData(), old_to_new_ids);
482 _changeIds(componentData(), old_to_new_ids);
488 RunQueue& queue = m_material_mng->_internalApi()->runQueue();
489 for (
Integer i = 0; i < nb_mat; ++i) {
490 MeshMaterial* true_mat = m_true_materials[i];
491 true_mat->componentData()->_rebuildPartData(queue);
493 componentData()->_rebuildPartData(queue);
502void MeshEnvironment::
505 info(4) <<
"ChangeIds() (V4) for name=" << cdata->name();
506 info(4) <<
"Use new version for ChangeIds()";
508 cdata->_changeLocalIdsForInternalList(old_to_new_ids);
509 cdata->variableIndexer()->changeLocalIds(old_to_new_ids);
531ComponentCell MeshEnvironment::
534 return findEnvCell(c);
543 return { m_non_const_this, variableIndexer()->matvarIndexes(),
544 constituentItemListView(), variableIndexer()->localIds() };
559void MeshEnvironment::
560resizeItemsInternal(
Integer nb_item)
562 m_data._resizeItemsInternal(nb_item);
571 return m_data._partData()->pureView();
580 return m_data._partData()->impureView();
589 return m_data._partData()->partView(part);
598 return { m_non_const_this, m_data._partData()->pureView() };
605impureEnvItems()
const
607 return { m_non_const_this, m_data._partData()->impureView() };
616 return { m_non_const_this, m_data._partData()->partView(part) };
622void MeshEnvironment::
638bool MeshEnvironment::
639isMonoMaterial()
const
641 bool is_mono_mat = (nbMaterial() == 1 && (cells().size() == totalNbCellMat()));
648Int32 MeshEnvironment::InternalApi::
649variableIndexerIndex()
const
651 return variableIndexer()->index();
657Ref<IConstituentItemVectorImpl> MeshEnvironment::InternalApi::
658createItemVectorImpl()
const
660 auto* x =
new ConstituentItemVectorImpl(m_environment->m_non_const_this);
667Ref<IConstituentItemVectorImpl> MeshEnvironment::InternalApi::
670 auto* x =
new ConstituentItemVectorImpl(rhs);
#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.
const String & name() const
Group name.
Integer size() const
Number of elements in the group.
ItemGroupImplInternal * _internalApi() const
Internal Arcane API.
Arcane cell with material and environment information.
View over the impure part of a component.
View over a vector of entities of a component.
View over pure or partial entities of a component.
View over the pure part of a component.
__host__ __device__ Int32 componentId() const
Component identifier in the list of components of this type.
Arcane cell of an environment.
__host__ __device__ Int32 environmentId() const
Environment identifier.
View over the impure part of the entities of an environment.
View over a vector of entities of an environment.
View over pure or partial entities of an environment.
View over the pure part of the entities of an environment.
Interface for the material and environment manager of a mesh.
Interface of a mesh material.
Represents an index on material and environment variables.
bool needInfo() const override
Indicates whether the observer will need transition information.
void executeReduce(const Int32ConstArrayView *info1) override
Execute the action associated with the extension.
void executeInvalidate() override
Execute the action associated with invalidation.
void executeExtend(const Int32ConstArrayView *info1) override
Execute the action associated with the extension.
void executeCompact(const Int32ConstArrayView *info1) override
Executes the action associated with compaction.
__host__ __device__ Int32 nbSubItem() const
Number of sub-components.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ItemGroupT< Cell > CellGroup
Group of cells.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
Always enables tracing in Arcane parts concerning materials.
MatItemVariableScalarOutViewT< Cell, DataType > viewOut(CellMaterialVariableScalarRef< DataType > &var)
Write view.
MatItemVariableScalarInViewT< Cell, DataType > viewIn(const CellMaterialVariableScalarRef< DataType > &var)
Read view.
eMatPart
Part of a component.
bool arcaneIsCheck()
True if running in check mode.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
std::int16_t Int16
Signed integer type of 16 bits.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.