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