14#include "arcane/impl/internal/VariableMng.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/IObservable.h"
18#include "arcane/utils/ScopedPtr.h"
19#include "arcane/utils/StringBuilder.h"
20#include "arcane/utils/MD5HashAlgorithm.h"
21#include "arcane/utils/SHA1HashAlgorithm.h"
22#include "arcane/utils/JSONWriter.h"
23#include "arcane/utils/ValueConvert.h"
25#include "arcane/core/IDataWriter.h"
26#include "arcane/core/IXmlDocumentHolder.h"
27#include "arcane/core/DomUtils.h"
28#include "arcane/core/XmlNode.h"
29#include "arcane/core/VariableMetaData.h"
30#include "arcane/core/IData.h"
31#include "arcane/core/IMesh.h"
32#include "arcane/core/Properties.h"
33#include "arcane/core/Timer.h"
34#include "arcane/core/ICheckpointWriter.h"
35#include "arcane/core/IPostProcessorWriter.h"
36#include "arcane/core/internal/IDataInternal.h"
38#include "arcane/core/ISubDomain.h"
39#include "arcane/core/IParallelMng.h"
55 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_VARIABLEMNG_HASHV2",
true))
56 m_use_hash_v2 = (v.value() != 0);
65void VariableIOWriterMng::
66writeCheckpoint(ICheckpointWriter* service)
71 Trace::Setter mci(traceMng(), _msgClassName());
73 Timer::Phase tp(m_variable_mng->m_time_stats, TP_InputOutput);
75 CheckpointSaveFilter save_filter;
77 service->notifyBeginWrite();
78 IDataWriter* data_writer = service->dataWriter();
81 writeVariables(data_writer, &save_filter,
true);
82 service->notifyEndWrite();
88void VariableIOWriterMng::
89writePostProcessing(IPostProcessorWriter* post_processor)
91 Trace::Setter mci(traceMng(), _msgClassName());
96 Timer::Phase tp(m_variable_mng->m_time_stats, TP_InputOutput);
98 post_processor->notifyBeginWrite();
99 VariableCollection variables(post_processor->variables());
100 IDataWriter* data_writer = post_processor->dataWriter();
103 writeVariables(data_writer, variables,
false);
104 post_processor->notifyEndWrite();
110void VariableIOWriterMng::
111writeVariables(IDataWriter* writer, IVariableFilter* filter,
bool use_hash)
113 Trace::Setter mci(traceMng(), _msgClassName());
120 for (
const auto& i : m_variable_mng->m_full_name_variable_map) {
121 IVariable* var = i.second;
122 bool apply_var =
true;
124 apply_var = filter->applyFilter(*var);
128 _writeVariables(writer, vars, use_hash);
136void VariableIOWriterMng::
142 VariableList var_array;
143 for (
const auto& i : m_variable_mng->m_full_name_variable_map) {
147 _writeVariables(writer, var_array, use_hash);
150 _writeVariables(writer, vars, use_hash);
161 json_writer.write(name, value);
163 void _writeAttribute(JSONWriter& json_writer, XmlNode var_node,
const String& name, Int32 value)
166 var_node.setAttrValue(name, String::fromNumber(v));
167 json_writer.write(name, v);
169 void _writeAttribute(JSONWriter& json_writer, XmlNode var_node,
const String& name,
bool value)
171 var_node.setAttrValue(name, String::fromNumber(value));
172 json_writer.write(name, value);
180void VariableIOWriterMng::
181_generateVariablesMetaData(JSONWriter& json_writer, XmlNode variables_node,
182 const VariableCollection& vars, IHashAlgorithm* hash_algo)
184 StringBuilder var_full_type_b;
186 Ref<IHashAlgorithmContext> hash_context;
188 SHA1HashAlgorithm sha1_hash_algo;
189 hash_context = sha1_hash_algo.createContext();
192 json_writer.writeKey(
"variables");
193 json_writer.beginArray();
195 for (VariableCollection::Enumerator i(vars); ++i;) {
196 JSONWriter::Object o(json_writer);
198 Ref<VariableMetaData> vmd(var->createMetaDataRef());
199 String var_full_type = vmd->fullType();
200 String var_family_name = var->itemFamilyName();
201 String var_mesh_name = var->meshName();
202 XmlNode var_node = XmlElement(variables_node,
"variable");
203 _writeAttribute(json_writer, var_node,
"base-name", var->name());
204 if (!var_family_name.null())
205 _writeAttribute(json_writer, var_node,
"item-family-name", var_family_name);
206 if (var->isPartial())
207 _writeAttribute(json_writer, var_node,
"item-group-name", var->itemGroupName());
208 if (!var_mesh_name.null())
209 _writeAttribute(json_writer, var_node,
"mesh-name", var_mesh_name);
210 _writeAttribute(json_writer, var_node,
"full-type", var_full_type);
211 _writeAttribute(json_writer, var_node,
"data-type", String(
dataTypeName(var->dataType())));
212 _writeAttribute(json_writer, var_node,
"dimension", var->dimension());
213 _writeAttribute(json_writer, var_node,
"multi-tag", var->multiTag());
214 _writeAttribute(json_writer, var_node,
"property", var->property());
217 if (var->property() & IVariable::PDumpNull)
218 var->data()->cloneEmptyRef()->computeHash(hash_algo, hash_values);
220 var->data()->computeHash(hash_algo, hash_values);
221 String hash_str = Convert::toHexaString(hash_values);
222 _writeAttribute(json_writer, var_node,
"hash", hash_str);
223 if (hash_context.get()) {
224 hash_context->reset();
225 DataHashInfo hash_info(hash_context.get());
226 if (var->property() & IVariable::PDumpNull)
227 var->data()->cloneEmptyRef()->_commonInternal()->computeHash(hash_info);
229 var->data()->_commonInternal()->computeHash(hash_info);
230 HashAlgorithmValue hash_value;
231 hash_context->computeHashValue(hash_value);
232 String hash2_str = Convert::toHexaString(
asBytes(hash_value.bytes()));
233 info(6) <<
"Hash=" << hash2_str <<
" old_hash="
234 << hash_str <<
" name=" << var->name();
235 _writeAttribute(json_writer, var_node,
"hash2", hash2_str);
236 _writeAttribute(json_writer, var_node,
"hash-version", hash_info.version());
241 json_writer.endArray();
250void VariableIOWriterMng::
256 json_writer.writeKey(
"meshes");
257 json_writer.beginArray();
265 for (
Integer i = 0, n = meshes.
size(); i < n; ++i) {
267 bool do_dump =
mesh->properties()->getBool(
"dump");
269 if (do_dump ||
mesh == default_mesh) {
272 _writeAttribute(json_writer, mesh_node,
"name",
mesh->name());
273 _writeAttribute(json_writer, mesh_node,
"factory-name",
mesh->factoryName());
280 if (is_parallel &&
mesh->parallelMng() == seq_pm)
281 _writeAttribute(json_writer, mesh_node,
"sequential",
true);
285 json_writer.endArray();
291String VariableIOWriterMng::
294 JSONWriter json_writer(JSONWriter::FormatFlags::None);
297 XmlNode doc_node = doc->documentNode();
298 XmlElement root_element(doc_node,
"arcane-checkpoint-metadata");
299 XmlElement variables_node(root_element,
"variables");
303 json_writer.write(
"version",
static_cast<Int64>(1));
305 json_writer.write(
"hash-algorithm-name", hash_algo->
name());
306 _generateVariablesMetaData(json_writer, variables_node, vars, hash_algo);
307 XmlElement meshes_node(root_element,
"meshes");
308 _generateMeshesMetaData(json_writer, meshes_node);
312 XmlElement json_node(root_element,
"json", json_writer.getBuffer());
314 String s = doc->save();
315 info(6) <<
"META_DATA=" << s;
322void VariableIOWriterMng::
323_writeVariables(IDataWriter* writer,
const VariableCollection& vars,
bool use_hash)
328 m_variable_mng->m_write_observable->notifyAllObservers();
329 writer->beginWrite(vars);
335 for (VariableCollection::Enumerator i(vars); ++i;) {
338 var->notifyBeginWrite();
341 MD5HashAlgorithm md5_hash_algo;
342 SHA1HashAlgorithm sha1_hash_algo;
343 IHashAlgorithm* hash_algo = &md5_hash_algo;
345 hash_algo = &sha1_hash_algo;
348 String meta_data = _generateMetaData(vars, hash_algo);
349 writer->setMetaData(meta_data);
351 for (VariableCollection::Enumerator i(vars); ++i;) {
356 if (var->property() & (IVariable::PDumpNull))
357 writer->write(var, var->data()->cloneEmptyRef().get());
359 writer->write(var, var->data());
361 catch (
const Exception& ex) {
362 error() <<
"Exception Arcane while VariableMng::writeVariables()"
363 <<
" var=" << var->fullName()
364 <<
" exception=" << ex;
367 catch (
const std::exception& ex) {
368 error() <<
"Exception while VariableMng::writeVariables()"
369 <<
" var=" << var->fullName()
370 <<
" exception=" << ex.what();
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface d'écriture des données d'une variable.
Interface d'un algorithme de hashage.
virtual String name() const
Nom de l'algorithme.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual IParallelMng * sequentialParallelMng()=0
Retourne un gestionnaire de parallélisme séquentiel.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
Interface du gestionnaire d'un sous-domaine.
virtual IMesh * defaultMesh()=0
Maillage par défaut.
virtual ConstArrayView< IMesh * > meshes() const =0
Listes des maillages du sous-domaine.
Interface d'une variable.
Encapsulation d'un pointeur qui se détruit automatiquement.
Chaîne de caractères unicode.
Classe d'accès aux traces.
Gestionnaire de variables.
void setAttrValue(const String &name, const String &value)
Positionne l'attribut name à la valeur value.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets non modifiables.
const char * dataTypeName(eDataType type)
Nom du type de donnée.