14#include "arcane/impl/internal/VariableMng.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ParallelFatalErrorException.h"
18#include "arcane/utils/IObservable.h"
19#include "arcane/utils/ScopedPtr.h"
20#include "arcane/utils/StringBuilder.h"
21#include "arcane/utils/MD5HashAlgorithm.h"
22#include "arcane/utils/SHA1HashAlgorithm.h"
23#include "arcane/utils/OStringStream.h"
24#include "arcane/utils/PlatformUtils.h"
25#include "arcane/utils/JSONReader.h"
26#include "arcane/utils/ValueConvert.h"
28#include "arcane/core/IXmlDocumentHolder.h"
29#include "arcane/core/XmlNode.h"
30#include "arcane/core/VariableMetaData.h"
31#include "arcane/core/IData.h"
32#include "arcane/core/IMesh.h"
33#include "arcane/core/Properties.h"
34#include "arcane/core/Timer.h"
35#include "arcane/core/VarRefEnumerator.h"
36#include "arcane/core/CheckpointInfo.h"
37#include "arcane/core/Directory.h"
38#include "arcane/core/ISerializedData.h"
39#include "arcane/core/VariableBuildInfo.h"
40#include "arcane/core/XmlNodeList.h"
41#include "arcane/core/IMeshMng.h"
42#include "arcane/core/IMeshFactoryMng.h"
43#include "arcane/core/MeshBuildInfo.h"
44#include "arcane/core/internal/IDataInternal.h"
46#include "arcane/core/ICheckpointReader.h"
47#include "arcane/core/IDataReader.h"
48#include "arcane/core/IDataReader2.h"
50#include "arcane/core/ISubDomain.h"
51#include "arcane/core/IParallelMng.h"
53#include "arcane/core/internal/IParallelMngInternal.h"
54#include "arcane/core/internal/IVariableInternal.h"
74 explicit VariableDataTypeInfo(
const String& full_type)
77 std::vector<String> split_strs;
78 full_type.
split(split_strs,
'.');
79 size_t nb_split = split_strs.size();
81 if (split_strs[4] !=
"Partial")
82 ARCANE_FATAL(
"Invalid value for partial full_type '{0}'", full_type);
87 ARCANE_FATAL(
"Invalid value for full_type '{0}'", full_type);
88 m_data_type_name = split_strs[0];
89 m_item_kind_name = split_strs[1];
90 m_dimension = split_strs[2];
91 m_multi_tag = split_strs[3];
96 const String& dataTypeName()
const {
return m_data_type_name; }
97 const String& itemKindName()
const {
return m_item_kind_name; }
98 const String& dimension()
const {
return m_dimension; }
99 const String& multiTag()
const {
return m_multi_tag; }
100 bool isPartial()
const {
return m_is_partial; }
127 virtual void endRead() = 0;
146 return m_reader->beginRead(vars);
151 m_reader->read(var, data);
153 void endRead()
override
155 return m_reader->endRead();
187 void endRead()
override
189 return m_reader->endRead();
200class VariableMetaDataList
204 typedef std::map<String, Ref<VariableMetaData>> VMDMap;
208 VariableMetaDataList() =
default;
209 VariableMetaDataList(
const VariableMetaDataList& rhs) =
delete;
210 VariableMetaDataList& operator=(
const VariableMetaDataList& rhs) =
delete;
211 ~VariableMetaDataList()
227 m_vmd_map.insert(std::make_pair(vmd->fullName(), vmd));
236 auto x = m_vmd_map.find(full_name);
237 if (x != m_vmd_map.end())
238 return x->second.get();
241 VMDMap::const_iterator begin()
const {
return m_vmd_map.begin(); }
242 VMDMap::const_iterator end()
const {
return m_vmd_map.end(); }
243 void setHashAlgorithmName(
const String& v) { m_hash_algorithm = v; }
244 const String& hashAlgorithmName()
const {
return m_hash_algorithm; }
248 std::map<String, Ref<VariableMetaData>> m_vmd_map;
261class VariableReaderMng
271 , m_meta_data(meta_data)
283 explicit VariableReaderMng(
ITraceMng* tm)
291 const VariableList& variablesToRead() {
return m_vars_to_read; }
295 VariableMetaDataList m_vmd_list;
296 VariableList m_vars_to_read;
297 UniqueArray<VarReadInfo> m_var_read_info_list;
301 void _buildVariablesToRead(IVariableMng* vm);
307void VariableReaderMng::
310 m_vars_to_read.clear();
311 m_var_read_info_list.clear();
312 for (
const auto& x : m_vmd_list) {
313 const String& full_name = x.first;
314 IVariable* var = vm->findVariableFullyQualified(full_name);
317 m_vars_to_read.add(var);
318 m_var_read_info_list.add(
VarReadInfo(var, var->data(), x.second.get()));
325void VariableReaderMng::
328 _buildVariablesToRead(vm);
329 reader->beginRead(m_vars_to_read);
330 for (
const auto& ivar : m_var_read_info_list) {
332 IVariable* var = ivar.m_variable;
333 IData* data = ivar.m_data;
334 VariableMetaData* vmd = ivar.m_meta_data;
335 String exception_message;
336 bool has_error =
false;
338 reader->read(vmd, var, data);
340 var->notifyEndRead();
342 catch (
const Exception& ex) {
345 exception_message = ostr.str();
348 catch (
const std::exception& ex) {
349 exception_message = ex.what();
354 String var_full_name = vmd->fullName();
355 ostr() <<
"Variable = " << var_full_name;
357 for (VarRefEnumerator ivar(var); ivar.hasNext(); ++ivar) {
358 VariableRef* ref = *ivar;
359 String s = ref->assignmentStackTrace();
361 ostr() <<
"Stack assignment: " << s;
365 ARCANE_FATAL(
"Can not read variable variable={0} exception={1} infos={2}",
366 var_full_name, exception_message, ostr.str());
382, m_is_use_json_metadata(true)
385 m_is_use_json_metadata = (v.value() != 0);
394void VariableIOReaderMng::
395readCheckpoint(ICheckpointReader* service)
397 Trace::Setter mci(
traceMng(), _msgClassName());
402 service->notifyBeginRead();
404 IDataReader* data_reader = service->dataReader();
407 String meta_data = data_reader->metaData();
409 if (meta_data.null())
412 OldDataReaderWrapper wrapper(data_reader);
414 info(6) <<
"METADATA (ICheckpointReader): FromCheckpoint: " << meta_data;
416 VariableReaderMng var_read_mng(
traceMng());
417 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
419 _readMetaData(vmd_list, meta_data.bytes());
420 _createVariablesFromMetaData(vmd_list);
421 _readVariablesData(var_read_mng, &wrapper);
424 service->notifyEndRead();
425 _checkHashFunction(vmd_list);
431void VariableIOReaderMng::
432readCheckpoint(
const CheckpointReadInfo& infos)
434 Trace::Setter mci(
traceMng(), _msgClassName());
436 ICheckpointReader2* service = infos.reader();
439 IParallelMng* pm = infos.parallelMng();
442 service->notifyBeginRead(infos);
444 IDataReader2* data_reader = service->dataReader();
447 UniqueArray<Byte> meta_data_bytes;
448 data_reader->fillMetaData(meta_data_bytes);
449 if (meta_data_bytes.empty())
452 DataReaderWrapper wrapper(data_reader);
454 info(6) <<
"METADATA (ICheckpointReader2): FromCheckpoint: " << String(meta_data_bytes);
456 VariableReaderMng var_read_mng(
traceMng());
457 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
459 _readMetaData(vmd_list, meta_data_bytes);
460 _createVariablesFromMetaData(vmd_list);
461 _readVariablesData(var_read_mng, &wrapper);
464 service->notifyEndRead();
465 _checkHashFunction(vmd_list);
471void VariableIOReaderMng::
472readVariables(IDataReader* reader, IVariableFilter* filter)
474 Trace::Setter mci(
traceMng(), _msgClassName());
475 VariableReaderMng var_read_mng(
traceMng());
476 _buildFilteredVariableList(var_read_mng, filter);
477 OldDataReaderWrapper wrapper(reader);
478 _readVariablesData(var_read_mng, &wrapper);
504 XmlNode root_node = doc->documentNode().documentElement();
512 if (!json_node.
null()) {
514 info(6) <<
"READER_JSON=" << json_meta_data;
521 String hash_algo_name = json_meta_data_object.
child(
"hash-algorithm-name").
value();
522 vmd_list.setHashAlgorithmName(hash_algo_name);
524 if (m_is_use_json_metadata) {
528 ARCANE_FATAL(
"Bad version for JSON Meta Data (v={0}). Only version '1' is supported", v);
529 json_variables = json_meta_data_object.
expectedChild(
"variables");
534 _readVariablesMetaData(vmd_list, json_variables, variables_node);
536 _readMeshesMetaData(json_meshes, meshes_node);
562 String hash_service_name = vmd_list.hashAlgorithmName();
563 if (!hash_service_name.
empty()) {
564 if (hash_service_name ==
"MD5")
565 hash_algo = &md5_hash_algorithm;
566 else if (hash_service_name ==
"SHA1") {
567 hash_algo = &sha1_hash_algorithm;
571 ARCANE_FATAL(
"Not supported hash algorithm '{0}'. Valid values are 'SHA1' or 'MD5'");
576 Directory listing_dir = m_variable_mng->subDomain()->listingDirectory();
577 for (
const auto& i : vmd_list) {
580 String reference_hash = (hash_version > 0) ? vmd->
hash2() : vmd->
hash();
585 if (reference_hash.
null())
587 const String& full_name = i.first;
588 IVariable* var = m_variable_mng->findVariableFullyQualified(full_name);
595 bool do_compare =
true;
596 if (hash_version > 0) {
598 hash_context->
reset();
602 hash_context->computeHashValue(hash_value);
605 if (hash_version != hash_info.version())
612 if (do_compare && (hash_str != reference_hash)) {
614 error() <<
"Hash values are different. Corrumpted values."
616 <<
" ref=" << reference_hash
617 <<
" current=" << hash_str;
620 String fname = listing_dir.
file(String::format(
"dump-{0}-sid_{1}", var->
fullName(), sid));
621 std::ofstream ofile(fname.
localstr());
622 ofile.write(
reinterpret_cast<const char*
>(buf.
data()), buf.
size());
626 if (total_nb_error != 0) {
636void VariableIOReaderMng::
641 for (
const auto& xvmd : vmd_list) {
642 auto& vmd = *(xvmd.second.get());
643 const String& full_name = vmd.fullName();
644 IVariable* var = m_variable_mng->findVariableFullyQualified(full_name);
647 const String& base_name = vmd.baseName();
648 Integer property = vmd.property();
649 const String& mesh_name = vmd.meshName();
650 const String& group_name = vmd.itemGroupName();
651 const String& family_name = vmd.itemFamilyName();
653 if (!mesh_name.
null()) {
655 vbi =
VariableBuildInfo(sd, base_name, mesh_name, family_name, group_name, property);
659 info(5) <<
"Create variable TYPE=" << full_name;
660 VariableRef* variable_ref = m_variable_mng->_createVariableFromType(vmd.fullType(), vbi);
665 if (!mesh_name.
null()) {
672 variable_ref->variable()->_internalApi()->changeAllocator(MemoryAllocationOptions(pm->_internalApi()->machineShMemWinMemoryAllocator()));
680void VariableIOReaderMng::
681_readVariablesMetaData(VariableMetaDataList& vmd_list, JSONValue variables_json,
682 const XmlNode& variables_node)
684 String ustr_base_name(
"base-name");
685 String ustr_family_name(
"item-family-name");
686 String ustr_group_name(
"item-group-name");
687 String ustr_mesh_name(
"mesh-name");
688 String ustr_full_type(
"full-type");
689 String ustr_data_type(
"data-type");
690 String ustr_hash(
"hash");
691 String ustr_hash2(
"hash2");
692 String ustr_hash_version(
"hash-version");
693 String ustr_property(
"property");
694 String ustr_multitag(
"multi-tag");
697 struct VariableReadInfo
706 Int32 hash_version = 0;
711 UniqueArray<VariableReadInfo> variables_info;
715 if (!variables_json.null()) {
718 JSONValueList vars = variables_json.valueAsArray();
719 for (
const JSONValue& var : vars) {
721 r.full_type = var.expectedChild(ustr_full_type).value();
722 r.base_name = var.expectedChild(ustr_base_name).value();
723 r.data_type = var.child(ustr_data_type).value();
724 r.mesh_name = var.child(ustr_mesh_name).value();
725 r.family_name = var.child(ustr_family_name).value();
726 r.group_name = var.child(ustr_group_name).value();
727 r.hash_value = var.child(ustr_hash).value();
728 r.hash2_value = var.child(ustr_hash2).value();
729 r.hash_version = var.child(ustr_hash_version).valueAsInt32();
730 r.multi_tag = var.child(ustr_multitag).value();
731 r.property = var.child(ustr_property).valueAsInt32();
732 variables_info.add(r);
737 XmlNodeList vars = variables_node.children(
"variable");
738 for (
const auto& var : vars) {
740 r.full_type = var.attrValue(ustr_full_type);
741 r.data_type = var.attrValue(ustr_data_type);
742 r.base_name = var.attrValue(ustr_base_name);
743 r.mesh_name = var.attrValue(ustr_mesh_name);
744 r.group_name = var.attrValue(ustr_group_name);
745 r.family_name = var.attrValue(ustr_family_name);
746 r.hash_value = var.attrValue(ustr_hash);
747 r.multi_tag = var.attrValue(ustr_multitag);
748 r.property = var.attr(ustr_property).valueAsInteger();
749 variables_info.add(r);
753 for (
const VariableReadInfo& r : variables_info) {
754 String full_type = r.full_type;
755 VariableDataTypeInfo vdti(full_type);
758 if (vdti.dataTypeName() != r.data_type)
759 ARCANE_FATAL(
"Incoherent value for 'data-type' name v='{0}' expected='{1}'", r.data_type, vdti.dataTypeName());
761 String family_name = r.family_name;
764 String group_name = r.group_name;
765 bool is_partial = vdti.isPartial();
770 group_name =
"All" + family_name +
"s";
772 auto vmd = vmd_list.add(r.base_name, r.mesh_name, r.family_name, group_name, is_partial);
774 vmd->setFullType(full_type);
775 vmd->setHash(r.hash_value);
776 vmd->setHash2(r.hash2_value);
777 vmd->setHashVersion(r.hash_version);
778 vmd->setMultiTag(r.multi_tag);
779 vmd->setProperty(r.property);
781 info(5) <<
"CHECK VAR: "
782 <<
" base-name=" << vmd->baseName()
783 <<
" mesh-name=" << vmd->meshName()
784 <<
" family-name=" << vmd->itemFamilyName()
785 <<
" full-type=" << vmd->fullType()
786 <<
" name=" << vmd->fullName()
787 <<
" multitag=" << vmd->multiTag()
788 <<
" property=" << vmd->property()
789 <<
" hash=" << vmd->hash();
796void VariableIOReaderMng::
797_readMeshesMetaData(JSONValue meshes_json,
const XmlNode& meshes_node)
799 ISubDomain* sd = m_variable_mng->subDomain();
800 IMeshMng* mesh_mng = sd->
meshMng();
809 UniqueArray<MeshInfo> meshes_info;
813 if (!meshes_json.null()) {
815 JSONValueList vars = meshes_json.valueAsArray();
816 for (
const JSONValue& var : vars) {
817 String mesh_name = var.expectedChild(
"name").value();
818 String mesh_factory_name = var.child(
"factory-name").value();
819 bool is_sequential =
false;
820 JSONValue v = var.child(
"sequential");
822 is_sequential = v.valueAsBool();
823 meshes_info.add({ mesh_name, mesh_factory_name, is_sequential });
827 XmlNodeList meshes = meshes_node.children(
"mesh");
828 for (XmlNode var : meshes) {
829 String mesh_name = var.attrValue(
"name");
830 String mesh_factory_name = var.attrValue(
"factory-name");
831 bool is_sequential = var.attr(
"sequential",
false).valueAsBoolean();
832 meshes_info.add({ mesh_name, mesh_factory_name, is_sequential });
836 for (
const MeshInfo& mesh_info : meshes_info) {
837 String mesh_name = mesh_info.name;
838 String mesh_factory_name = mesh_info.factory_name;
839 MeshHandle* mesh_handle = mesh_mng->findMeshHandle(mesh_name,
false);
840 IMesh* mesh = (mesh_handle) ? mesh_handle->mesh() :
nullptr;
843 bool is_sequential = mesh_info.is_sequential;
844 info() <<
"Creating from checkpoint mesh='" << mesh_name
845 <<
"' sequential?=" << is_sequential
846 <<
" factory=" << mesh_factory_name;
849 if (mesh_factory_name.null())
853 MeshBuildInfo mbi(mesh_name);
854 mbi.addFactoryName(mesh_factory_name);
855 IParallelMng* mesh_pm = m_variable_mng->m_parallel_mng;
857 mesh_pm = mesh_pm->sequentialParallelMng();
859 mesh_factory_mng->createMesh(mbi);
867void VariableIOReaderMng::
868_buildFilteredVariableList(VariableReaderMng& var_read_mng, IVariableFilter* filter)
870 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
871 for (
const auto& i : m_variable_mng->m_full_name_variable_map) {
872 IVariable* var = i.second;
873 bool apply_me =
true;
875 apply_me = filter->applyFilter(*var);
876 info(5) <<
"Read variable name=" << var->fullName() <<
" filter=" << apply_me;
878 Ref<VariableMetaData> vmd = var->createMetaDataRef();
887void VariableIOReaderMng::
888_readVariablesData(VariableReaderMng& var_read_mng, IDataReaderWrapper* reader)
890 var_read_mng.readVariablesData(m_variable_mng, reader);
891 _finalizeReadVariables(var_read_mng.variablesToRead());
897void VariableIOReaderMng::
898_finalizeReadVariables(
const VariableList& vars_to_read)
900 ARCANE_UNUSED(vars_to_read);
902 info(4) <<
"VariableMng: _finalizeReadVariables()";
911 for (
const auto& i : m_variable_mng->m_full_name_variable_map)
912 i.second->syncReferences();
915 m_variable_mng->m_read_observable->notifyAllObservers();
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_CHECK_POINTER2(ptr, text)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
void clear()
Removes the elements from the array.
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Information for calculating data hash.
Data reading information.
Class managing a directory.
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Hash algorithm return value.
virtual void computeHash(DataHashInfo &hash_info)=0
Calculates the hash of the data.
Interface for reading data of a variable (Version 2).
Interface for reading variable data.
Interface of a data item.
virtual Ref< ISerializedData > createSerializedDataRef(bool use_basic_type) const =0
Serialize the data.
virtual void computeHash(IHashAlgorithm *algo, ByteArray &output) const =0
Compute a hash key on this data.
virtual IDataInternal * _commonInternal()=0
Interface of a hashing algorithm.
virtual IMeshFactoryMng * meshFactoryMng() const =0
Mesh factory associated with this manager.
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Searches for the mesh with name name.
virtual IParallelMng * parallelMng()=0
Parallelism manager.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
Interface of the subdomain manager.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual IMeshMng * meshMng() const =0
Returns the mesh manager.
Variable manager interface.
virtual String fullName() const =0
Full variable name (with family prefix).
@ PInShMem
Indicates that the variable must be allocated in shared memory.
virtual IData * data()=0
Data associated with the variable.
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Loads an XML document.
Management of a JSON document.
void parse(Span< const Byte > bytes)
Reads the file in UTF-8 format.
JSONValue root() const
Root element.
String value() const
Value in String format. The returned string is null if 'null()' is true.
Int32 valueAsInt32() const
Value in Int64 format. Returns 0 if 'null()' is true.
JSONValue expectedChild(StringView name) const
Child value with name name. Throws an exception if not found.
JSONValue child(StringView name) const
Child value with name name. Returns a null value if not found.
Calculates the MD5 hashing function of an array.
IMesh * mesh() const
Associated mesh.
Exception when a 'parallel' fatal error is generated.
T * get() const
Returns the object referenced by the instance.
void reset()
Positions the instance to the null pointer.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Implementation of the SHA-1 algorithm.
Ref< IHashAlgorithmContext > createContext() override
Creates a context to calculate the hash value incrementally.
Encapsulation of an automatically destructing pointer.
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
View of an array of elements of type T.
Unicode character string.
bool null() const
Returns true if the string is null.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Span< const Byte > bytes() const
Returns the conversion of the instance into UTF-8 encoding.
bool empty() const
True if the string is empty (null or "").
void split(StringContainer &str_array, char c) const
Splits the string based on the character c.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
ITraceMng * traceMng() const
Trace manager.
Parameters necessary for building a variable.
Data reading information for a variable.
Wrapper for IDataReader2.
Interface to use IDataReader or IDataReader2.
void _readMetaData(VariableMetaDataList &vmd_list, Span< const Byte > bytes)
Reading metadata.
void _checkHashFunction(const VariableMetaDataList &vmd_list)
Checks hash function values.
XmlNode child(const String &name) const
Child node of this node with name name.
String value() const
Node value.
bool null() const
True if the node is null.
String toHexaString(ByteConstArrayView input)
Converts a byte array to its hexadecimal representation.
@ ReduceSum
Sum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
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.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.