Arcane  4.1.11.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshStats.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/* MeshStats.cc (C) 2000-2026 */
9/* */
10/* Statistiques sur le maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "ArcaneTypes.h"
15#include "arcane/utils/StringBuilder.h"
16#include "arcane/utils/Collection.h"
17
18#include "arcane/core/MeshStats.h"
19#include "arcane/core/Item.h"
20#include "arcane/core/ItemGroup.h"
22#include "arcane/core/IMesh.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/IParallelMng.h"
25#include "arcane/core/IVariable.h"
26#include "arcane/core/IVariableMng.h"
27#include "arcane/core/ISubDomain.h"
28#include "arcane/core/StringDictionary.h"
29#include "arcane/core/VariableCollection.h"
30#include "arcane/core/IVariableSynchronizer.h"
31#include "arcane/core/MeshHandle.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43create(ITraceMng* trace, IMesh* mesh, IParallelMng* pm)
44{
45 return new MeshStats(trace, mesh, pm);
46}
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51MeshStats::
52MeshStats(ITraceMng* trace, IMesh* mesh, IParallelMng* pm)
53: TraceAccessor(trace)
54, m_mesh(mesh)
55, m_parallel_mng(pm)
56{
57}
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
64{
65 // Affichage du maillage
66 _dumpStats<IMesh>();
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
74{
75 _dumpStats<IMesh>();
76}
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81template <> void MeshStats::
82_computeElementsOnGroup<IMesh>(ArrayView<Int64> nb_type, Int64ArrayView nb_kind, Integer istat)
83{
84 _computeElementsOnGroup(nb_type, nb_kind, m_mesh->allNodes(), istat);
85 _computeElementsOnGroup(nb_type, nb_kind, m_mesh->allEdges(), istat);
86 _computeElementsOnGroup(nb_type, nb_kind, m_mesh->allFaces(), istat);
87 _computeElementsOnGroup(nb_type, nb_kind, m_mesh->allCells(), istat);
88}
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
92
93template <> void MeshStats::
94_statLabel<IMesh>(const String& name)
95{
96 info() << " -- MESH STATISTICS " << Trace::Width(8) << name
97 << " FOR " << m_mesh->name();
98}
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103template <typename T> void MeshStats::
104_dumpStats()
105{
106 Trace::Setter setter(traceMng(), "Mesh");
107
108 const Integer nb_type = m_mesh->itemTypeMng()->types().size();
109 const Integer nb_kind = NB_ITEM_KIND;
110
111 const char* name[3] = { "(All)", "(Own)", "(Ghost)" };
112
113 // Pour ne s'occuper de Own et Ghost que en parallèle
114 const Integer nstat = (m_parallel_mng->isParallel()) ? 3 : 1;
115
116 // On regroupe toutes les données dans la même communication
117 const Integer data_by_stat = nb_type + nb_kind;
118 const Integer all_data_count = nstat * data_by_stat;
119 Int64UniqueArray nb_data(all_data_count, 0);
120
121 // On remplit maintenant tout le tableau par bloc
122 for (Integer istat = 0; istat < nstat; ++istat) {
123 const Integer first_type = istat * data_by_stat;
124 const Integer first_kind = first_type + nb_type;
125 // Nombre d'éléments de chaque type sur ce sous-domaine.
126 Int64ArrayView nb_local_type = nb_data.view().subView(first_type, nb_type);
127 // Nombre d'éléments de chaque genre sur de sous-domaine
128 Int64ArrayView nb_local_kind = nb_data.view().subView(first_kind, nb_kind);
129 _computeElementsOnGroup<T>(nb_local_type, nb_local_kind, istat);
130 }
131
132 // Tableau résultat de synthèse
133 Int64UniqueArray nb_data_min(all_data_count, 0);
134 Int64UniqueArray nb_data_max(all_data_count, 0);
135 Int64UniqueArray nb_data_sum(all_data_count, 0);
136 Int32UniqueArray min_data_rank(all_data_count, 0);
137 Int32UniqueArray max_data_rank(all_data_count, 0);
138 m_parallel_mng->computeMinMaxSum(nb_data,
139 nb_data_min,
140 nb_data_max,
141 nb_data_sum,
142 min_data_rank,
143 max_data_rank);
144
145 // On vérifie s'il y a quelque chose à afficher
146 {
147 bool is_empty = true;
148 for (Integer istat = 0; istat < nstat; ++istat) {
149 const Integer first_type = istat * data_by_stat;
150 Int64ConstArrayView nb_global_type = nb_data_sum.subConstView(first_type, nb_type);
151 for (Integer i = 0; i < nb_global_type.size(); ++i)
152 if (nb_global_type[i] != 0) {
153 is_empty = false;
154 break;
155 }
156 if (!is_empty)
157 break;
158 }
159 if (is_empty)
160 return;
161 }
162
163 ItemTypeMng* type_mng = m_mesh->itemTypeMng();
164
165 // On produit maintenant l'affichage des stats
166 const Integer nb_rank = m_parallel_mng->commSize();
167 for (Integer istat = 0; istat < nstat; ++istat) {
168 // Construction des vues de travail décompactées
169 // (on reprend les noms des variables de la précédente version)
170 const Integer first_type = istat * data_by_stat;
171 const Integer first_kind = first_type + nb_type;
172
173 Int64ConstArrayView nb_local_type = nb_data.subConstView(first_type, nb_type);
174 Int64ConstArrayView nb_local_min_type = nb_data_min.subConstView(first_type, nb_type);
175 Int64ConstArrayView nb_local_max_type = nb_data_max.subConstView(first_type, nb_type);
176 Int64ConstArrayView nb_global_type = nb_data_sum.subConstView(first_type, nb_type);
177 Int32ConstArrayView min_rank_type = min_data_rank.subConstView(first_type, nb_type);
178 Int32ConstArrayView max_rank_type = max_data_rank.subConstView(first_type, nb_type);
179
180 Int64ConstArrayView nb_local_kind = nb_data.subConstView(first_kind, nb_kind);
181 Int64ConstArrayView nb_local_min_kind = nb_data_min.subConstView(first_kind, nb_kind);
182 Int64ConstArrayView nb_local_max_kind = nb_data_max.subConstView(first_kind, nb_kind);
183 Int64ConstArrayView nb_global_kind = nb_data_sum.subConstView(first_kind, nb_kind);
184 Int32ConstArrayView min_rank_kind = min_data_rank.subConstView(first_kind, nb_kind);
185 Int32ConstArrayView max_rank_kind = max_data_rank.subConstView(first_kind, nb_kind);
186
187 info() << " -------------------------------------------";
188 _statLabel<T>(name[istat]);
189
190 info() << Trace::Width(18) << "Item"
191 << Trace::Width(10) << "Myself"
192 << Trace::Width(10) << "Min"
193 << Trace::Width(8) << "Rank"
194 << Trace::Width(10) << "Max"
195 << Trace::Width(8) << "Rank"
196 << Trace::Width(10) << "Average"
197 << Trace::Width(10) << "Bal"
198 << Trace::Width(12) << "Total";
199
200 info() << " ";
201 for (Integer i = 0, s = nb_kind; i < s; ++i) {
202 eItemKind kt = static_cast<eItemKind>(i);
203 _printInfo(itemKindName(kt), nb_local_kind[i],
204 nb_local_min_kind[i], min_rank_kind[i],
205 nb_local_max_kind[i], max_rank_kind[i],
206 nb_global_kind[i], nb_rank);
207 // if (nb_global_kind[i]!=0) {
208 // pinfo() << "MeshStats ("<< m_parallel_mng->commRank() <<") : " << name[istat]
209 // << " kind=" << itemKindName(kt)
210 // << " n=" << nb_local_kind[i];
211 // plog() << "MeshStats ("<< m_parallel_mng->commRank() <<") : " << name[istat]
212 // << " kind=" << itemKindName(kt)
213 // << " n=" << nb_local_kind[i];
214 // }
215 }
216 info() << " ";
217 for (Integer i = 0, s = nb_type; i < s; ++i) {
218 _printInfo(type_mng->typeName(i), nb_local_type[i],
219 nb_local_min_type[i], min_rank_type[i],
220 nb_local_max_type[i], max_rank_type[i],
221 nb_global_type[i], nb_rank);
222 // if (nb_global_type[i]!=0)
223 // pinfo() << "MeshStats ("<< m_parallel_mng->commRank() <<") : " << name[istat]
224 // << " type=" << Item::typeName(i)
225 // << " n=" << nb_local_type[i];
226 }
227 info() << " ";
228 info() << " -------------------------------------------";
229 }
230 // _computeNeighboorsComm();
231
232 _dumpCommunicatingRanks();
233 _dumpLegacyConnectivityMemoryUsage();
234 _dumpIncrementalConnectivityMemoryUsage();
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240void MeshStats::
241_dumpLegacyConnectivityMemoryUsage()
242{
243 // Cette liste de nom est issue de mesh/ItemFamily.cc
244 UniqueArray<String> var_names = { "FamilyItemsData", "FamilyItemsShared" };
245 IVariableMng* vm = m_mesh->variableMng();
246 Real total_memory = 0.0;
247 for (IItemFamily* family : m_mesh->itemFamilies()) {
248 String name = family->name();
249 Real family_memory = 0.0;
250 info(4) << "Family name=" << family->name();
251 for (const String& s : var_names) {
252 IVariable* v = vm->findMeshVariable(m_mesh, name + s);
253 if (v) {
254 Real v_memory = v->allocatedMemory();
255 family_memory += v_memory;
256 info(4) << "Allocated Memory n=" << s << " v=" << v_memory;
257 }
258 }
259 info(4) << "Memory for family name=" << name << " mem=" << family_memory;
260 total_memory += family_memory;
261 }
262 info() << "Total memory for legacy connectivities mem=" << total_memory;
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
268void MeshStats::
269_dumpIncrementalConnectivityMemoryUsage()
270{
271 IVariableMng* vm = m_mesh->variableMng();
272 Real total_memory = 0.0;
273 VariableCollection used_variables = vm->usedVariables();
274 const String tag_name = "ArcaneConnectivity";
275 for (VariableCollection::Enumerator iv(used_variables); ++iv;) {
276 IVariable* v = *iv;
277 if (!v->hasTag(tag_name))
278 continue;
279 if (v->meshHandle().meshOrNull() == m_mesh) {
280 Real v_memory = v->allocatedMemory();
281 info(4) << "Allocated Memory n=" << v->name() << " v=" << v_memory;
282 total_memory += v_memory;
283 }
284 }
285 info() << "Total memory for incremental connectivities mem=" << total_memory;
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291void MeshStats::
292_printInfo(const String& name, Int64 nb_local,
293 Int64 nb_local_min, Integer min_rank,
294 Int64 nb_local_max, Integer max_rank,
295 Int64 nb_global, Integer nb_rank)
296{
297 if (nb_global == 0 && nb_local == 0)
298 return;
299
300 Int64 average = nb_global;
301 if (nb_rank != 0)
302 average /= nb_rank;
303 Real bal1 = (Real)(nb_local_max - average);
304 if (average != 0)
305 bal1 = bal1 / (Real)average;
306 Int64 bal = static_cast<Int64>(bal1 * 1000);
307 info() << Trace::Width(18) << name
308 << Trace::Width(10) << nb_local
309 << Trace::Width(10) << nb_local_min
310 << Trace::Width(8) << min_rank
311 << Trace::Width(10) << nb_local_max
312 << Trace::Width(8) << max_rank
313 << Trace::Width(10) << average
314 << Trace::Width(10) << bal
315 << Trace::Width(12) << nb_global;
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321void MeshStats::
322_computeElementsOnGroup(Int64ArrayView nb_type, Int64ArrayView nb_kind,
323 ItemGroup group, Integer istat)
324{
325 Int32 ik = static_cast<Int32>(group.itemKind());
326 ENUMERATE_ITEM (i, group) {
327 Item item = *i;
328 Int16 type = item.type();
329 if (istat == 0 || (istat == 1 && item.isOwn()) || (istat == 2 && !item.isOwn())) {
330 ++nb_kind[ik];
331 ++nb_type[type];
332 }
333 }
334}
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
338
339void MeshStats::
340_computeNeighboorsComm()
341{
342 Integer nb_proc = m_parallel_mng->commSize();
343 Int64UniqueArray vol_comm_out(nb_proc);
344 StringBuilder out = "";
345 vol_comm_out.fill(0);
346
347 ENUMERATE_ITEM (i, m_mesh->allCells()) {
348 Item item = *i;
349 if (item.isOwn())
350 continue;
351 vol_comm_out[item.owner()]++;
352 }
353
354 for (Integer i = 0; i < nb_proc; ++i) {
355 out += " ";
356 out += vol_comm_out[i];
357 }
358 pinfo() << "Comm Proc " << m_parallel_mng->commRank() << " : " << out;
359}
360
361/*---------------------------------------------------------------------------*/
362/*---------------------------------------------------------------------------*/
363
364void MeshStats::
365_dumpCommunicatingRanks()
366{
367 // Affiche les statistiques sur le nombre de sous-domaines avec
368 // lesquels on communique. On prend les voisins sur la liste des mailles.
369 IItemFamily* cell_family = m_mesh->cellFamily();
370 IVariableSynchronizer* sync_info = cell_family->allItemsSynchronizer();
371 Int64 nb_comm_local = sync_info->communicatingRanks().size();
372 Int32 nb_comm_min_rank = 0;
373 Int32 nb_comm_max_rank = 0;
374 Int64 nb_comm_max = 0;
375 Int64 nb_comm_min = 0;
376 Int64 nb_comm_sum = 0;
377 IParallelMng* pm = m_parallel_mng;
378 pm->computeMinMaxSum(nb_comm_local, nb_comm_min, nb_comm_max, nb_comm_sum,
379 nb_comm_min_rank, nb_comm_max_rank);
380 Int64 average = nb_comm_sum / pm->commSize();
381 info() << String::format("CommunicatingSubDomains: local={0}, min={1}, max={2}"
382 " average={3} min_rank={4} max_rank={5}",
383 nb_comm_local, nb_comm_min, nb_comm_max, average,
384 nb_comm_min_rank, nb_comm_max_rank);
385}
386
387/*---------------------------------------------------------------------------*/
388/*---------------------------------------------------------------------------*/
389
390} // namespace Arcane
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
Déclarations des types généraux de Arcane.
Types et macros pour itérer sur les entités du maillage.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Vue modifiable d'un tableau d'un type T.
constexpr ArrayView< T > subView(Integer abegin, Integer asize) noexcept
Sous-vue à partir de l'élément abegin et contenant asize éléments.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sous-vue (constante) à partir de l'élément abegin et contenant asize éléments.
virtual String name() const =0
Nom du maillage.
virtual FaceGroup allFaces()=0
Groupe de toutes les faces.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
virtual EdgeGroup allEdges()=0
Groupe de toutes les arêtes.
static IMeshStats * create(ITraceMng *trace, IMesh *mesh, IParallelMng *pm)
Création d'une instance par défaut.
Definition MeshStats.cc:43
Interface du gestionnaire de parallélisme pour un sous-domaine.
Interface du gestionnaire de traces.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
void dumpStats() override
Imprime des infos sur le maillage.
Definition MeshStats.cc:63
void dumpGraphStats() override
Imprime des infos sur le graphe du maillage.
Definition MeshStats.cc:73
Chaîne de caractères unicode.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:451
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:339
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:482
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:480
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:341
eItemKind
Genre d'entité de maillage.
std::int16_t Int16
Type entier signé sur 16 bits.
const char * itemKindName(eItemKind kind)
Nom du genre d'entité.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.