Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialSyncUnitTest.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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/* MeshMaterialSyncUnitTest.cc (C) 2000-2023 */
9/* */
10/* Service de test de la synchronisation des matériaux. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/OStringStream.h"
15
16#include "arcane/core/BasicUnitTest.h"
17#include "arcane/core/ItemPrinter.h"
18#include "arcane/core/IMesh.h"
19
20#include "arcane/accelerator/core/IAcceleratorMng.h"
21#include "arcane/accelerator/core/RunQueue.h"
22
23#if defined(ARCANE_HAS_ACCELERATOR_API)
25#include "arcane/accelerator/MaterialVariableViews.h"
27#endif
28
29#include "arcane/materials/IMeshMaterialMng.h"
30#include "arcane/materials/MeshMaterialInfo.h"
31#include "arcane/materials/MeshEnvironmentBuildInfo.h"
32#include "arcane/materials/MeshMaterialModifier.h"
33#include "arcane/materials/MatItemEnumerator.h"
34#include "arcane/materials/MeshMaterialVariableRef.h"
35#include "arcane/materials/MaterialVariableBuildInfo.h"
36#include "arcane/materials/MeshMaterialVariableSynchronizerList.h"
37
38#include "arcane/tests/ArcaneTestGlobal.h"
39#include "arcane/tests/MeshMaterialSyncUnitTest_axl.h"
40
41#include <set>
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46namespace ArcaneTest
47{
48
49using namespace Arcane;
50using namespace Arcane::Materials;
51namespace ax = Arcane::Accelerator;
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
59: public ArcaneMeshMaterialSyncUnitTestObject
60{
61 public:
62
64
65 public:
66
67 void initializeTest() override;
68 void executeTest() override;
69
70 private:
71
72 IMeshMaterialMng* m_material_mng;
73 VariableCellByte m_variable_is_own_cell;
74 VariableCellInt64 m_cell_unique_ids;
75 MaterialVariableCellInt64 m_material_uids;
76
77 void _checkVariableSync1();
78 void _doPhase1();
79 void _doPhase2();
80
81 public:
82
83#if defined(ARCANE_HAS_ACCELERATOR_API)
84 void _checkVariableSync2(bool do_check,Int32 iteration);
85#endif
86};
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91MeshMaterialSyncUnitTest::
92MeshMaterialSyncUnitTest(const ServiceBuildInfo& sbi)
93: ArcaneMeshMaterialSyncUnitTestObject(sbi)
94, m_material_mng(IMeshMaterialMng::getReference(sbi.mesh()))
95, m_variable_is_own_cell(VariableBuildInfo(sbi.meshHandle(),"CellIsOwn"))
96, m_cell_unique_ids(VariableBuildInfo(sbi.meshHandle(),"CellUniqueId"))
97, m_material_uids(MaterialVariableBuildInfo(m_material_mng,"SyncMaterialsUid"))
98{
99}
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
107void MeshMaterialSyncUnitTest::
108initializeTest()
109{
110 IMeshMaterialMng* mm = m_material_mng;
111 Integer nb_mat = options()->nbMaterial();
112 info() << "Number of wanted materials: " << nb_mat;
113
114 // Lit les infos des matériaux du JDD et les enregistre dans le gestionnaire
115 for( Integer i=0; i<nb_mat; ++i ){
116 String mat_name = String("MAT_") + String::fromNumber(i);
117 mm->registerMaterialInfo(mat_name);
118 }
119
120 // Créé des milieux en fonction du nombre de matériaux du jeu de données.
121 {
122 Integer env_index = 1;
123 Integer mat_index = 0;
124
125 while(mat_index<nb_mat){
126 String env_name = "ENV_" + String::fromNumber(env_index);
128 // Utilise un std::set pour être sur qu'on n'ajoute pas 2 fois le même matériau.
129 std::set<String> mats_in_env;
130 for( Integer z=0; z<=env_index; ++z ){
131 String mat1_name = "MAT_" + String::fromNumber(mat_index);
132 mats_in_env.insert(mat1_name);
133 // Ajoute aussi des matériaux qui sont dans les milieux précédents
134 // pour être sur d'avoir des matériaux qui appartiennent à plusieurs milieux.
135 String mat2_name = "MAT_" + String::fromNumber(mat_index/2);
136 mats_in_env.insert(mat2_name);
137
138 ++mat_index;
139 if (mat_index>=nb_mat)
140 break;
141 }
142 for( String mat_name : mats_in_env ){
143 info() << "Add material " << mat_name << " for environment " << env_name;
144 env_build.addMaterial(mat_name);
145 }
146 mm->createEnvironment(env_build);
147 ++env_index;
148 }
149
150 mm->endCreate(false);
151 }
152}
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
156
157void MeshMaterialSyncUnitTest::
158executeTest()
159{
160 _doPhase1();
161
162 {
164 m_material_mng->dumpInfos(ostr());
165 info() << ostr.str();
166 }
167
168 _doPhase2();
169}
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
173
174void MeshMaterialSyncUnitTest::
175_doPhase1()
176{
177 // Cette phase se fait juste après l'init donc on a déjà créé les
178 // matériaux mais on n'a pas encore de mailles dedans.
179
180 // Ajoute des mailles dans les matériaux.
181 // Pour tester la synchronisation, on n'ajoute que des matériaux aux
182 // mailles propres. Ainsi, il faudra que quelqu'un nous envoie les
183 // informations pour les mailles fantômes.
184
185 IMeshMaterialMng* mm = m_material_mng;
186 Integer nb_mat = options()->nbMaterial();
187
188 {
189 CellGroup cells = ownCells();
190 MeshMaterialModifier mmodifier(m_material_mng);
192 // TODO: calculer en fonction du max des uid.
193 for( Integer imat=0; imat<nb_mat; ++imat ){
194 ids.clear();
195 Int64 min_uid = imat*10;
196 Int64 max_uid = min_uid + 10 + imat*10;
197 ENUMERATE_CELL(icell,cells){
198 Cell cell = *icell;
199 Int64 uid = cell.uniqueId();
201 ids.add(cell.localId());
202 }
203 info() << "Adding cells n=" << ids.size() << " to mat " << imat << " (min_uid="
204 << min_uid << " max_uid=" << max_uid << ")";
205 mmodifier.addCells(mm->materials()[imat],ids);
206 }
207 }
208
209 m_material_mng->synchronizeMaterialsInCells();
210 m_material_mng->checkMaterialsInCells();
211 _checkVariableSync1();
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217void MeshMaterialSyncUnitTest::
218_doPhase2()
219{
220 info() << "Begin phase2";
221 IMeshMaterialMng* mm = m_material_mng;
222 Integer nb_mat = options()->nbMaterial();
223 // Cette phase doit se faire après la phase1 et supprime
224 // des mailles qui ont été ajoutées dans la phase 1.
225
226 // Ajoute et supprime des mailles dans les matériaux.
227 // Pour tester la synchronisation, on ne travaille que sur
228 // les mailles dont on est propriétaires. Ainsi, il faudra que
229 // quelqu'un nous envoie les informations pour les mailles fantômes.
230 {
231 CellGroup cells = ownCells();
232 MeshMaterialModifier mmodifier(m_material_mng);
235 // TODO: calculer en fonction du max des uid.
236 for( Integer imat=0; imat<nb_mat; ++imat ){
237 remove_ids.clear();
238 add_ids.clear();
241
243 Int64 max_uid = min_uid + 20 + imat*5;
244 ENUMERATE_CELL(icell,cells){
245 Cell cell = *icell;
246 Int64 uid = cell.uniqueId();
248 remove_ids.add(cell.localId());
250 add_ids.add(cell.localId());
251 }
252 info() << "Adding cells n=" << add_ids.size() << " to mat " << imat << " (min_uid="
253 << min_uid << " max_uid=" << max_uid << ")";
254 info() << "Removing cells n=" << remove_ids.size() << " to mat " << imat << " (min_uid="
255 << phase1_min_uid << " max_uid=" << phase1_max_uid << ")";
256 IMeshMaterial* mat = mm->materials()[imat];
257 mmodifier.removeCells(mat,remove_ids);
258 mmodifier.addCells(mat,add_ids);
259 }
260 }
261
262 m_material_mng->synchronizeMaterialsInCells();
263 m_material_mng->checkMaterialsInCells();
264 _checkVariableSync1();
265 m_variable_is_own_cell.fill(0);
266 ENUMERATE_(Cell,icell,ownCells()){
267 m_variable_is_own_cell[icell] = 1;
268 }
269 ENUMERATE_(Cell,icell,allCells()){
270 Cell cell = *icell;
271 m_cell_unique_ids[cell] = cell.uniqueId();
272 }
273
274#if defined(ARCANE_HAS_ACCELERATOR_API)
275 for( int i=0; i<10; ++i )
276 _checkVariableSync2(false,i);
277 _checkVariableSync2(true,5);
278#endif
279}
280
281/*---------------------------------------------------------------------------*/
282/*---------------------------------------------------------------------------*/
283
284void MeshMaterialSyncUnitTest::
285_checkVariableSync1()
286{
287 // Vérifie que la synchronisation des variables marche bien
288 MaterialVariableCellInt32 mat_indexes(MaterialVariableBuildInfo(m_material_mng,"SyncMatIndexes"));
289
290 ENUMERATE_ALLENVCELL(iallenvcell,m_material_mng,ownCells()){
295 mat_indexes[mc] = mc.materialId() + 1;
296 }
297 }
298 }
299
300 mat_indexes.synchronize();
301
302 Integer nb_error = 0;
303 ENUMERATE_ALLENVCELL(iallenvcell,m_material_mng,allCells()){
308 if (mat_indexes[mc] != (mc.materialId() + 1)){
309 ++nb_error;
310 if (nb_error<10)
311 error() << "VariableSync error mat=" << mc.materialId()
312 << " mat_index=" << mat_indexes[mc]
313 << " cell=" << ItemPrinter(mc.globalCell());
314 }
315 }
316 }
317 }
318 if (nb_error!=0)
319 ARCANE_FATAL("Bad variable synchronization nb_error={0}",nb_error);
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
325#if defined(ARCANE_HAS_ACCELERATOR_API)
326void MeshMaterialSyncUnitTest::
327_checkVariableSync2(bool do_check,Int32 iteration)
328{
329 // TODO: Faire aussi avec les matériaux lorsqu'ils seront disponibles
330 // TODO: Ne pas mettre la même valeur dans chaque maille milieu/matériau (faire un offset du uid)
331 Arcane::Accelerator::RunQueue* queue = subDomain()->acceleratorMng()->defaultQueue();
332
333 // Vérifie que la synchronisation des variables marche bien
334
335 ENUMERATE_ENV(ienv, m_material_mng) {
337 EnvCellVectorView envcellsv = env->envView();
338 auto cmd = makeCommand(queue);
339 auto out_mat_uids = viewOut(cmd, m_material_uids);
340 auto in_is_own_cell = ax::viewIn(cmd, m_variable_is_own_cell);
341 auto in_cell_uids = ax::viewIn(cmd, m_cell_unique_ids);
343 auto [mvi, cid] = evi();
344 if (in_is_own_cell[cid]==1){
346 }
347 };
348 }
349
350 // Avec la version 7 des synchronisations, on teste une fois sur deux la version
351 // non bloquante.
352 if ((iteration%2)==0 && m_material_mng->synchronizeVariableVersion()==7){
354 m_material_uids.synchronize(vlist);
355 vlist.beginSynchronize();
356 vlist.endSynchronize();
357 }
358 else
359 m_material_uids.synchronize();
360
361 if (!do_check)
362 return;
363
364 Integer nb_error = 0;
365 ENUMERATE_ALLENVCELL(iallenvcell,m_material_mng,allCells()){
369 Cell global_cell = mc.globalCell();
370 if (m_material_uids[mc] != global_cell.uniqueId()){
371 ++nb_error;
372 if (nb_error<10)
373 error() << "VariableSync error mat=" << mc
374 << " uid_value=" << m_material_uids[mc]
375 << " cell=" << ItemPrinter(mc.globalCell());
376 }
377 }
378 }
379 if (nb_error!=0)
380 ARCANE_FATAL("Bad variable synchronization nb_error={0}",nb_error);
381}
382#endif
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
387ARCANE_REGISTER_SERVICE_MESHMATERIALSYNCUNITTEST(MeshMaterialSyncUnitTest,
388 MeshMaterialSyncUnitTest);
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
Types et macros pour gérer les énumérations des matériaux et milieux sur les accélérateurs.
#define RUNCOMMAND_MAT_ENUMERATE(MatItemNameType, iter_name, env_or_mat_vector,...)
Macro pour itérer sur un matériau ou un milieu.
Module de test pour la gestion des matériaux et des milieux.
File d'exécution pour un accélérateur.
Maille d'un maillage.
Definition Item.h:1178
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Maille arcane avec info matériaux et milieux.
Maille arcane d'un milieu.
Vue sur un vecteur sur les entités d'un milieu.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
virtual void dumpInfos(std::ostream &o)=0
Ecrit les infos des matériaux et milieux sur le flot o.
virtual void checkMaterialsInCells(Integer max_print=10)=0
Vérifie que les mailles des matériaux sont cohérentes entre les sous-domaines.
virtual Integer synchronizeVariableVersion() const =0
Version de l'implémentation pour la synchronisation des variables matériaux.
virtual bool synchronizeMaterialsInCells()=0
Synchronise les mailles des matériaux.
Interface d'un matériau d'un maillage.
Représente un matériau d'une maille multi-matériau.
Informations pour la création d'un milieu.
Objet permettant de modifier les matériaux ou les milieux.
void synchronize()
Synchronise les valeurs entre les sous-domaines.
Flot de sortie lié à une String.
Structure contenant les informations pour créer un service.
Paramètres nécessaires à la construction d'une variable.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
#define ENUMERATE_ENV(ienv, container)
Macro pour itérer sur une liste de milieux.
#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.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro pour itérer sur toutes les mailles AllEnvCell d'un groupe.
Espace de nom pour l'utilisation des accélérateurs.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
auto viewIn(RunCommand &cmd, const CellMaterialVariableScalarRef< DataType > &var)
Vue en lecture pour les variables materiaux scalaire.
auto viewOut(RunCommand &cmd, CellMaterialVariableScalarRef< DataType > &var)
Vue en écriture pour les variables materiaux scalaire.
Active toujours les traces dans les parties Arcane concernant les matériaux.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.