Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
AcceleratorMeshMaterialSynchronizerImpl.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* Synchronisation des entités des matériaux. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/AcceleratorMeshMaterialSynchronizerImpl.h"
15
16#include "arcane/VariableTypes.h"
17#include "arcane/IParallelMng.h"
18#include "arcane/ItemPrinter.h"
19#include "arcane/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->defaultRunner() == nullptr) {
46 internal_pm->setDefaultRunner(default_runner);
47 }
48 Arcane::Accelerator::RunQueue* m_queue = internal_pm->defaultQueue();
49 m_idx_selecter = Arcane::Accelerator::IndexSelecter(m_queue);
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58bool AcceleratorMeshMaterialSynchronizerImpl::
59synchronizeMaterialsInCells()
60{
61 /*
62 L'algorithme utilisé est le suivant:
63
64 On utilise une variable aux mailles qui utilise un bit pour chaque
65 matériau pour indiquer sa présence: si ce bit est positionné, le matériau
66 est présent, sinon il est absent. La variable utilisée est donc de type
67 ArrayByte aux mailles. Les méthodes _hasBit() et _setBit() permettent
68 de positionner le bit d'un matériau donné.
69
70 1. Le sous-domaine remplit cette variables pour ces mailles.
71 2. La variable est synchronisée.
72 3. Le sous-domaine compare pour chacune de ses mailles fantômes
73 ce tableau de présence des matériaux et ajoute/supprime les matériaux en fonction
74 de ce tableau.
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->defaultQueue();
93
94 m_queue->setAsync(true);
95 auto command = Arcane::Accelerator::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 },
154 /*host_view=*/false);
155
156 if (!to_add[imat].empty()) {
157 /*String s="[";
158 for(int u=0; u < to_add[imat].size(); u++){
159 s = s + to_add[imat][u] + ",";
160 }
161 s = s +"]";
162 pinfo() << "Materiau " << imat <<": " << to_add[imat].size() << " cellules ajoutées" << s << " adrr =" << to_add[imat];*/
163 modifier.addCells(materials[imat], to_add[imat]);
164 has_changed = true;
165 }
166
167 to_remove[imat] = m_idx_selecter.syncSelectIf(m_queue, [=] ARCCORE_HOST_DEVICE(Int32 cid) -> bool {
168 if (cells_info.isOwn(cid))
169 return false;
170 CellLocalId c{ cid };
171 AllEnvCell allenvcell{ cell_converter[c] };
172 bool was_here = false;
173 ENUMERATE_CELL_ENVCELL (ienvcell, allenvcell) {
174 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
175 MatCell mc = *imatcell;
176 Integer mat_index = mc.materialId();
177
178 if (mat_index == imat) {
179 was_here = true;
180 }
181 }
182 }
183 if (!was_here)
184 return false;
185 return !_hasBit(out_after_presence[c][imat / 8], imat);
186 },
187 /*host_view=*/false);
188
189 if (!to_remove[imat].empty()) {
190 /*String s="[";
191 for(int u=0; u < to_remove[imat].size(); u++){
192 s = s + to_remove[imat][u] + ",";
193 }
194 s = s +"]";
195 pinfo() << "Materiau " << imat <<": " << to_remove[imat].size() << " cellules supprimées" << s;*/
196 modifier.removeCells(materials[imat], to_remove[imat]);
197 has_changed = true;
198 }
199 }
200 }
201
202 return has_changed;
203}
204} // End namespace Arcane::Materials
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
File d'exécution pour un accélérateur.
void setAsync(bool v)
Positionne l'asynchronisme de l'instance.
Definition RunQueue.cc:292
void barrier() const
Bloque tant que toutes les commandes associées à la file ne sont pas terminées.
Definition RunQueue.cc:158
Gestionnaire d'exécution pour accélérateur.
Definition core/Runner.h:53
Vue sur les informations génériques d'une famille d'entités.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro pour itérer sur tous les matériaux d'une maille.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro pour itérer sur tous les milieux d'une maille.
auto viewInOut(RunCommand &cmd, CellMaterialVariableScalarRef< DataType > &var)
Vue en lecture/écriture pour les variables materiaux scalaire.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
@ Sequential
Politique d'exécution séquentielle.
Active toujours les traces dans les parties Arcane concernant les matériaux.
Int32 Integer
Type représentant un entier.