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);
137void VariableIOWriterMng::
143 VariableList var_array;
144 for (
const auto& i : m_variable_mng->m_full_name_variable_map) {
148 _writeVariables(writer, var_array, use_hash);
151 _writeVariables(writer, vars, use_hash);
162 json_writer.write(name, value);
164 void _writeAttribute(JSONWriter& json_writer, XmlNode var_node,
const String& name, Int32 value)
167 var_node.setAttrValue(name, String::fromNumber(v));
168 json_writer.write(name, v);
170 void _writeAttribute(JSONWriter& json_writer, XmlNode var_node,
const String& name,
bool value)
172 var_node.setAttrValue(name, String::fromNumber(value));
173 json_writer.write(name, value);
181void VariableIOWriterMng::
182_generateVariablesMetaData(JSONWriter& json_writer, XmlNode variables_node,
183 const VariableCollection& vars, IHashAlgorithm* hash_algo)
185 StringBuilder var_full_type_b;
187 Ref<IHashAlgorithmContext> hash_context;
189 SHA1HashAlgorithm sha1_hash_algo;
190 hash_context = sha1_hash_algo.createContext();
193 json_writer.writeKey(
"variables");
194 json_writer.beginArray();
196 for (VariableCollection::Enumerator i(vars); ++i;) {
197 JSONWriter::Object o(json_writer);
199 Ref<VariableMetaData> vmd(var->createMetaDataRef());
200 String var_full_type = vmd->fullType();
201 String var_family_name = var->itemFamilyName();
202 String var_mesh_name = var->meshName();
203 XmlNode var_node = XmlElement(variables_node,
"variable");
204 _writeAttribute(json_writer, var_node,
"base-name", var->name());
205 if (!var_family_name.null())
206 _writeAttribute(json_writer, var_node,
"item-family-name", var_family_name);
207 if (var->isPartial())
208 _writeAttribute(json_writer, var_node,
"item-group-name", var->itemGroupName());
209 if (!var_mesh_name.null())
210 _writeAttribute(json_writer, var_node,
"mesh-name", var_mesh_name);
211 _writeAttribute(json_writer, var_node,
"full-type", var_full_type);
212 _writeAttribute(json_writer, var_node,
"data-type", String(
dataTypeName(var->dataType())));
213 _writeAttribute(json_writer, var_node,
"dimension", var->dimension());
214 _writeAttribute(json_writer, var_node,
"multi-tag", var->multiTag());
215 _writeAttribute(json_writer, var_node,
"property", var->property());
218 if (var->property() & IVariable::PDumpNull)
219 var->data()->cloneEmptyRef()->computeHash(hash_algo, hash_values);
221 var->data()->computeHash(hash_algo, hash_values);
222 String hash_str = Convert::toHexaString(hash_values);
223 _writeAttribute(json_writer, var_node,
"hash", hash_str);
224 if (hash_context.get()) {
225 hash_context->reset();
226 DataHashInfo hash_info(hash_context.get());
227 if (var->property() & IVariable::PDumpNull)
228 var->data()->cloneEmptyRef()->_commonInternal()->computeHash(hash_info);
230 var->data()->_commonInternal()->computeHash(hash_info);
231 HashAlgorithmValue hash_value;
232 hash_context->computeHashValue(hash_value);
233 String hash2_str = Convert::toHexaString(
asBytes(hash_value.bytes()));
234 info(6) <<
"Hash=" << hash2_str <<
" old_hash="
235 << hash_str <<
" name=" << var->name();
236 _writeAttribute(json_writer, var_node,
"hash2", hash2_str);
237 _writeAttribute(json_writer, var_node,
"hash-version", hash_info.version());
242 json_writer.endArray();
252void VariableIOWriterMng::
258 json_writer.writeKey(
"meshes");
259 json_writer.beginArray();
267 for (
Integer i = 0, n = meshes.
size(); i < n; ++i) {
269 bool do_dump =
mesh->properties()->getBool(
"dump");
271 if (do_dump ||
mesh == default_mesh) {
274 _writeAttribute(json_writer, mesh_node,
"name",
mesh->name());
275 _writeAttribute(json_writer, mesh_node,
"factory-name",
mesh->factoryName());
282 if (is_parallel &&
mesh->parallelMng() == seq_pm)
283 _writeAttribute(json_writer, mesh_node,
"sequential",
true);
287 json_writer.endArray();
293String VariableIOWriterMng::
296 JSONWriter json_writer(JSONWriter::FormatFlags::None);
299 XmlNode doc_node = doc->documentNode();
300 XmlElement root_element(doc_node,
"arcane-checkpoint-metadata");
301 XmlElement variables_node(root_element,
"variables");
305 json_writer.write(
"version",
static_cast<Int64>(1));
307 json_writer.write(
"hash-algorithm-name", hash_algo->
name());
308 _generateVariablesMetaData(json_writer, variables_node, vars, hash_algo);
309 XmlElement meshes_node(root_element,
"meshes");
310 _generateMeshesMetaData(json_writer, meshes_node);
314 XmlElement json_node(root_element,
"json", json_writer.getBuffer());
316 String s = doc->save();
317 info(6) <<
"META_DATA=" << s;
324void VariableIOWriterMng::
325_writeVariables(IDataWriter* writer,
const VariableCollection& vars,
bool use_hash)
330 m_variable_mng->m_write_observable->notifyAllObservers();
331 writer->beginWrite(vars);
337 for (VariableCollection::Enumerator i(vars); ++i;) {
340 var->notifyBeginWrite();
343 MD5HashAlgorithm md5_hash_algo;
344 SHA1HashAlgorithm sha1_hash_algo;
345 IHashAlgorithm* hash_algo = &md5_hash_algo;
347 hash_algo = &sha1_hash_algo;
350 String meta_data = _generateMetaData(vars, hash_algo);
351 writer->setMetaData(meta_data);
353 for (VariableCollection::Enumerator i(vars); ++i;) {
358 if (var->property() & (IVariable::PDumpNull))
359 writer->write(var, var->data()->cloneEmptyRef().get());
361 writer->write(var, var->data());
363 catch (
const Exception& ex) {
364 error() <<
"Exception Arcane while VariableMng::writeVariables()"
365 <<
" var=" << var->fullName()
366 <<
" exception=" << ex;
369 catch (
const std::exception& ex) {
370 error() <<
"Exception while VariableMng::writeVariables()"
371 <<
" var=" << var->fullName()
372 <<
" exception=" << ex.what();
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Interface for writing variable data.
Interface of a hashing algorithm.
virtual String name() const
Name of the algorithm.
Interface of the parallelism manager for a subdomain.
virtual IParallelMng * sequentialParallelMng()=0
Returns a sequential parallelism manager.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
Interface of the subdomain manager.
virtual IMesh * defaultMesh()=0
Default mesh.
virtual ConstArrayView< IMesh * > meshes() const =0
List of meshes in the subdomain.
Encapsulation of an automatically destructing pointer.
Unicode character string.
void setAttrValue(const String &name, const String &value)
Sets the attribute name to the value value.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
UniqueArray< Byte > ByteUniqueArray
Dynamic 1D array of characters.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of non-modifiable bytes.
const char * dataTypeName(eDataType type)
Data type name.