Arcane  v3.16.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
VerifierService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* VerifierService.cc (C) 2000-2025 */
9/* */
10/* Classe de base du service de vérification des données. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/VerifierService.h"
15
16#include "arcane/utils/List.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/OStringStream.h"
19
20#include "arcane/core/ServiceBuildInfo.h"
21#include "arcane/core/ISubDomain.h"
22#include "arcane/core/IVariable.h"
23#include "arcane/core/IParallelMng.h"
24#include "arcane/core/IVariableMng.h"
25#include "arcane/core/ArcaneException.h"
26#include "arcane/core/CommonVariables.h"
27#include "arcane/core/SerializeBuffer.h"
28#include "arcane/core/VariableCollection.h"
29#include "arcane/core/IMesh.h"
30#include "arcane/core/VariableComparer.h"
31
32#include <map>
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43VerifierService::
44VerifierService(const ServiceBuildInfo& sbi)
45: AbstractService(sbi)
46, m_sub_domain(sbi.subDomain())
47, m_service_info(sbi.serviceInfo())
48, m_file_name()
49{
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55IBase* VerifierService::
56serviceParent() const
57{
58 return m_sub_domain;
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64void VerifierService::
65_getVariables(VariableCollection variables,bool parallel_sequential)
66{
67 ISubDomain* sd = subDomain();
68 IParallelMng* pm_sd = sd->parallelMng();
69 IVariableMng* vm = sd->variableMng();
70 VariableCollection used_vars = vm->usedVariables();
71
72 for( VariableCollection::Enumerator i(used_vars); ++i; ){
73 IVariable* variable = *i;
74 if (parallel_sequential){
75 if (variable->property() & IVariable::PSubDomainDepend)
76 continue;
77 // Ne compare pas les variables tableaux lors des comparaisons parallèles/séquentielles
78 // car en général ces variables sont dépendantes du découpage.
79 if (variable->itemKind()==IK_Unknown)
80 continue;
81 // Ne compare pas les variables dont le maillage n'utilise pas le même
82 // parallelMng() que le sous-domaine. En effet, dans ce cas, il n'est pas possible
83 // de faire une vue séquentielle du maillage.
84 MeshHandle mesh_handle = variable->meshHandle();
85 if (mesh_handle.hasMesh()){
86 IMesh* mesh = mesh_handle.mesh();
87 if (mesh->parallelMng()!=pm_sd)
88 continue;
89 }
90 }
91 if (variable->property() & IVariable::PExecutionDepend)
92 continue;
93 variables.add(variable);
94 }
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100template<typename ReaderType> void VerifierService::
101_doVerif2(ReaderType reader,const VariableList& variables,bool compare_ghost)
102{
103 ISubDomain* sd = subDomain();
104 IParallelMng* pm = sd->parallelMng();
105 ITraceMng* trace = sd->traceMng();
106
107 OStringStream not_compared_str;
108 Integer nb_not_compared =0;
109 Integer nb_compared = 0;
110
111 typedef std::map<String,DiffInfo> MapDiffInfos;
112 typedef std::map<String,DiffInfo>::value_type MapDiffInfosValues;
113 MapDiffInfos diff_infos;
114 VariableComparer variable_comparer;
115 VariableComparerArgs compare_args = variable_comparer.buildForCheckIfSame(reader);
116 compare_args.setMaxPrint(10);
117 compare_args.setComputeDifferenceMethod(m_compute_diff_method);
118 compare_args.setCompareGhost(compare_ghost);
119 {
120 for( VariableList::Enumerator i(variables); ++i; ){
121 IVariable* variable = *i;
122 Integer nb_diff = 0;
123 String var_name(variable->name());
124 try
125 {
126 VariableComparerResults r = variable_comparer.apply(variable, compare_args);
127 nb_diff = r.nbDifference();
128 ++nb_compared;
129 }
130 catch(const ReaderWriterException& rw)
131 {
132 OStringStream ostr;
133 rw.explain(ostr());
134 trace->pinfo() << "Impossible to compare the variable '" << var_name << "'\n"
135 << "(Exception: " << ostr.str() << ")";
136 not_compared_str() << ' ' << var_name;
137 ++nb_not_compared;
138 }
139 diff_infos.insert(MapDiffInfosValues(var_name,DiffInfo(var_name,nb_diff)));
140 }
141 }
142 if (nb_not_compared!=0){
143 trace->warning() << "Impossible to compare " << nb_not_compared << " variable(s): "
144 << not_compared_str.str();
145 }
146 if (nb_compared==0){
147 trace->pfatal() << "No variable has been compared";
148 }
149 Int32 sid = pm->commRank();
150 Int32 nb_sub_domain = pm->commSize();
151 bool is_master = sid==0;
152
153 if (is_master){
154
155 for( Integer i=0; i<nb_sub_domain; ++i ){
156 if (i==sid)
157 continue;
158 SerializeBuffer sbuf;
159 pm->recvSerializer(&sbuf,i);
160 sbuf.setMode(ISerializer::ModeGet);
161
162 {
163 Int64 n = sbuf.getInt64();
164 String var_name;
165 for( Integer z=0; z<n; ++z ){
166 Int64 nb_var_diff = sbuf.getInt64();
167 sbuf.get(var_name);
168 String uvar_name(var_name);
169 trace->debug() << "RECEIVE: "
170 << " varname=" << var_name
171 << " nbdiff=" << nb_var_diff;
172 auto i_map = diff_infos.find(uvar_name);
173 if (i_map==diff_infos.end()){
174 diff_infos.insert(MapDiffInfosValues(uvar_name,DiffInfo(uvar_name,nb_var_diff)));
175 }
176 else
177 i_map->second.m_nb_diff += nb_var_diff;
178 }
179 }
180 }
181 }
182 else{
183 SerializeBuffer sbuf;
184 Int64 nb_diff = diff_infos.size();
185 sbuf.setMode(ISerializer::ModeReserve);
186 sbuf.reserve(DT_Int64,1); // pour la taille
187 for (auto& i_map : diff_infos) {
188 const DiffInfo& diff_info = i_map.second;
189 sbuf.reserve(DT_Int64,1);
190 sbuf.reserve(diff_info.m_variable_name);
191 }
192 sbuf.allocateBuffer();
193 sbuf.setMode(ISerializer::ModePut);
194 sbuf.putInt64(nb_diff);
195 for (auto& i_map : diff_infos) {
196 const DiffInfo& diff_info = i_map.second;
197 Int64 n = diff_info.m_nb_diff;
198 sbuf.putInt64(n);
199 sbuf.put(diff_info.m_variable_name);
200 }
201 pm->sendSerializer(&sbuf,0);
202 }
203
204 pm->barrier();
205
206 if (is_master){
207 Int64 total_nb_diff = 0;
208 for (auto& diff_info : diff_infos)
209 total_nb_diff += diff_info.second.m_nb_diff;
210
211 if (!m_result_file_name.empty()){
212 const CommonVariables& vc = subDomain()->commonVariables();
213 std::ofstream result_file(m_result_file_name.localstr());
214 result_file << "<?xml version='1.0'?>\n";
215 result_file << "<compare-results"
216 << " version='1.0'"
217 << " total-nb-diff='" << total_nb_diff << "'"
218 << " global-iteration='" << vc.globalIteration() << "'"
219 << " global-time='" << vc.globalTime() << "'"
220 << ">\n";
221 for (auto& i_map : diff_infos) {
222 const DiffInfo& diff_info = i_map.second;
223 result_file << " <variable>\n"
224 << " <name>" << diff_info.m_variable_name << "</name>\n"
225 << " <nb-diff>" << diff_info.m_nb_diff << "</nb-diff>\n"
226 << " </variable>\n";
227 }
228 result_file << "</compare-results>\n";
229 }
230 if (total_nb_diff!=0){
231 trace->error() << "Some differences exist (N=" << total_nb_diff << ") with the reference file";
232 }
233 else{
234 trace->info() << "No difference with the reference !";
235 }
236
237 }
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243void VerifierService::
244_doVerif(IDataReader* reader,const VariableList& variables,bool compare_ghost)
245{
246 _doVerif2(reader,variables,compare_ghost);
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252} // End namespace Arcane
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
Classe de base d'un service.
Interface de la classe de base des objets principaux arcane.
Definition IBase.h:38
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void barrier()=0
Effectue une barière.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual IVariableMng * variableMng()=0
Retourne le gestionnaire de variables.
Interface du gestionnaire de traces.
virtual TraceMessage warning()=0
Flot pour un message d'avertissement.
virtual TraceMessage pfatal()=0
Flot pour un message d'erreur fatale parallèle.
virtual TraceMessage pinfo()=0
Flot pour un message d'information parallèle.
virtual TraceMessage error()=0
Flot pour un message d'erreur.
virtual TraceMessage info()=0
Flot pour un message d'information.
virtual TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium)=0
Flot pour un message de debug.
Interface du gestionnaire de variables.
virtual VariableCollection usedVariables()=0
Liste des variables utilisées.
Interface d'une variable.
Definition IVariable.h:56
@ PSubDomainDepend
Indique que la valeur de la variable est dépendante du sous-domaine.
Definition IVariable.h:93
@ PExecutionDepend
Indique que la valeur de la variable est dépendante de l'exécution.
Definition IVariable.h:108
virtual int property() const =0
Retourne les propriétés de la variable.
virtual eItemKind itemKind() const =0
Type des entités du maillage sur lequel repose la variable.
virtual MeshHandle meshHandle() const =0
Maillage auquel est associé la variable.
virtual String name() const =0
Nom de la variable.
Handle sur un maillage.
Definition MeshHandle.h:47
bool hasMesh() const
Indique si le maillage associé a déjà été créé (i.e: mesh() est valide)
IMesh * mesh() const
Maillage associé.
Flot de sortie lié à une String.
Structure contenant les informations pour créer un service.
Chaîne de caractères unicode.
Collection de variables.
Arguments des méthodes de VariableComparer.
void setMaxPrint(Int32 v)
Positionne le nombre d'erreurs à afficher dans le listing.
void setCompareGhost(bool v)
Indique sur quelles entités on fait la comparaison.
Résultats d'une opération de comparaison.
Classe pour effectuer des comparaisons entre les variables.
VariableComparerResults apply(IVariable *var, const VariableComparerArgs &compare_args)
Applique la comparaison compare_args à la variable var.
VariableComparerArgs buildForCheckIfSame(IDataReader *data_reader)
Créé une comparaison pour vérifie qu'une variable est identique à une valeur de référence.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé