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"
71 explicit VariableDataTypeInfo(
const String& full_type)
74 std::vector<String> split_strs;
75 full_type.
split(split_strs,
'.');
76 size_t nb_split = split_strs.size();
78 if (split_strs[4] !=
"Partial")
79 ARCANE_FATAL(
"Invalid value for partial full_type '{0}'", full_type);
84 ARCANE_FATAL(
"Invalid value for full_type '{0}'", full_type);
85 m_data_type_name = split_strs[0];
86 m_item_kind_name = split_strs[1];
87 m_dimension = split_strs[2];
88 m_multi_tag = split_strs[3];
93 const String& dataTypeName()
const {
return m_data_type_name; }
94 const String& itemKindName()
const {
return m_item_kind_name; }
95 const String& dimension()
const {
return m_dimension; }
96 const String& multiTag()
const {
return m_multi_tag; }
97 bool isPartial()
const {
return m_is_partial; }
123 virtual void endRead() = 0;
141 return m_reader->beginRead(vars);
146 m_reader->read(var, data);
148 void endRead()
override
150 return m_reader->endRead();
181 void endRead()
override
183 return m_reader->endRead();
194class VariableMetaDataList
198 typedef std::map<String, Ref<VariableMetaData>> VMDMap;
202 VariableMetaDataList() =
default;
203 VariableMetaDataList(
const VariableMetaDataList& rhs) =
delete;
204 VariableMetaDataList& operator=(
const VariableMetaDataList& rhs) =
delete;
205 ~VariableMetaDataList()
221 m_vmd_map.insert(std::make_pair(vmd->fullName(), vmd));
230 auto x = m_vmd_map.find(full_name);
231 if (x != m_vmd_map.end())
232 return x->second.get();
235 VMDMap::const_iterator begin()
const {
return m_vmd_map.begin(); }
236 VMDMap::const_iterator end()
const {
return m_vmd_map.end(); }
237 void setHashAlgorithmName(
const String& v) { m_hash_algorithm = v; }
238 const String& hashAlgorithmName()
const {
return m_hash_algorithm; }
242 std::map<String, Ref<VariableMetaData>> m_vmd_map;
254class VariableReaderMng
264 , m_meta_data(meta_data)
276 explicit VariableReaderMng(
ITraceMng* tm)
284 const VariableList& variablesToRead() {
return m_vars_to_read; }
288 VariableMetaDataList m_vmd_list;
289 VariableList m_vars_to_read;
290 UniqueArray<VarReadInfo> m_var_read_info_list;
294 void _buildVariablesToRead(IVariableMng* vm);
300void VariableReaderMng::
303 m_vars_to_read.clear();
304 m_var_read_info_list.clear();
305 for (
const auto& x : m_vmd_list) {
306 const String& full_name = x.first;
307 IVariable* var = vm->findVariableFullyQualified(full_name);
310 m_vars_to_read.add(var);
311 m_var_read_info_list.add(
VarReadInfo(var, var->data(), x.second.get()));
318void VariableReaderMng::
321 _buildVariablesToRead(vm);
322 reader->beginRead(m_vars_to_read);
323 for (
const auto& ivar : m_var_read_info_list) {
325 IVariable* var = ivar.m_variable;
326 IData* data = ivar.m_data;
327 VariableMetaData* vmd = ivar.m_meta_data;
328 String exception_message;
329 bool has_error =
false;
331 reader->read(vmd, var, data);
333 var->notifyEndRead();
335 catch (
const Exception& ex) {
338 exception_message = ostr.str();
341 catch (
const std::exception& ex) {
342 exception_message = ex.what();
347 String var_full_name = vmd->fullName();
348 ostr() <<
"Variable = " << var_full_name;
350 for (VarRefEnumerator ivar(var); ivar.hasNext(); ++ivar) {
351 VariableRef* ref = *ivar;
352 String s = ref->assignmentStackTrace();
354 ostr() <<
"Stack assignement: " << s;
358 ARCANE_FATAL(
"Can not read variable variable={0} exception={1} infos={2}",
359 var_full_name, exception_message, ostr.str());
375, m_is_use_json_metadata(true)
378 m_is_use_json_metadata = (v.value() != 0);
387void VariableIOReaderMng::
388readCheckpoint(ICheckpointReader* service)
390 Trace::Setter mci(
traceMng(), _msgClassName());
395 service->notifyBeginRead();
397 IDataReader* data_reader = service->dataReader();
400 String meta_data = data_reader->metaData();
402 if (meta_data.null())
405 OldDataReaderWrapper wrapper(data_reader);
407 info(6) <<
"METADATA (ICheckpointReader): FromCheckpoint: " << meta_data;
409 VariableReaderMng var_read_mng(
traceMng());
410 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
412 _readMetaData(vmd_list, meta_data.bytes());
413 _createVariablesFromMetaData(vmd_list);
414 _readVariablesData(var_read_mng, &wrapper);
417 service->notifyEndRead();
418 _checkHashFunction(vmd_list);
424void VariableIOReaderMng::
425readCheckpoint(
const CheckpointReadInfo& infos)
427 Trace::Setter mci(
traceMng(), _msgClassName());
429 ICheckpointReader2* service = infos.reader();
432 IParallelMng* pm = infos.parallelMng();
435 service->notifyBeginRead(infos);
437 IDataReader2* data_reader = service->dataReader();
440 UniqueArray<Byte> meta_data_bytes;
441 data_reader->fillMetaData(meta_data_bytes);
442 if (meta_data_bytes.empty())
445 DataReaderWrapper wrapper(data_reader);
447 info(6) <<
"METADATA (ICheckpointReader2): FromCheckpoint: " << String(meta_data_bytes);
449 VariableReaderMng var_read_mng(
traceMng());
450 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
452 _readMetaData(vmd_list, meta_data_bytes);
453 _createVariablesFromMetaData(vmd_list);
454 _readVariablesData(var_read_mng, &wrapper);
457 service->notifyEndRead();
458 _checkHashFunction(vmd_list);
464void VariableIOReaderMng::
465readVariables(IDataReader* reader, IVariableFilter* filter)
467 Trace::Setter mci(
traceMng(), _msgClassName());
468 VariableReaderMng var_read_mng(
traceMng());
469 _buildFilteredVariableList(var_read_mng, filter);
470 OldDataReaderWrapper wrapper(reader);
471 _readVariablesData(var_read_mng, &wrapper);
496 XmlNode root_node = doc->documentNode().documentElement();
504 if (!json_node.
null()) {
506 info(6) <<
"READER_JSON=" << json_meta_data;
513 String hash_algo_name = json_meta_data_object.
child(
"hash-algorithm-name").
value();
514 vmd_list.setHashAlgorithmName(hash_algo_name);
516 if (m_is_use_json_metadata) {
520 ARCANE_FATAL(
"Bad version for JSON Meta Data (v={0}). Only version '1' is supported", v);
521 json_variables = json_meta_data_object.
expectedChild(
"variables");
526 _readVariablesMetaData(vmd_list, json_variables, variables_node);
528 _readMeshesMetaData(json_meshes, meshes_node);
553 String hash_service_name = vmd_list.hashAlgorithmName();
554 if (!hash_service_name.
empty()) {
555 if (hash_service_name ==
"MD5")
556 hash_algo = &md5_hash_algorithm;
557 else if (hash_service_name ==
"SHA1") {
558 hash_algo = &sha1_hash_algorithm;
562 ARCANE_FATAL(
"Not supported hash algorithm '{0}'. Valid values are 'SHA1' or 'MD5'");
567 Directory listing_dir = m_variable_mng->subDomain()->listingDirectory();
568 for (
const auto& i : vmd_list) {
571 String reference_hash = (hash_version > 0) ? vmd->
hash2() : vmd->
hash();
576 if (reference_hash.
null())
578 const String& full_name = i.first;
579 IVariable* var = m_variable_mng->findVariableFullyQualified(full_name);
586 bool do_compare =
true;
587 if (hash_version > 0) {
589 hash_context->
reset();
593 hash_context->computeHashValue(hash_value);
596 if (hash_version != hash_info.version())
603 if (do_compare && (hash_str != reference_hash)) {
605 error() <<
"Hash values are different. Corrumpted values."
607 <<
" ref=" << reference_hash
608 <<
" current=" << hash_str;
611 String fname = listing_dir.
file(String::format(
"dump-{0}-sid_{1}", var->
fullName(), sid));
612 std::ofstream ofile(fname.
localstr());
613 ofile.write(
reinterpret_cast<const char*
>(buf.
data()), buf.
size());
617 if (total_nb_error != 0) {
627void VariableIOReaderMng::
632 for (
const auto& xvmd : vmd_list) {
633 auto& vmd = *(xvmd.second.get());
634 const String& full_name = vmd.fullName();
635 IVariable* var = m_variable_mng->findVariableFullyQualified(full_name);
638 const String& base_name = vmd.baseName();
639 Integer property = vmd.property();
640 const String& mesh_name = vmd.meshName();
641 const String& group_name = vmd.itemGroupName();
642 const String& family_name = vmd.itemFamilyName();
644 if (!mesh_name.
null()) {
646 vbi =
VariableBuildInfo(sd, base_name, mesh_name, family_name, group_name, property);
650 info(5) <<
"Create variable TYPE=" << full_name;
651 m_variable_mng->_createVariableFromType(vmd.fullType(), vbi);
658void VariableIOReaderMng::
659_readVariablesMetaData(VariableMetaDataList& vmd_list, JSONValue variables_json,
660 const XmlNode& variables_node)
662 String ustr_base_name(
"base-name");
663 String ustr_family_name(
"item-family-name");
664 String ustr_group_name(
"item-group-name");
665 String ustr_mesh_name(
"mesh-name");
666 String ustr_full_type(
"full-type");
667 String ustr_data_type(
"data-type");
668 String ustr_hash(
"hash");
669 String ustr_hash2(
"hash2");
670 String ustr_hash_version(
"hash-version");
671 String ustr_property(
"property");
672 String ustr_multitag(
"multi-tag");
675 struct VariableReadInfo
684 Int32 hash_version = 0;
689 UniqueArray<VariableReadInfo> variables_info;
693 if (!variables_json.null()) {
696 JSONValueList vars = variables_json.valueAsArray();
697 for (
const JSONValue& var : vars) {
699 r.full_type = var.expectedChild(ustr_full_type).value();
700 r.base_name = var.expectedChild(ustr_base_name).value();
701 r.data_type = var.child(ustr_data_type).value();
702 r.mesh_name = var.child(ustr_mesh_name).value();
703 r.family_name = var.child(ustr_family_name).value();
704 r.group_name = var.child(ustr_group_name).value();
705 r.hash_value = var.child(ustr_hash).value();
706 r.hash2_value = var.child(ustr_hash2).value();
707 r.hash_version = var.child(ustr_hash_version).valueAsInt32();
708 r.multi_tag = var.child(ustr_multitag).value();
709 r.property = var.child(ustr_property).valueAsInt32();
710 variables_info.add(r);
715 XmlNodeList vars = variables_node.children(
"variable");
716 for (
const auto& var : vars) {
718 r.full_type = var.attrValue(ustr_full_type);
719 r.data_type = var.attrValue(ustr_data_type);
720 r.base_name = var.attrValue(ustr_base_name);
721 r.mesh_name = var.attrValue(ustr_mesh_name);
722 r.group_name = var.attrValue(ustr_group_name);
723 r.family_name = var.attrValue(ustr_family_name);
724 r.hash_value = var.attrValue(ustr_hash);
725 r.multi_tag = var.attrValue(ustr_multitag);
726 r.property = var.attr(ustr_property).valueAsInteger();
727 variables_info.add(r);
731 for (
const VariableReadInfo& r : variables_info) {
732 String full_type = r.full_type;
733 VariableDataTypeInfo vdti(full_type);
736 if (vdti.dataTypeName() != r.data_type)
737 ARCANE_FATAL(
"Incoherent value for 'data-type' name v='{0}' expected='{1}'", r.data_type, vdti.dataTypeName());
739 String family_name = r.family_name;
742 String group_name = r.group_name;
743 bool is_partial = vdti.isPartial();
748 group_name =
"All" + family_name +
"s";
750 auto vmd = vmd_list.add(r.base_name, r.mesh_name, r.family_name, group_name, is_partial);
752 vmd->setFullType(full_type);
753 vmd->setHash(r.hash_value);
754 vmd->setHash2(r.hash2_value);
755 vmd->setHashVersion(r.hash_version);
756 vmd->setMultiTag(r.multi_tag);
757 vmd->setProperty(r.property);
759 info(5) <<
"CHECK VAR: "
760 <<
" base-name=" << vmd->baseName()
761 <<
" mesh-name=" << vmd->meshName()
762 <<
" family-name=" << vmd->itemFamilyName()
763 <<
" full-type=" << vmd->fullType()
764 <<
" name=" << vmd->fullName()
765 <<
" multitag=" << vmd->multiTag()
766 <<
" property=" << vmd->property()
767 <<
" hash=" << vmd->hash();
774void VariableIOReaderMng::
775_readMeshesMetaData(JSONValue meshes_json,
const XmlNode& meshes_node)
777 ISubDomain* sd = m_variable_mng->subDomain();
778 IMeshMng* mesh_mng = sd->
meshMng();
787 UniqueArray<MeshInfo> meshes_info;
791 if (!meshes_json.null()) {
793 JSONValueList vars = meshes_json.valueAsArray();
794 for (
const JSONValue& var : vars) {
795 String mesh_name = var.expectedChild(
"name").value();
796 String mesh_factory_name = var.child(
"factory-name").value();
797 bool is_sequential =
false;
798 JSONValue v = var.child(
"sequential");
800 is_sequential = v.valueAsBool();
801 meshes_info.add({ mesh_name, mesh_factory_name, is_sequential });
805 XmlNodeList meshes = meshes_node.children(
"mesh");
806 for (XmlNode var : meshes) {
807 String mesh_name = var.attrValue(
"name");
808 String mesh_factory_name = var.attrValue(
"factory-name");
809 bool is_sequential = var.attr(
"sequential",
false).valueAsBoolean();
810 meshes_info.add({ mesh_name, mesh_factory_name, is_sequential });
814 for (
const MeshInfo& mesh_info : meshes_info) {
815 String mesh_name = mesh_info.name;
816 String mesh_factory_name = mesh_info.factory_name;
817 MeshHandle* mesh_handle = mesh_mng->findMeshHandle(mesh_name,
false);
818 IMesh* mesh = (mesh_handle) ? mesh_handle->mesh() :
nullptr;
821 bool is_sequential = mesh_info.is_sequential;
822 info() <<
"Creating from checkpoint mesh='" << mesh_name
823 <<
"' sequential?=" << is_sequential
824 <<
" factory=" << mesh_factory_name;
827 if (mesh_factory_name.null())
831 MeshBuildInfo mbi(mesh_name);
832 mbi.addFactoryName(mesh_factory_name);
833 IParallelMng* mesh_pm = m_variable_mng->m_parallel_mng;
835 mesh_pm = mesh_pm->sequentialParallelMng();
837 mesh_factory_mng->createMesh(mbi);
845void VariableIOReaderMng::
846_buildFilteredVariableList(VariableReaderMng& var_read_mng, IVariableFilter* filter)
848 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
849 for (
const auto& i : m_variable_mng->m_full_name_variable_map) {
850 IVariable* var = i.second;
851 bool apply_me =
true;
853 apply_me = filter->applyFilter(*var);
854 info(5) <<
"Read variable name=" << var->fullName() <<
" filter=" << apply_me;
856 Ref<VariableMetaData> vmd = var->createMetaDataRef();
865void VariableIOReaderMng::
866_readVariablesData(VariableReaderMng& var_read_mng, IDataReaderWrapper* reader)
868 var_read_mng.readVariablesData(m_variable_mng, reader);
869 _finalizeReadVariables(var_read_mng.variablesToRead());
875void VariableIOReaderMng::
876_finalizeReadVariables(
const VariableList& vars_to_read)
878 ARCANE_UNUSED(vars_to_read);
880 info(4) <<
"VariableMng: _finalizeReadVariables()";
889 for (
const auto& i : m_variable_mng->m_full_name_variable_map)
890 i.second->syncReferences();
893 m_variable_mng->m_read_observable->notifyAllObservers();
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_CHECK_POINTER2(ptr, text)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
void clear()
Supprime les éléments du tableau.
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Informations pour le calcul du hash d'une donnée.
Informations de relecture des données.
Classe gérant un répertoire.
virtual String file(const String &file_name) const
Retourne le chemin complet du fichier file_name dans le répertoire.
Valeur retournée par un algorithme de hashage.
virtual void computeHash(DataHashInfo &hash_info)=0
Calcule le hash de la donnée.
Interface de lecture des données d'une variable (Version 2)
Interface de lecture des données d'une variable.
virtual Ref< ISerializedData > createSerializedDataRef(bool use_basic_type) const =0
Sérialise la donnée.
virtual void computeHash(IHashAlgorithm *algo, ByteArray &output) const =0
Calcul une clé de hashage sur cette donnée.
virtual IDataInternal * _commonInternal()=0
Interface d'un algorithme de hashage.
virtual IMeshFactoryMng * meshFactoryMng() const =0
Fabrique de maillages associée à ce gestionnaire.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Interface du gestionnaire d'un sous-domaine.
virtual IMeshMng * meshMng() const =0
Retourne le gestionnaire de maillage.
Interface du gestionnaire de traces.
Interface du gestionnaire de variables.
Interface d'une variable.
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille)
virtual IData * data()=0
Données associées à la variable.
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Charge un document XML.
Gestion d'un document JSON.
void parse(Span< const Byte > bytes)
Lit le fichier au format UTF-8.
JSONValue root() const
Elément racine.
Représente une valeur JSON.
String value() const
Valeur sous forme de String. La chaîne retournée est nulle si 'null()' est vrai.
Int32 valueAsInt32() const
Valeur sous forme de Int64. Retourn 0 si 'null()' est vrai.
JSONValue expectedChild(StringView name) const
Valeur fille de nom name. Lance une exception si non trouvé.
JSONValue child(StringView name) const
Valeur fille de nom name. Retourne une valeur nulle si non trouvé.
Calcule la fonction de hashage MD5 d'un tableau.
Exception lorsqu'une erreur fatale 'parallèle' est générée.
T * get() const
Retourne l'objet référé par l'instance.
Référence à une instance.
void reset()
Positionne l'instance au pointeur nul.
InstanceType * get() const
Instance associée ou nullptr si aucune.
Implémentation de l'algorithme SHA-1.
Ref< IHashAlgorithmContext > createContext() override
Créé un contexte pour calculer la valeur du hash de manière incrémentale.
Encapsulation d'un pointeur qui se détruit automatiquement.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Vue d'un tableau d'éléments de type T.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Span< const Byte > bytes() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
void split(StringContainer &str_array, char c) const
Découpe la chaîne suivant le caractère c.
Classe d'accès aux traces.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
ITraceMng * traceMng() const
Gestionnaire de trace.
Paramètres nécessaires à la construction d'une variable.
Informations de relecture des données d'une variable.
Wrapper pour IDataReader2.
Interface pour utiliser IDataReader ou IDataReader2.
Wrapper pour IDataReader.
void _readMetaData(VariableMetaDataList &vmd_list, Span< const Byte > bytes)
Lecture des méta-données.
void _checkHashFunction(const VariableMetaDataList &vmd_list)
Vérifie les valeurs des fonctions de hashage.
Gestionnaire de variables.
XmlNode child(const String &name) const
Noeud fils de celui-ci de nom name.
String value() const
Valeur du noeud.
bool null() const
Vrai si le noeud est nul.
String toHexaString(ByteConstArrayView input)
Converti un tableau d'octet en sa représentation hexadécimale.
@ ReduceSum
Somme des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
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.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.