Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
CheckpointMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* CheckpointMng.cc (C) 2000-2025 */
9/* */
10/* Protection Manager. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15#include "arcane/utils/TraceAccessor.h"
16#include "arcane/utils/String.h"
17#include "arcane/utils/ScopedPtr.h"
18#include "arcane/utils/IOException.h"
19#include "arcane/utils/TraceInfo.h"
20#include "arcane/utils/Array.h"
21#include "arcane/utils/NotImplementedException.h"
22#include "arcane/utils/ITraceMng.h"
23
24#include "arcane/core/Directory.h"
25#include "arcane/core/ICheckpointMng.h"
26#include "arcane/core/ISubDomain.h"
27#include "arcane/core/IParallelMng.h"
28#include "arcane/core/IParallelReplication.h"
29#include "arcane/core/IRessourceMng.h"
30#include "arcane/core/IVariableMng.h"
31#include "arcane/core/IIOMng.h"
32#include "arcane/core/IXmlDocumentHolder.h"
33#include "arcane/core/XmlNode.h"
34#include "arcane/core/ICheckpointReader.h"
35#include "arcane/core/ICheckpointWriter.h"
36#include "arcane/core/ServiceBuilder.h"
37#include "arcane/core/IObservable.h"
38#include "arcane/core/CheckpointInfo.h"
39#include "arcane/core/SubDomainBuildInfo.h"
40#include "arcane/core/MeshPartInfo.h"
41
42#include "arcane/core/VariableCollection.h"
43#include "arcane/core/IVariable.h"
44#include "arcane/core/IMeshModifier.h"
45#include "arcane/core/ItemGroup.h"
46#include "arcane/core/IItemFamily.h"
47#include "arcane/core/IMainFactory.h"
48#include "arcane/core/IPrimaryMesh.h"
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53namespace Arcane
54{
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59extern "C++" ISubDomain*
60arcaneCreateSubDomain(ISession* session, const SubDomainBuildInfo& sdbi);
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
68class CheckpointMng
69: public TraceAccessor
70, public ICheckpointMng
71{
72 public:
73 public:
74
75 CheckpointMng(ISubDomain*);
76 ~CheckpointMng() override;
77
78 public:
79
80 void readCheckpoint() override;
81 void readDefaultCheckpoint() override;
83 void readCheckpoint(ICheckpointReader* reader) override;
84 void readCheckpoint(ByteConstArrayView infos) override;
85 void readCheckpoint(const CheckpointInfo& checkpoint_infos) override;
86 CheckpointInfo readCheckpointInfo(Span<const Byte> infos, const String& buf_name) override;
87
88 void writeCheckpoint(ICheckpointWriter* writer) override;
89 void writeCheckpoint(ICheckpointWriter* writer, ByteArray& infos) override;
90 void writeDefaultCheckpoint(ICheckpointWriter* writer) override;
93
94 public:
95
96 void build();
97
98 private:
99
100 ISubDomain* m_sub_domain;
103
104 private:
105
106 void _writeCheckpointInfoFile(ICheckpointWriter* checkpoint_writer, ByteArray& infos);
107 CheckpointInfo _readCheckpointInfo(Span<const Byte> infos, const String& info_file_name);
108 void _readCheckpoint(const CheckpointInfo& checkpoint_info);
109 void _readCheckpoint(const CheckpointReadInfo& infos);
111 void _applyNbSubDomainChange(const CheckpointInfo& ci, ICheckpointReader2* reader);
112 void _changeItemsOwner(IMesh* mesh, Int32ConstArrayView old_ranks_to_new_ranks);
113};
114
115/*---------------------------------------------------------------------------*/
116/*---------------------------------------------------------------------------*/
117
118extern "C++" ICheckpointMng*
119arcaneCreateCheckpointMng(ISubDomain* sd)
120{
121 CheckpointMng* cm = new CheckpointMng(sd);
122 cm->build();
123 return cm;
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
129CheckpointMng::
130CheckpointMng(ISubDomain* sd)
131: TraceAccessor(sd->traceMng())
132, m_sub_domain(sd)
133, m_write_observable(IObservable::createDefault())
134, m_read_observable(IObservable::createDefault())
135{
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
141CheckpointMng::
142~CheckpointMng()
143{
144 m_read_observable->detachAllObservers();
145 m_write_observable->detachAllObservers();
146
147 delete m_read_observable;
148 delete m_write_observable;
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
156
157void CheckpointMng::
158build()
159{
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
173
176{
177 m_sub_domain->variableMng()->readCheckpoint(reader);
178 m_read_observable->notifyAllObservers();
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
184void CheckpointMng::
185_readCheckpoint(const CheckpointReadInfo& infos)
186{
187 m_sub_domain->variableMng()->readCheckpoint(infos);
189}
190
191/*---------------------------------------------------------------------------*/
192/*---------------------------------------------------------------------------*/
193
196{
197 // Reads the file containing the info from the previous execution to
198 // know the protection/recovery service used
199 String info_file_name(m_sub_domain->exportDirectory().file("checkpoint_info.xml"));
200 ByteUniqueArray bytes;
201 IIOMng* io_mng = m_sub_domain->ioMng();
202 io_mng->collectiveRead(info_file_name, bytes);
203 CheckpointInfo checkpoint_info = _readCheckpointInfo(bytes, info_file_name);
204 return checkpoint_info;
205}
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
212{
213 CheckpointInfo checkpoint_info = readDefaultCheckpointInfo();
214 _readCheckpoint(checkpoint_info);
215}
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
222{
223 CheckpointInfo checkpoint_info = _readCheckpointInfo(bytes_infos, "unknown");
224 _readCheckpoint(checkpoint_info);
225}
226
227/*---------------------------------------------------------------------------*/
228/*---------------------------------------------------------------------------*/
229
231readCheckpointInfo(Span<const Byte> bytes_infos, const String& buf_name)
232{
233 String buf_name2 = buf_name;
234 if (buf_name2.null())
235 buf_name2 = "unknown";
236 CheckpointInfo checkpoint_info = _readCheckpointInfo(bytes_infos, buf_name2);
237 return checkpoint_info;
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243CheckpointInfo CheckpointMng::
244_readCheckpointInfo(Span<const Byte> bytes_infos, const String& info_file_name)
245{
246 CheckpointInfo checkpoint_info;
247
248 // By default, reads the info based on the IParallelMng associated with the subdomain
249 IParallelMng* pm = m_sub_domain->parallelMng();
250 Int32 rank = pm->commRank();
251 checkpoint_info.setSubDomainRank(rank);
252 Int32 replication_rank = pm->replication()->replicationRank();
253 checkpoint_info.setReplicationRank(replication_rank);
254
255 ITraceMng* tm = m_sub_domain->traceMng();
256 auto xml_doc_ptr = IXmlDocumentHolder::loadFromBuffer(bytes_infos, info_file_name, tm);
257 ScopedPtrT<IXmlDocumentHolder> xml_doc(xml_doc_ptr);
258 XmlNode doc_node = xml_doc->documentNode();
259 if (doc_node.null())
260 ARCANE_FATAL("Can not read file '{0}' containing checkpoint/restart informations",
261 info_file_name);
262
263 XmlNode doc_elem = doc_node.documentElement();
264
265 Int32 nb_checkpoint_sub_domain = doc_elem.attr("nb-sub-domain").valueAsInteger();
266 checkpoint_info.setNbSubDomain(nb_checkpoint_sub_domain);
267
268 Int32 nb_checkpoint_replication = doc_elem.attr("nb-replication").valueAsInteger();
269 checkpoint_info.setNbReplication(nb_checkpoint_replication);
270
271 XmlNode service_elem = doc_elem.child("service");
272 String service_name = service_elem.attrValue("name");
273 if (service_name.null()) {
275 "The file '{0}}' doesn't have "
276 "the name of the protection/restore service used "
277 "(attribute /checkpoint-info/service/@name)",
278 info_file_name);
279 }
280 checkpoint_info.setServiceName(service_name);
281 String service_directory = service_elem.attrValue("directory");
282 checkpoint_info.setDirectory(service_directory);
283
284 XmlNode times_node = doc_node.documentElement().child("times");
285
286 XmlNode last_index_attr = times_node.attr("last-index");
287 if (last_index_attr.null())
288 ARCANE_THROW(IOException, "missing attribute 'last-index'");
289
290 XmlNode last_time_attr = times_node.attr("last-time");
291 if (last_time_attr.null())
292 ARCANE_THROW(IOException, "missing attribute 'last-time'");
293
294 Real last_time = last_time_attr.valueAsReal();
295 checkpoint_info.setCheckpointTime(last_time);
296
297 Integer last_index = last_index_attr.valueAsInteger();
298 checkpoint_info.setCheckpointIndex(last_index);
299
300 XmlNode meta_data_node = service_elem.child("meta-data");
301 if (meta_data_node.null())
302 ARCANE_THROW(IOException, "missing tag 'meta-data'");
303 checkpoint_info.setReaderMetaData(meta_data_node.value());
304
305 return checkpoint_info;
306}
307
308/*---------------------------------------------------------------------------*/
309/*---------------------------------------------------------------------------*/
310
312readCheckpoint(const CheckpointInfo& checkpoint_info)
313{
314 _readCheckpoint(checkpoint_info);
315}
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
319
320void CheckpointMng::
321_readCheckpoint(const CheckpointInfo& checkpoint_info)
322{
323 String service_name = checkpoint_info.serviceName();
324 if (service_name.null())
326
327 String service_directory = checkpoint_info.directory();
328
329 bool has_changing_sub_domain = _checkChangingNbSubDomain(checkpoint_info);
330
331 IApplication* app = m_sub_domain->application();
332 // Tries to use the ICheckpointReader2 interface if available.
333 // Note that the service implementing ICheckpointReader2 is an application
334 // service, whereas for ICheckpointReader it is a subdomain service.
335 // If it is not available, it uses the ICheckpointReader implementation.
336 // S'il n'est pas disponible, utilise l'implémentation ICheckpointReader.
337 // With the new implementation, it is possible to handle the case where
338 // the number of sub-domains changes.
339 {
341 Ref<ICheckpointReader2> s(sb.createReference(service_name, SB_AllowNull));
342 if (s.get()) {
343 info() << "Using the checkpoint/restart service"
344 << " <" << service_name << "> (implement ICheckpointReader2)";
345 if (has_changing_sub_domain)
346 _applyNbSubDomainChange(checkpoint_info, s.get());
347 else {
348 CheckpointReadInfo cri(checkpoint_info);
349 IParallelMng* pm = m_sub_domain->parallelMng();
350 cri.setParallelMng(pm);
351 cri.setReader(s.get());
352 _readCheckpoint(cri);
353 }
354 return;
355 }
356 }
357 // With the old implementation, it is not possible to change
358 // the number of sub-domains
359 if (has_changing_sub_domain)
360 ARCANE_FATAL("The number of sub-domains/replica in this run is different "
361 "from the number in checkpoint but the service specified "
362 "for checkpoint {0} does not handle this case",
363 service_name);
364
365 ServiceFinder2T<ICheckpointReader, ISubDomain> sf2(app, m_sub_domain);
366 Ref<ICheckpointReader> checkpoint_reader(sf2.createReference(service_name));
367
368 if (!checkpoint_reader.get()) {
369 ARCANE_FATAL("The service specified for checkpoint/restart ({0}) is not available",
370 service_name);
371 }
372
373 info() << "Using the checkpoint/restart service <" << service_name << ">";
374 Real last_time = checkpoint_info.checkpointTime();
375 Int32 last_index = checkpoint_info.checkpointIndex();
376
377 checkpoint_reader->setCurrentTimeAndIndex(last_time, last_index);
378
379 String meta_data = checkpoint_info.readerMetaData();
380 checkpoint_reader->setReaderMetaData(meta_data);
381 checkpoint_reader->setBaseDirectoryName(service_directory);
382
383 readCheckpoint(checkpoint_reader.get());
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
400{
401 ByteUniqueArray bytes_infos;
402 writeCheckpoint(writer, bytes_infos);
403
404 if (m_sub_domain->allReplicaParallelMng()->isMasterIO()) {
405 Directory export_directory(m_sub_domain->exportDirectory());
406 String info_file(export_directory.file("checkpoint_info.xml"));
407 std::ofstream ofile(info_file.localstr());
408 ofile.write((const char*)bytes_infos.unguardedBasePointer(), bytes_infos.size());
409 if (!ofile.good())
410 ARCANE_THROW(IOException, "Can not write file '{0}'", info_file);
411 }
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
419{
420 m_write_observable->notifyAllObservers();
421 m_sub_domain->variableMng()->writeCheckpoint(writer);
422 _writeCheckpointInfoFile(writer, infos);
423}
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
427
429_writeCheckpointInfoFile(ICheckpointWriter* checkpoint_writer, ByteArray& infos)
430{
431 ISubDomain* sd = m_sub_domain;
432 IParallelMng* pm = sd->parallelMng();
434
435 Int32 nb_rank = pm->commSize();
436 Int32 nb_replica = pr->nbReplication();
437
438 ScopedPtrT<IXmlDocumentHolder> info_document;
439
440 RealConstArrayView checkpoints_time = checkpoint_writer->checkpointTimes();
441
442 IRessourceMng* rm = sd->ressourceMng();
443 info_document = rm->createXmlDocument();
444 XmlNode doc = info_document->documentNode();
445 XmlElement root(doc, "checkpoint-info");
446
447 // Saves info about the number of replicas and sub-domains.
448 // This will later allow restarts by changing
449 // the number of sub-domains or replicas.
450 root.setAttrValue("nb-sub-domain", String::fromNumber(nb_rank));
451 root.setAttrValue("nb-replication", String::fromNumber(nb_replica));
452
453 XmlElement service_info(root, "service");
454 String reader_name = checkpoint_writer->readerServiceName();
455 service_info.setAttrValue("name", reader_name);
456 service_info.setAttrValue("directory", checkpoint_writer->baseDirectoryName());
457
458 String reader_meta_data = checkpoint_writer->readerMetaData();
459 XmlElement meta_data_elem(service_info, "meta-data", reader_meta_data);
460 XmlElement checkpoints_time_elem(root, "times");
461
462 XmlNode info_root = info_document->documentNode().documentElement();
463
464 {
465 // Saves the information of the last checkpoint
466 Integer nb_checkpoint = checkpoints_time.size();
467 if (nb_checkpoint > 0) {
468 checkpoints_time_elem.setAttrValue("last-time", String::fromNumber(checkpoints_time[nb_checkpoint - 1]));
469 checkpoints_time_elem.setAttrValue("last-index", String::fromNumber(nb_checkpoint - 1));
470 }
471 }
472 checkpoints_time_elem.clear();
473 for (Integer i = 0, is = checkpoints_time.size(); i < is; ++i) {
474 XmlElement elem(checkpoints_time_elem, "time");
475 elem.setAttrValue("value", String::fromNumber(checkpoints_time[i]));
476 }
477
478 info_document->save(infos);
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
490{
491 // Checks that the number of sub-domains and replicas is the same between
492 // the checkpoint and the current run.
493 Int32 nb_checkpoint_sub_domain = ci.nbSubDomain();
494 Int32 nb_checkpoint_replication = ci.nbReplication();
495 // If we do not have the info (or if it is invalid) about the number of
496 // sub-domains or replicas, we consider that the partitioning is not changing.
497 // This can happen if the 'checkpoint_info' file is too old
498 // or was not written by this CheckpointMng.
499 if (nb_checkpoint_sub_domain < 1 || nb_checkpoint_replication < 1) {
500 info() << "Invalid or missing partitionning info in checkpoint.";
501 return false;
502 }
503 info() << "Reading checkpoint nb_sub_domain=" << nb_checkpoint_sub_domain
504 << " nb_replication=" << nb_checkpoint_replication;
505 MeshPartInfo current_part_info(makeMeshPartInfoFromParallelMng(m_sub_domain->parallelMng()));
506
507 Int32 nb_rank = current_part_info.nbPart();
508 Int32 nb_replication = current_part_info.nbReplication();
509 bool has_different_sub_domain = false;
510 if (nb_rank != nb_checkpoint_sub_domain) {
511 has_different_sub_domain = true;
512 }
513 // For now, we do not support changing the number of replicas.
514 if (nb_replication != nb_checkpoint_replication) {
516 "Bad number of replication ({0} in checkpoint, {1} in this run)",
517 nb_checkpoint_replication, nb_replication);
518 }
519 return has_different_sub_domain;
520}
521
522/*---------------------------------------------------------------------------*/
523/*---------------------------------------------------------------------------*/
524
525void CheckpointMng::
526_changeItemsOwner(IMesh* mesh, Int32ConstArrayView old_ranks_to_new_ranks)
527{
528 Int32 mesh_rank = mesh->meshPartInfo().partRank();
529 // Changes the owners of all families
530 for (IItemFamily* family : mesh->itemFamilies()) {
531 const ItemGroup& all_items = family->allItems();
532 // Changes the owners to match the new partitioning.
533 ENUMERATE_ITEM (iitem, all_items) {
534 Item item = *iitem;
535 Int32 owner = item.owner();
536 item.mutableItemBase().setOwner(old_ranks_to_new_ranks[owner], mesh_rank);
537 }
538 family->notifyItemsOwnerChanged();
539 }
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
545void CheckpointMng::
546_applyNbSubDomainChange(const CheckpointInfo& ci, ICheckpointReader2* reader)
547{
548 ISubDomain* sd1 = m_sub_domain;
549 IApplication* app = sd1->application();
550 IParallelMng* pm = sd1->parallelMng();
551 Int32 nb_old_rank = ci.nbSubDomain();
552 Int32 my_rank = pm->commRank();
553 Int32 nb_rank = pm->commSize();
554 if (nb_rank > nb_old_rank)
555 ARCANE_THROW(NotImplementedException, "Increasing number of sub-domains (old={0} new={1})",
556 nb_old_rank, nb_rank);
557 UniqueArray<Int32> old_ranks_to_new_ranks(nb_old_rank);
558 UniqueArray<Int32> ranks_to_read;
559 for (Integer i = 0; i < nb_old_rank; ++i) {
560 Int32 new_rank = i % nb_rank;
561 old_ranks_to_new_ranks[i] = new_rank;
562 if (new_rank == my_rank)
563 ranks_to_read.add(i);
564 }
565 info() << "OLD_RANKS_TO_NEW_RANKS=" << old_ranks_to_new_ranks;
566 info() << "RANKS_TO_READ=" << ranks_to_read;
567 info() << "Apply Changing nb sub domain my_rank=" << my_rank;
568 String service_name = ci.serviceName();
569 // TODO: create a new parallelMng() for each created sub-domain
570 // (to have an ITraceMng per sub-domain)
571 IParallelMng* pm2 = pm->sequentialParallelMng();
572 UniqueArray<ISubDomain*> sd_to_merge_list2;
573 UniqueArray<Byte> case_bytes;
574 sd1->fillCaseBytes(case_bytes);
575
576 String message_passing_service = "SequentialParallelMngContainerFactory";
577 ServiceBuilder<IParallelMngContainerFactory> sf(app);
578 auto pbf = sf.createReference(message_passing_service, SB_AllowNull);
579 if (!pbf)
580 ARCANE_FATAL("Can not find service '{0}' implementing IParallelMngContainerFactory", message_passing_service);
581 Ref<IParallelMngContainer> parallel_builder(pbf->_createParallelMngBuilder(1, pm2->communicator(), pm2->machineCommunicator()));
582
583 for (Int32 i : ranks_to_read) {
584 info() << "Reading Part sub_domain index=" << i;
585 info() << "Using the checkpoint/restart service"
586 << " <" << service_name << "> (implement ICheckpointReader2)";
587 CheckpointInfo checkpoint_info2(ci);
588 checkpoint_info2.setSubDomainRank(i);
589 CheckpointReadInfo cri(checkpoint_info2);
590 cri.setReader(reader);
591 cri.setParallelMng(pm2);
592 bool is_first = (i == my_rank);
593 ISubDomain* sd2 = nullptr;
594 if (is_first) {
595 sd2 = sd1;
596 }
597 else {
598 String file_suffix = String::format("s_{0}_{1}", my_rank, i);
599 ITraceMng* tm = app->createAndInitializeTraceMng(sd1->traceMng(), file_suffix);
600 Ref<IParallelMng> sub_pm = parallel_builder->_createParallelMng(0, tm);
601 SubDomainBuildInfo sdbi(sub_pm, i);
602 sdbi.setCaseFileName(sd1->caseFullFileName());
603 sdbi.setCaseBytes(case_bytes);
604
605 // TODO: protect arcaneCreateSubDomain()
606 // in a critical section.
607 // We use arcaneCreateSubDomain() directly to avoid
608 // adding the created sub-domain to the list of sub-domains
609 // of the session (this can cause problems because then we won't
610 // really know how to destroy it)
611 sd2 = arcaneCreateSubDomain(sd1->session(), sdbi);
612 sd2->initialize();
613 sd2->readCaseMeshes();
614
615 sd_to_merge_list2.add(sd2);
616 sd2->setIsContinue();
617 sd2->allocateMeshes();
618 }
619 sd2->variableMng()->readCheckpoint(cri);
620 sd2->checkpointMng()->readObservable()->notifyAllObservers();
621 // We must indicate that the variables are used otherwise
622 // they will not be transferred. The additional sub-domains
623 // do not create the modules, so it is possible that the sub-domain
624 // sd1 has more variables than the others. This is the case with the
625 // NoDump variables which do not exist in the other sub-domains.
626 // Therefore, they should not be initialized.
627 // TODO: it would be preferable to take the variables from the
628 // mesh common to all meshes that will be merged.
629 VariableCollection vars = sd2->variableMng()->variables();
630 for (VariableCollection::Enumerator ivar(vars); ++ivar;) {
631 IVariable* var = *ivar;
632 if (var->isUsed())
633 continue;
634 if ((var->property() & IVariable::PNoDump) != 0)
635 continue;
636 // Do not process variables that are not on families.
637 if (var->itemFamilyName().null())
638 continue;
639 var->setUsed(true);
640 info() << "LIST_VAR name=" << var->fullName();
641 }
642 }
643 UniqueArray<IMesh*> meshes_to_merge;
644 for (ISubDomain* sd_to_merge : sd_to_merge_list2) {
645 meshes_to_merge.add(sd_to_merge->defaultMesh());
646 }
647
648 // Changes the owners of the meshes so that they reference the
649 // new ranks.
650 _changeItemsOwner(sd1->defaultMesh(), old_ranks_to_new_ranks);
651 for (IMesh* mesh : meshes_to_merge)
652 _changeItemsOwner(mesh, old_ranks_to_new_ranks);
653
654 {
655 IMesh* mesh = sd1->defaultMesh();
656 // Proceeds with the merging of meshes
657 mesh->modifier()->mergeMeshes(meshes_to_merge);
658 // Updates IMesh::meshPartInfo() because
659 // the number of mesh parts has changed.
660 MeshPartInfo p(makeMeshPartInfoFromParallelMng(mesh->parallelMng()));
661 mesh->toPrimaryMesh()->setMeshPartInfo(p);
662 }
663
664 // TODO: destroy the created sub-domains
665}
666
667/*---------------------------------------------------------------------------*/
668/*---------------------------------------------------------------------------*/
669
670} // namespace Arcane
671
672/*---------------------------------------------------------------------------*/
673/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
Integer size() const
Number of elements in the vector.
Information about a checkpoint.
Protection Manager.
IObservable * m_write_observable
Observable for writing.
void readDefaultCheckpoint() override
Reads a default checkpoint.
IObservable * readObservable() override
Read observable.
void writeCheckpoint(ICheckpointWriter *writer) override
Writes a default checkpoint using the writer.
void _writeCheckpointInfoFile(ICheckpointWriter *checkpoint_writer, ByteArray &infos)
CheckpointInfo readCheckpointInfo(Span< const Byte > infos, const String &buf_name) override
Reads checkpoint information.
IObservable * writeObservable() override
Write observable.
void writeDefaultCheckpoint(ICheckpointWriter *writer) override
Writes a checkpoint using the writer.
bool _checkChangingNbSubDomain(const CheckpointInfo &ci)
Checks if the number of sub-domains has changed between the checkpoint and the current allocation.
void readCheckpoint() override
Reads a checkpoint.
CheckpointInfo readDefaultCheckpointInfo() override
Reads default checkpoint information.
IObservable * m_read_observable
Observable for reading.
Checkpoint reading information.
constexpr Integer size() const noexcept
Number of elements in the array.
Class managing a directory.
Definition Directory.h:36
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Definition Directory.cc:120
Application interface.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual IRessourceMng * ressourceMng() const =0
Resource manager.
Interface of the checkpoint information manager.
Interface for the protection/recovery reading service (V2).
Interface for the protection/recovery reading service.
Interface of the checkpoint/recovery write service.
virtual ConstArrayView< Real > checkpointTimes() const =0
Checkpoint times.
virtual String readerServiceName() const =0
Name of the reader service associated with this writer.
virtual String readerMetaData() const =0
Metadata for the reader associated with this writer.
virtual String baseDirectoryName() const =0
Name of the checkpoint base directory.
Interface of the input/output manager.
Definition IIOMng.h:37
virtual bool collectiveRead(const String &filename, ByteArray &bytes)=0
Collective reading of a file.
Interface of an entity family.
Definition IItemFamily.h:83
virtual void mergeMeshes(ConstArrayView< IMesh * > meshes)=0
Merges the meshes of meshes with the current mesh.
virtual IMeshModifier * modifier()=0
Associated modifier interface.
Exception when an input/output error is detected.
Definition IOException.h:34
virtual void notifyAllObservers()=0
Notifies all observers.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual IParallelReplication * replication() const =0
Replication information.
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual ARCANE_DEPRECATED Integer nbSubDomain() const final
Total number of subdomains.
Brief information on parallel subdomain replication.
virtual Int32 replicationRank() const =0
Rank in the replication (from 0 to nbReplication()-1).
virtual Int32 nbReplication() const =0
Number of replications.
Interface of a resource manager.
virtual IXmlDocumentHolder * createXmlDocument()=0
Creates an XML document node.
Interface for a case execution session.
Definition ISession.h:38
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual IApplication * application()=0
Application.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual IVariableMng * variableMng()=0
Returns the variable manager.
virtual void readCheckpoint(ICheckpointReader *reader)=0
Reads all variables from a checkpoint.
@ PNoDump
Indicates that the variable should not be saved.
Definition IVariable.h:62
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Loads an XML document.
Definition DomUtils.cc:425
Mesh entity group.
Definition ItemGroup.h:51
Base class for a mesh element.
Definition Item.h:84
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
Definition Item.h:394
Int32 owner() const
Owner subdomain number of the entity.
Definition Item.h:252
Information about a partitioned mesh.
void setOwner(Integer suid, Int32 current_sub_domain)
Sets the sub-domain number of the entity owner.
Exception when a 'parallel' fatal error is generated.
Reference to an instance.
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
Utility class for instantiating a service of a given interface.
View of an array of elements of type T.
Definition Span.h:635
bool null() const
Returns true if the string is null.
Definition String.cc:306
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
Parameters necessary for building a subdomain.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
Element of a DOM tree.
Definition XmlNode.h:406
Node of a DOM tree.
Definition XmlNode.h:51
XmlNode attr(const String &name, bool throw_exception=false) const
Returns the attribute of name name.
Definition XmlNode.cc:257
XmlNode documentElement() const
Returns the document element.
Definition XmlNode.cc:565
String attrValue(const String &name, bool throw_exception=false) const
Value of attribute name.
Definition XmlNode.cc:234
XmlNode child(const String &name) const
Child node of this node with name name.
Definition XmlNode.cc:73
void clear()
Deletes all child nodes.
Definition XmlNode.cc:302
bool null() const
True if the node is null.
Definition XmlNode.h:303
Integer valueAsInteger(bool throw_exception=false) const
Node value converted to integer.
Definition XmlNode.cc:441
void setAttrValue(const String &name, const String &value)
Sets the attribute name to the value value.
Definition XmlNode.cc:248
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
@ SB_AllowNull
Allows the service to be absent.
Int32 Integer
Type representing an integer.
Array< Byte > ByteArray
Dynamic one-dimensional array of characters.
Definition UtilsTypes.h:121
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
UniqueArray< Byte > ByteUniqueArray
Dynamic 1D array of characters.
Definition UtilsTypes.h:335
double Real
Type representing a real number.
ConstArrayView< Byte > ByteConstArrayView
C equivalent of a 1D array of characters.
Definition UtilsTypes.h:476
std::int32_t Int32
Signed integer type of 32 bits.
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.
Definition UtilsTypes.h:488