Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
AcceleratorMeshMaterialSynchronizerImpl.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* AcceleratorMeshMaterialSynchronizerImpl.cc (C) 2000-2024 */
9/* */
10/* Synchronization of material entities. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/AcceleratorMeshMaterialSynchronizerImpl.h"
15
16#include "arcane/core/VariableTypes.h"
17#include "arcane/core/IParallelMng.h"
18#include "arcane/core/ItemPrinter.h"
19#include "arcane/core/IMesh.h"
20
21#include "arcane/materials/CellToAllEnvCellConverter.h"
22#include "arcane/materials/MatItemEnumerator.h"
23#include "arcane/materials/MeshMaterialModifier.h"
24
25#include "arcane/core/ItemGenericInfoListView.h"
26#include "arcane/core/internal/IParallelMngInternal.h"
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane::Materials
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36AcceleratorMeshMaterialSynchronizerImpl::
37AcceleratorMeshMaterialSynchronizerImpl(IMeshMaterialMng* material_mng)
38: TraceAccessor(material_mng->traceMng())
39, m_material_mng(material_mng)
40, m_mat_presence(VariableBuildInfo(material_mng->mesh(), "ArcaneMaterialSyncPresence"))
41{
42 IMesh* mesh = m_material_mng->mesh();
43 auto* internal_pm = mesh->parallelMng()->_internalApi();
44 if (!internal_pm->runner().isInitialized()) {
45 Arcane::Runner default_runner(Arcane::Accelerator::eExecutionPolicy::Sequential);
46 internal_pm->setDefaultRunner(default_runner);
47 }
48 Arcane::Accelerator::RunQueue m_queue = internal_pm->queue();
49 m_idx_selecter = Arcane::Accelerator::IndexSelecter(m_queue);
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58bool AcceleratorMeshMaterialSynchronizerImpl::
59synchronizeMaterialsInCells()
60{
61 /*
62 The algorithm used is as follows:
63
64 We use a cell variable that uses a bit for each
65 material to indicate its presence: if this bit is set, the material
66 is present, otherwise it is absent. The variable used is therefore of type
67 ArrayByte on the cells. The _hasBit() and _setBit() methods allow
68 setting the bit of a given material.
69
70 1. The subdomain fills this variable for these cells.
71 2. The variable is synchronized.
72 3. The subdomain compares for each of its ghost cells
73 this material presence array and adds/removes materials based on
74 this array.
75 */
76 IMesh* mesh = m_material_mng->mesh();
77 if (!mesh->parallelMng()->isParallel())
78 return false;
79
80 auto* internal_pm = mesh->parallelMng()->_internalApi();
81
82 ConstArrayView<IMeshMaterial*> materials = m_material_mng->materials();
83 Integer nb_mat = materials.size();
84 Integer dim2_size = nb_mat / 8;
85 if ((nb_mat % 8) != 0)
86 ++dim2_size;
87 m_mat_presence.resize(dim2_size);
88
89 info(4) << "Resize presence variable nb_mat=" << nb_mat << " dim2=" << dim2_size;
90 CellToAllEnvCellConverter cell_converter = m_material_mng->cellToAllEnvCellConverter();
91
92 Arcane::Accelerator::RunQueue m_queue = internal_pm->queue();
93
94 m_queue.setAsync(true);
95 auto command = makeCommand(m_queue);
96
97 auto out_mat_presence = Arcane::Accelerator::viewInOut(command, m_mat_presence);
98 CellToAllEnvCellAccessor cell2allenvcell(m_material_mng);
99
100 m_idx_selecter.resize(mesh->allCells().size());
101
102 command << RUNCOMMAND_ENUMERATE_CELL_ALLENVCELL(cell2allenvcell, cid, mesh->ownCells())
103 {
104 AllEnvCell allenvcell{ cell_converter[cid] };
105
106 for (Integer dim2 = 0; dim2 < dim2_size; dim2++) {
107 out_mat_presence[cid][dim2] = 0;
108 }
109
110 ENUMERATE_CELL_ENVCELL (ienvcell, allenvcell) {
111 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
112 MatCell mc = *imatcell;
113 Integer mat_index = mc.materialId();
114 _setBit(out_mat_presence[cid][mat_index / 8], mat_index);
115 }
116 }
117 };
118
119 bool has_changed = false;
120 m_queue.barrier();
121
122 m_mat_presence.synchronize();
123 Arcane::ItemGenericInfoListView cells_info(mesh->cellFamily());
124 auto out_after_presence = out_mat_presence;
125
126 {
127 UniqueArray<ConstArrayView<Int32>> to_add(nb_mat);
128 UniqueArray<ConstArrayView<Int32>> to_remove(nb_mat);
129
130 MeshMaterialModifier modifier(m_material_mng);
131
132 for (Integer imat = 0; imat < nb_mat; ++imat) {
133
134 to_add[imat] = m_idx_selecter.syncSelectIf(m_queue, [=] ARCCORE_HOST_DEVICE(Int32 cid) -> bool {
135 if (cells_info.isOwn(cid))
136 return false;
137 CellLocalId c{ cid };
138 AllEnvCell allenvcell{ cell_converter[c] };
139 bool was_here = false;
140 ENUMERATE_CELL_ENVCELL (ienvcell, allenvcell) {
141 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
142 MatCell mc = *imatcell;
143 Integer mat_index = mc.materialId();
144
145 if (mat_index == imat) {
146 was_here = true;
147 }
148 }
149 }
150 if (was_here)
151 return false;
152 return _hasBit(out_after_presence[c][imat / 8], imat); },
153 /*host_view=*/false);
154
155 if (!to_add[imat].empty()) {
156 /*String s="[";
157 for(int u=0; u < to_add[imat].size(); u++){
158 s = s + to_add[imat][u] + ",";
159 }
160 s = s +"]";
161 pinfo() << "Materiau " << imat <<": " << to_add[imat].size() << " cellules ajoutées" << s << " adrr =" << to_add[imat];*/
162 modifier.addCells(materials[imat], to_add[imat]);
163 has_changed = true;
164 }
165
166 to_remove[imat] = m_idx_selecter.syncSelectIf(m_queue, [=] ARCCORE_HOST_DEVICE(Int32 cid) -> bool {
167 if (cells_info.isOwn(cid))
168 return false;
169 CellLocalId c{ cid };
170 AllEnvCell allenvcell{ cell_converter[c] };
171 bool was_here = false;
172 ENUMERATE_CELL_ENVCELL (ienvcell, allenvcell) {
173 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
174 MatCell mc = *imatcell;
175 Integer mat_index = mc.materialId();
176
177 if (mat_index == imat) {
178 was_here = true;
179 }
180 }
181 }
182 if (!was_here)
183 return false;
184 return !_hasBit(out_after_presence[c][imat / 8], imat); },
185 /*host_view=*/false);
186
187 if (!to_remove[imat].empty()) {
188 /*String s="[";
189 for(int u=0; u < to_remove[imat].size(); u++){
190 s = s + to_remove[imat][u] + ",";
191 }
192 s = s +"]";
193 pinfo() << "Materiau " << imat <<": " << to_remove[imat].size() << " cellules supprimées" << s;*/
194 modifier.removeCells(materials[imat], to_remove[imat]);
195 has_changed = true;
196 }
197 }
198 }
199
200 return has_changed;
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
206} // End namespace Arcane::Materials
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
void setAsync(bool v)
Sets the instance's asynchronous state.
Definition RunQueue.cc:299
void barrier() const
Blocks until all commands associated with the queue are finished.
Definition RunQueue.cc:159
View of the generic information of an entity family.
Interface for the material and environment manager of a mesh.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro to iterate over all MatCell cells of a cell.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro to iterate over all EnvCell cells of a cell.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
auto viewInOut(const ViewBuildInfo &vbi, CellMaterialVariableScalarRef< DataType > &var)
Read/write view for scalar material variables.
Always enables tracing in Arcane parts concerning materials.
Int32 Integer
Type representing an integer.