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"
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);
148 void endRead()
override
150 return m_reader->endRead();
181 void endRead()
override
198 typedef std::map<String, Ref<VariableMetaData>> VMDMap;
221 m_vmd_map.insert(std::make_pair(
vmd->fullName(),
vmd));
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;
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::
301_buildVariablesToRead(IVariableMng* vm)
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::
319readVariablesData(IVariableMng* vm, VariableIOReaderMng::IDataReaderWrapper* reader)
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());
372VariableIOReaderMng(VariableMng* vm)
373: TraceAccessor(vm->traceMng())
375, m_is_use_json_metadata(true)
377 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_USE_JSON_METADATA",
true))
378 m_is_use_json_metadata = (v.value() != 0);
387void VariableIOReaderMng::
388readCheckpoint(ICheckpointReader* service)
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)
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)
468 VariableReaderMng var_read_mng(
traceMng());
469 _buildFilteredVariableList(var_read_mng, filter);
470 OldDataReaderWrapper wrapper(reader);
471 _readVariablesData(var_read_mng, &wrapper);
516 if (m_is_use_json_metadata) {
520 ARCANE_FATAL(
"Bad version for JSON Meta Data (v={0}). Only version '1' is supported", v);
562 ARCANE_FATAL(
"Not supported hash algorithm '{0}'. Valid values are 'SHA1' or 'MD5'");
586 bool do_compare =
true;
605 error() <<
"Hash values are different. Corrumpted values."
606 <<
" name=" <<
var->fullName()
613 ofile.write(
reinterpret_cast<const char*
>(buf.data()), buf.size());
618 bool allow_bad = !platform::getEnvironmentVariable(
"ARCANE_ALLOW_DIFFERENT_CHECKPOINT_HASH").null();
627void VariableIOReaderMng::
633 auto&
vmd = *(
xvmd.second.get());
639 Integer
property =
vmd.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();
779 IMeshFactoryMng* mesh_factory_mng = mesh_mng->meshFactoryMng();
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.
Informations pour le calcul du hash d'une donnée.
Informations de relecture des données.
Classe gérant un répertoire.
Valeur retournée par un algorithme de hashage.
Interface de lecture des données d'une variable (Version 2)
virtual void read(const VariableDataReadInfo &infos)=0
Lit les données des informations spécifiées par infos.
virtual void beginRead(const DataReaderInfo &infos)=0
Notifie du début de lecture des données.
virtual void endRead()=0
Notifie de la fin de lecture des données.
Interface de lecture des données d'une variable.
virtual void read(IVariable *var, IData *data)=0
Lit les données data de la variable var.
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.
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.
virtual const IDirectory & listingDirectory() const =0
Répertoire de base des listings (logs, info exécution).
Interface du gestionnaire de variables.
Interface d'une variable.
virtual String name() const =0
Nom de la variable.
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Charge un document XML.
Gestion d'un document JSON.
Représente une valeur JSON.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Calcule la fonction de hashage MD5 d'un tableau.
Exception lorsqu'une erreur fatale 'parallèle' est générée.
Implémentation de l'algorithme SHA-1.
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.
Gestion de la lecture des variables.
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
Classe d'accès aux traces.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage error() const
Flot pour un message d'erreur.
TraceMessage info() const
Flot pour un message d'information.
Positionne une classe de message.
Vecteur 1D de données avec sémantique par valeur (style STL).
String toHexaString(ByteConstArrayView input)
Converti un tableau d'octet en sa représentation hexadécimale.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.