Arcane  v3.14.10.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-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
65 _dumpStats<IMesh>();
66}
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
70
73{
74 _dumpStats<IMesh>();
75}
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 IVariableSynchronizer * allItemsSynchronizer()=0
Synchroniseur sur toutes les entités de la famille.
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.
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.
virtual Int32ConstArrayView communicatingRanks()=0
Rangs des sous-domaines avec lesquels on communique.
static Integer nbBasicItemType()
nombre de types disponibles
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 Integer size() const noexcept
Nombre d'éléments du tableau.
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.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
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
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.