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