Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
VariableIOReaderMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* VariableIOMng.cc (C) 2000-2024 */
9/* */
10/* Classe gérant les entrées/sorties pour les variables. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/VariableMng.h"
15
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"
27
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"
45
46#include "arcane/core/ICheckpointReader.h"
47#include "arcane/core/IDataReader.h"
48#include "arcane/core/IDataReader2.h"
49
50#include "arcane/core/ISubDomain.h"
51#include "arcane/core/IParallelMng.h"
52
53// TODO: gérer le hash en version 64 bits.
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58namespace Arcane
59{
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64// Extraction des infos de type à partir d'une chaîne de caractères
65// NOTE L'extraction doit être cohérente avec la construction qui est
66// dans Variable.cc
68{
69 public:
70
72 : m_is_partial(false)
73 {
74 std::vector<String> split_strs;
75 full_type.split(split_strs, '.');
76 size_t nb_split = split_strs.size();
77 if (nb_split == 5) {
78 if (split_strs[4] != "Partial")
79 ARCANE_FATAL("Invalid value for partial full_type '{0}'", full_type);
80 m_is_partial = true;
81 --nb_split;
82 }
83 if (nb_split != 4)
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];
89 }
90
91 public:
92
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; }
98
99 private:
100
101 String m_data_type_name;
102 String m_item_kind_name;
103 String m_dimension;
104 String m_multi_tag;
105 bool m_is_partial;
106};
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
114{
115 public:
116
117 virtual ~IDataReaderWrapper() = default;
118
119 public:
120
121 virtual void beginRead(const VariableCollection& vars) = 0;
122 virtual void read(VariableMetaData* vmd, IVariable* var, IData* data) = 0;
123 virtual void endRead() = 0;
124};
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
132: public IDataReaderWrapper
133{
134 public:
135
136 explicit OldDataReaderWrapper(IDataReader* reader)
137 : m_reader(reader)
138 {}
139 void beginRead(const VariableCollection& vars) override
140 {
141 return m_reader->beginRead(vars);
142 }
143 void read(VariableMetaData* vmd, IVariable* var, IData* data) override
144 {
145 ARCANE_UNUSED(vmd);
146 m_reader->read(var, data);
147 }
148 void endRead() override
149 {
150 return m_reader->endRead();
151 }
152
153 private:
154
155 IDataReader* m_reader;
156};
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
164: public IDataReaderWrapper
165{
166 public:
167
168 explicit DataReaderWrapper(IDataReader2* reader)
169 : m_reader(reader)
170 {}
171 void beginRead(const VariableCollection& vars) override
172 {
173 ARCANE_UNUSED(vars);
174 return m_reader->beginRead(DataReaderInfo());
175 }
176 void read(VariableMetaData* vmd, IVariable* var, IData* data) override
177 {
178 ARCANE_UNUSED(var);
179 m_reader->read(VariableDataReadInfo(vmd, data));
180 }
181 void endRead() override
182 {
183 return m_reader->endRead();
184 }
185
186 private:
187
188 IDataReader2* m_reader;
189};
190
191/*---------------------------------------------------------------------------*/
192/*---------------------------------------------------------------------------*/
193
195{
196 public:
197
198 typedef std::map<String, Ref<VariableMetaData>> VMDMap;
199
200 public:
201
202 VariableMetaDataList() = default;
204 VariableMetaDataList& operator=(const VariableMetaDataList& rhs) = delete;
206 {
207 clear();
208 }
209
210 public:
211
213 const String& family_name, const String& group_name,
214 bool is_partial)
215 {
216 auto vmd = makeRef(new VariableMetaData(base_name, mesh_name, family_name, group_name, is_partial));
217 return add(vmd);
218 }
220 {
221 m_vmd_map.insert(std::make_pair(vmd->fullName(), vmd));
222 return vmd.get();
223 }
224 void clear()
225 {
226 m_vmd_map.clear();
227 }
228 VariableMetaData* findMetaData(const String& full_name)
229 {
230 auto x = m_vmd_map.find(full_name);
231 if (x != m_vmd_map.end())
232 return x->second.get();
233 return nullptr;
234 }
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; }
239
240 public:
241
242 std::map<String, Ref<VariableMetaData>> m_vmd_map;
243 String m_hash_algorithm;
244};
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
255: public TraceAccessor
256{
258 {
259 public:
260
262 : m_variable(var)
263 , m_data(data)
264 , m_meta_data(meta_data)
265 {}
266
267 public:
268
269 IVariable* m_variable;
270 IData* m_data;
271 VariableMetaData* m_meta_data;
272 };
273
274 public:
275
278 {}
279
280 public:
281
282 void readVariablesData(IVariableMng* vm, VariableIOReaderMng::IDataReaderWrapper* reader);
283 VariableMetaDataList& variableMetaDataList() { return m_vmd_list; }
284 const VariableList& variablesToRead() { return m_vars_to_read; }
285
286 private:
287
288 VariableMetaDataList m_vmd_list;
289 VariableList m_vars_to_read;
290 UniqueArray<VarReadInfo> m_var_read_info_list;
291
292 private:
293
294 void _buildVariablesToRead(IVariableMng* vm);
295};
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300void VariableReaderMng::
301_buildVariablesToRead(IVariableMng* vm)
302{
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);
308 if (!var)
309 ARCANE_FATAL("Var {0} not in VariableMng", full_name);
310 m_vars_to_read.add(var);
311 m_var_read_info_list.add(VarReadInfo(var, var->data(), x.second.get()));
312 }
313}
314
315/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
317
318void VariableReaderMng::
319readVariablesData(IVariableMng* vm, VariableIOReaderMng::IDataReaderWrapper* reader)
320{
321 _buildVariablesToRead(vm);
322 reader->beginRead(m_vars_to_read);
323 for (const auto& ivar : m_var_read_info_list) {
324 // NOTE: var peut-être nul
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;
330 try {
331 reader->read(vmd, var, data);
332 if (var)
333 var->notifyEndRead();
334 }
335 catch (const Exception& ex) {
336 OStringStream ostr;
337 ostr() << ex;
338 exception_message = ostr.str();
339 has_error = true;
340 }
341 catch (const std::exception& ex) {
342 exception_message = ex.what();
343 has_error = true;
344 }
345 if (has_error) {
346 OStringStream ostr;
347 String var_full_name = vmd->fullName();
348 ostr() << "Variable = " << var_full_name;
349 if (var) {
350 for (VarRefEnumerator ivar(var); ivar.hasNext(); ++ivar) {
351 VariableRef* ref = *ivar;
352 String s = ref->assignmentStackTrace();
353 if (!s.null())
354 ostr() << "Stack assignement: " << s;
355 }
356 }
357
358 ARCANE_FATAL("Can not read variable variable={0} exception={1} infos={2}",
359 var_full_name, exception_message, ostr.str());
360 }
361 }
362 reader->endRead();
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368/*---------------------------------------------------------------------------*/
369/*---------------------------------------------------------------------------*/
370
371VariableIOReaderMng::
372VariableIOReaderMng(VariableMng* vm)
373: TraceAccessor(vm->traceMng())
374, m_variable_mng(vm)
375, m_is_use_json_metadata(true)
376{
377 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_USE_JSON_METADATA", true))
378 m_is_use_json_metadata = (v.value() != 0);
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
387void VariableIOReaderMng::
388readCheckpoint(ICheckpointReader* service)
389{
390 Trace::Setter mci(traceMng(), _msgClassName());
391
392 if (!service)
393 ARCANE_FATAL("No protection service specified");
394
395 service->notifyBeginRead();
396
397 IDataReader* data_reader = service->dataReader();
398 if (!data_reader)
399 ARCANE_FATAL("no dataReader()");
400 String meta_data = data_reader->metaData();
401
402 if (meta_data.null())
403 ARCANE_FATAL("No meta-data in checkpoint.");
404
405 OldDataReaderWrapper wrapper(data_reader);
406
407 info(6) << "METADATA (ICheckpointReader): FromCheckpoint: " << meta_data;
408
409 VariableReaderMng var_read_mng(traceMng());
410 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
411 {
412 _readMetaData(vmd_list, meta_data.bytes());
413 _createVariablesFromMetaData(vmd_list);
414 _readVariablesData(var_read_mng, &wrapper);
415 }
416
417 service->notifyEndRead();
418 _checkHashFunction(vmd_list);
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
424void VariableIOReaderMng::
425readCheckpoint(const CheckpointReadInfo& infos)
426{
427 Trace::Setter mci(traceMng(), _msgClassName());
428
429 ICheckpointReader2* service = infos.reader();
430 ARCANE_CHECK_POINTER2(service, "No checkpoint service specified");
431
432 IParallelMng* pm = infos.parallelMng();
433 ARCANE_CHECK_POINTER2(pm, "no parallelMng()");
434
435 service->notifyBeginRead(infos);
436
437 IDataReader2* data_reader = service->dataReader();
438 ARCANE_CHECK_POINTER2(data_reader, "No dataReader()");
439
440 UniqueArray<Byte> meta_data_bytes;
441 data_reader->fillMetaData(meta_data_bytes);
442 if (meta_data_bytes.empty())
443 ARCANE_FATAL("No meta-data in checkpoint.");
444
445 DataReaderWrapper wrapper(data_reader);
446
447 info(6) << "METADATA (ICheckpointReader2): FromCheckpoint: " << String(meta_data_bytes);
448
449 VariableReaderMng var_read_mng(traceMng());
450 VariableMetaDataList& vmd_list = var_read_mng.variableMetaDataList();
451 {
452 _readMetaData(vmd_list, meta_data_bytes);
453 _createVariablesFromMetaData(vmd_list);
454 _readVariablesData(var_read_mng, &wrapper);
455 }
456
457 service->notifyEndRead();
458 _checkHashFunction(vmd_list);
459}
460
461/*---------------------------------------------------------------------------*/
462/*---------------------------------------------------------------------------*/
463
464void VariableIOReaderMng::
465readVariables(IDataReader* reader, IVariableFilter* filter)
466{
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);
472}
473
474/*---------------------------------------------------------------------------*/
475/*---------------------------------------------------------------------------*/
489{
491 if (!doc.get())
492 ARCANE_FATAL("The meta-data are invalid");
495
496 XmlNode root_node = doc->documentNode().documentElement();
497 XmlNode json_node = root_node.child("json");
498
499 // A partir de la version 3.11 de Arcane (juillet 2023), les
500 // méta-données sont aussi disponibles au format JSON. On les utilise
501 // si 'm_is_use_json_metadata' est vrai.
504 if (!json_node.null()) {
506 info(6) << "READER_JSON=" << json_meta_data;
507 json_reader.parse(json_meta_data.bytes());
508
509 JSONValue json_meta_data_object = json_reader.root().expectedChild("arcane-checkpoint-metadata");
510
511 // Lit toujours le nom de l'algorithme même si on n'utilise pas les meta-données
512 // car on s'en sert pour les comparaisons de la valeur du hash.
513 String hash_algo_name = json_meta_data_object.child("hash-algorithm-name").value();
514 vmd_list.setHashAlgorithmName(hash_algo_name);
515
516 if (m_is_use_json_metadata) {
517 JSONValue json_version = json_meta_data_object.expectedChild("version");
518 Int32 v = json_version.valueAsInt32();
519 if (v != 1)
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");
522 json_meshes = json_meta_data_object.expectedChild("meshes");
523 }
524 }
525 XmlNode variables_node = root_node.child("variables");
526 _readVariablesMetaData(vmd_list, json_variables, variables_node);
527 XmlNode meshes_node = root_node.child("meshes");
528 _readMeshesMetaData(json_meshes, meshes_node);
529}
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
544{
548 // Par défaut si rien n'est spécifié, il s'agit d'une protection issue
549 // d'une version antérieure à la 3.12 de Arcane. Dans ce cas l'algorithme
550 // utilisé est 'MD5'.
553 String hash_service_name = vmd_list.hashAlgorithmName();
554 if (!hash_service_name.empty()) {
555 if (hash_service_name == "MD5")
557 else if (hash_service_name == "SHA1") {
559 hash_context = sha1_hash_algorithm.createContext();
560 }
561 else
562 ARCANE_FATAL("Not supported hash algorithm '{0}'. Valid values are 'SHA1' or 'MD5'");
563 }
564 Integer nb_error = 0;
565 IParallelMng* pm = m_variable_mng->m_parallel_mng;
566 Int32 sid = pm->commRank();
567 Directory listing_dir = m_variable_mng->subDomain()->listingDirectory();
568 for (const auto& i : vmd_list) {
569 const VariableMetaData* vmd = i.second.get();
570 Int32 hash_version = vmd->hashVersion();
571 String reference_hash = (hash_version > 0) ? vmd->hash2() : vmd->hash();
572 // Teste si la valeur de hashage est présente. C'est normalement
573 // toujours le cas, sauf si la protection vient d'une ancienne
574 // version de Arcane qui ne sauvait pas cette information.
575 // Ce test pourra être supprimé plus tard.
576 if (reference_hash.null())
577 continue;
578 const String& full_name = i.first;
579 IVariable* var = m_variable_mng->findVariableFullyQualified(full_name);
580 if (!var)
581 // Ne devrait pas arriver
582 continue;
583 hash_values.clear();
584 IData* data = var->data();
586 bool do_compare = true;
587 if (hash_version > 0) {
589 hash_context->reset();
591 data->_commonInternal()->computeHash(hash_info);
593 hash_context->computeHashValue(hash_value);
594 hash_str = Convert::toHexaString(asBytes(hash_value.bytes()));
595 // Ne compare si les versions de hash associées à la variable différent
596 if (hash_version != hash_info.version())
597 do_compare = false;
598 }
599 else {
602 }
603 if (do_compare && (hash_str != reference_hash)) {
604 ++nb_error;
605 error() << "Hash values are different. Corrumpted values."
606 << " name=" << var->fullName()
607 << " ref=" << reference_hash
608 << " current=" << hash_str;
610 Span<const Byte> buf(sdata->constBytes());
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());
614 }
615 }
616 Integer total_nb_error = pm->reduce(Parallel::ReduceSum, nb_error);
617 if (total_nb_error != 0) {
618 bool allow_bad = !platform::getEnvironmentVariable("ARCANE_ALLOW_DIFFERENT_CHECKPOINT_HASH").null();
619 if (!allow_bad)
620 throw ParallelFatalErrorException(A_FUNCINFO, "hash functions differs");
621 }
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627void VariableIOReaderMng::
628_createVariablesFromMetaData(const VariableMetaDataList& vmd_list)
629{
630 ISubDomain* sd = m_variable_mng->subDomain();
631 // Récupère ou construit les variables qui n'existent pas encore.
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);
636 if (var)
637 continue;
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();
643 VariableBuildInfo vbi(sd, base_name, property);
644 if (!mesh_name.null()) {
645 if (vmd.isPartial())
647 else
649 }
650 info(5) << "Create variable TYPE=" << full_name;
651 m_variable_mng->_createVariableFromType(vmd.fullType(), vbi);
652 }
653}
654
655/*---------------------------------------------------------------------------*/
656/*---------------------------------------------------------------------------*/
657
658void VariableIOReaderMng::
659_readVariablesMetaData(VariableMetaDataList& vmd_list, JSONValue variables_json,
660 const XmlNode& variables_node)
661{
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");
673 vmd_list.clear();
674
675 struct VariableReadInfo
676 {
677 String full_type;
678 String base_name;
679 String mesh_name;
680 String family_name;
681 String group_name;
682 String hash_value;
683 String hash2_value;
684 Int32 hash_version = 0;
685 String multi_tag;
686 String data_type;
687 Int32 property = 0;
688 };
689 UniqueArray<VariableReadInfo> variables_info;
690
691 // Lit les informations des variables à partir des données JSON
692 // si ces dernières existent.
693 if (!variables_json.null()) {
694 // Lecture via JSON
695 // Déclare la liste ici pour éviter de retourner un temporaire dans 'for-range'
696 JSONValueList vars = variables_json.valueAsArray();
697 for (const JSONValue& var : vars) {
698 VariableReadInfo r;
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);
711 }
712 }
713 else {
714 // Lecture via les données XML
715 XmlNodeList vars = variables_node.children("variable");
716 for (const auto& var : vars) {
717 VariableReadInfo r;
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);
728 }
729 }
730
731 for (const VariableReadInfo& r : variables_info) {
732 String full_type = r.full_type;
733 VariableDataTypeInfo vdti(full_type);
734
735 // Vérifie que 'data-type' est cohérent avec la valeur dans '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());
738
739 String family_name = r.family_name;
740 // Actuellement, si la variable n'est pas partielle alors son groupe
741 // n'est pas sauvé dans les meta-données. Il faut donc le générer.
742 String group_name = r.group_name;
743 bool is_partial = vdti.isPartial();
744 if (!is_partial) {
745 // NOTE: Cette construction doit être cohérente avec celle de
746 // DynamicMeshKindInfos. A terme il faudra toujours sauver le nom du groupe
747 // dans les meta-données.
748 group_name = "All" + family_name + "s";
749 }
750 auto vmd = vmd_list.add(r.base_name, r.mesh_name, r.family_name, group_name, is_partial);
751
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);
758
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();
768 }
769}
770
771/*---------------------------------------------------------------------------*/
772/*---------------------------------------------------------------------------*/
773
774void VariableIOReaderMng::
775_readMeshesMetaData(JSONValue meshes_json, const XmlNode& meshes_node)
776{
777 ISubDomain* sd = m_variable_mng->subDomain();
778 IMeshMng* mesh_mng = sd->meshMng();
779 IMeshFactoryMng* mesh_factory_mng = mesh_mng->meshFactoryMng();
780
781 struct MeshInfo
782 {
783 String name;
784 String factory_name;
785 bool is_sequential;
786 };
787 UniqueArray<MeshInfo> meshes_info;
788
789 // Lit les informations des maillages à partir des données JSON
790 // si ces dernières existent.
791 if (!meshes_json.null()) {
792 // Déclare la liste ici pour éviter de retourner un temporaire dans 'for-range'
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");
799 if (!v.null())
800 is_sequential = v.valueAsBool();
801 meshes_info.add({ mesh_name, mesh_factory_name, is_sequential });
802 }
803 }
804 else {
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 });
811 }
812 }
813
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;
819 if (mesh)
820 continue;
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;
825 // Depuis avril 2020, l'attribut 'factory-name' doit être présent
826 // et sa valeur non nulle.
827 if (mesh_factory_name.null())
828 ARCANE_FATAL("No attribute 'factory-name' for mesh");
829
830 {
831 MeshBuildInfo mbi(mesh_name);
832 mbi.addFactoryName(mesh_factory_name);
833 IParallelMng* mesh_pm = m_variable_mng->m_parallel_mng;
834 if (is_sequential)
835 mesh_pm = mesh_pm->sequentialParallelMng();
836 mbi.addParallelMng(Arccore::makeRef(mesh_pm));
837 mesh_factory_mng->createMesh(mbi);
838 }
839 }
840}
841
842/*---------------------------------------------------------------------------*/
843/*---------------------------------------------------------------------------*/
844
845void VariableIOReaderMng::
846_buildFilteredVariableList(VariableReaderMng& var_read_mng, IVariableFilter* filter)
847{
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;
852 if (filter)
853 apply_me = filter->applyFilter(*var);
854 info(5) << "Read variable name=" << var->fullName() << " filter=" << apply_me;
855 if (apply_me) {
856 Ref<VariableMetaData> vmd = var->createMetaDataRef();
857 vmd_list.add(vmd);
858 }
859 }
860}
861
862/*---------------------------------------------------------------------------*/
863/*---------------------------------------------------------------------------*/
864
865void VariableIOReaderMng::
866_readVariablesData(VariableReaderMng& var_read_mng, IDataReaderWrapper* reader)
867{
868 var_read_mng.readVariablesData(m_variable_mng, reader);
869 _finalizeReadVariables(var_read_mng.variablesToRead());
870}
871
872/*---------------------------------------------------------------------------*/
873/*---------------------------------------------------------------------------*/
874
875void VariableIOReaderMng::
876_finalizeReadVariables(const VariableList& vars_to_read)
877{
878 ARCANE_UNUSED(vars_to_read);
879
880 info(4) << "VariableMng: _finalizeReadVariables()";
881
882 // Resynchronise en lecture les valeurs de toutes les variables pour
883 // être sur que les références sont toujours correctes (en cas de
884 // réallocation mémoire).
885 // NOTE: en théorie cela ne doit pas être utile car IVariable::notifyEndRead()
886 // se charge de faire cela.
887 // NOTE: de plus, il n'est nécessaire de le faire que sur les variables
888 // de \a vars_to_read.
889 for (const auto& i : m_variable_mng->m_full_name_variable_map)
890 i.second->syncReferences();
891
892 // Notifie les observateurs qu'une lecture vient d'être faite.
893 m_variable_mng->m_read_observable->notifyAllObservers();
894}
895
896/*---------------------------------------------------------------------------*/
897/*---------------------------------------------------------------------------*/
898
899} // End namespace Arcane
900
901/*---------------------------------------------------------------------------*/
902/*---------------------------------------------------------------------------*/
#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.
Definition Directory.h:33
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.
Definition IDataReader.h:41
virtual void read(IVariable *var, IData *data)=0
Lit les données data de la variable var.
Interface d'une donnée.
Definition IData.h:33
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.
Definition ISubDomain.h:74
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.
Definition IVariable.h:54
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.
Definition DomUtils.cc:426
Gestion d'un document JSON.
Definition JSONReader.h:230
Représente une valeur JSON.
Definition JSONReader.h:43
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
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.
Collection de variables.
Informations de relecture des données d'une variable.
Interface pour utiliser IDataReader ou IDataReader2.
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.
Meta-données sur une variable.
Gestion de la lecture des variables.
Noeud d'un arbre DOM.
Definition XmlNode.h:51
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
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.
Definition Convert.cc:388
-*- 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.