Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
SequentialParallelMng.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/* SequentialParallelMng.cc (C) 2000-2026 */
9/* */
10/* Management of parallelism in the sequential case. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/ReferenceCounter.h"
15
16#include "arccore/message_passing/PointToPointMessageInfo.h"
17
18#include "arcane/utils/Collection.h"
19#include "arcane/utils/ITraceMng.h"
20#include "arcane/utils/NotImplementedException.h"
21#include "arcane/utils/Real2.h"
22#include "arcane/utils/Real2x2.h"
23#include "arcane/utils/Real3.h"
24#include "arcane/utils/Real3x3.h"
25#include "arcane/utils/HPReal.h"
26#include "arcane/utils/NullThreadMng.h"
27#include "arcane/utils/ArgumentException.h"
28
29#include "arcane/core/IIOMng.h"
30#include "arcane/core/ISubDomain.h"
31#include "arcane/core/IApplication.h"
32#include "arcane/core/IParallelDispatch.h"
33#include "arcane/core/ParallelMngDispatcher.h"
34#include "arcane/core/ItemGroup.h"
35#include "arcane/core/IMesh.h"
36#include "arcane/core/IItemFamily.h"
37#include "arcane/core/MeshVariable.h"
38#include "arcane/core/Timer.h"
39#include "arcane/core/FactoryService.h"
40#include "arcane/core/AbstractService.h"
41#include "arcane/core/ISerializer.h"
42#include "arcane/core/internal/SerializeMessage.h"
43#include "arcane/core/internal/ParallelMngInternal.h"
44#include "arcane/core/internal/MachineShMemWinMemoryAllocator.h"
45
46#include "arcane/parallel/IStat.h"
47
48#include "arcane/impl/TimerMng.h"
49#include "arcane/impl/GetVariablesValuesParallelOperation.h"
50#include "arcane/impl/ParallelExchanger.h"
51#include "arcane/impl/ParallelTopology.h"
52#include "arcane/impl/ParallelReplication.h"
53#include "arcane/impl/SequentialParallelSuperMng.h"
54#include "arcane/impl/SequentialParallelMng.h"
55#include "arcane/impl/internal/ParallelMngUtilsFactoryBase.h"
56#include "arcane/impl/internal/VariableSynchronizer.h"
57
58#include "arccore/message_passing/RequestListBase.h"
59#include "arccore/message_passing/internal/SerializeMessageList.h"
60#include "arccore/message_passing/internal/IContigMachineShMemWinBaseInternal.h"
61#include "arccore/message_passing/internal/IMachineShMemWinBaseInternal.h"
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66namespace Arcane
67{
70using namespace Arcane::MessagePassing;
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75extern "C++" IVariableSynchronizer*
76createNullVariableSynchronizer(IParallelMng* pm, const ItemGroup& group);
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
82: public RequestListBase
83{
84 public:
85
86 void _wait(Parallel::eWaitType wait_mode)
87 {
88 ARCANE_UNUSED(wait_mode);
89 }
90};
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
98template <class Type>
99class SequentialParallelDispatchT
100: public TraceAccessor
101, public IParallelDispatchT<Type>
102, public ITypeDispatcher<Type>
103{
104 public:
105
106 typedef Parallel::Request Request;
107 typedef Parallel::eReduceType eReduceType;
108
109 public:
110
111 SequentialParallelDispatchT(ITraceMng* tm)
112 : TraceAccessor(tm)
113 {}
114 void finalize() override {}
115
116 public:
117
118 void broadcast(ArrayView<Type> send_buf, Int32 rank) override
119 {
120 ARCANE_UNUSED(send_buf);
121 ARCANE_UNUSED(rank);
122 }
123 void broadcast(Span<Type> send_buf, Int32 rank) override
124 {
125 ARCANE_UNUSED(send_buf);
126 ARCANE_UNUSED(rank);
127 }
128 void allGather(ConstArrayView<Type> send_buf, ArrayView<Type> recv_buf) override
129 {
130 recv_buf.copy(send_buf);
131 }
132 void allGather(Span<const Type> send_buf, Span<Type> recv_buf) override
133 {
134 recv_buf.copy(send_buf);
135 }
136 void gather(ConstArrayView<Type> send_buf, ArrayView<Type> recv_buf, Int32 rank) override
137 {
138 ARCANE_UNUSED(rank);
139 recv_buf.copy(send_buf);
140 }
141 void gather(Span<const Type> send_buf, Span<Type> recv_buf, Int32 rank) override
142 {
143 ARCANE_UNUSED(rank);
144 recv_buf.copy(send_buf);
145 }
146 void scatterVariable(ConstArrayView<Type> send_buf, ArrayView<Type> recv_buf, Int32 root) override
147 {
148 ARCANE_UNUSED(root);
149 recv_buf.copy(send_buf);
150 }
151 void scatterVariable(Span<const Type> send_buf, Span<Type> recv_buf, Int32 root) override
152 {
153 ARCANE_UNUSED(root);
154 recv_buf.copy(send_buf);
155 }
156 void allGatherVariable(ConstArrayView<Type> send_buf, Array<Type>& recv_buf) override
157 {
158 gatherVariable(send_buf, recv_buf, 0);
159 }
160 void allGatherVariable(Span<const Type> send_buf, Array<Type>& recv_buf) override
161 {
162 gatherVariable(send_buf, recv_buf, 0);
163 }
164 void gatherVariable(ConstArrayView<Type> send_buf, Array<Type>& recv_buf, Int32 rank) override
165 {
166 ARCANE_UNUSED(rank);
167 recv_buf.resize(send_buf.size());
168 ArrayView<Type> av(recv_buf);
169 av.copy(send_buf);
170 }
171 void gatherVariable(Span<const Type> send_buf, Array<Type>& recv_buf, Int32 rank) override
172 {
173 ARCANE_UNUSED(rank);
174 recv_buf.resize(send_buf.size());
175 Span<Type> av(recv_buf.span());
176 av.copy(send_buf);
177 }
178 void allToAll(ConstArrayView<Type> send_buf, ArrayView<Type> recv_buf, Integer count) override
179 {
180 ARCANE_UNUSED(count);
181 recv_buf.copy(send_buf);
182 }
183 void allToAll(Span<const Type> send_buf, Span<Type> recv_buf, Int32 count) override
184 {
185 ARCANE_UNUSED(count);
186 recv_buf.copy(send_buf);
187 }
188 void allToAllVariable(ConstArrayView<Type> send_buf,
189 Int32ConstArrayView send_count,
190 Int32ConstArrayView send_index,
191 ArrayView<Type> recv_buf,
192 Int32ConstArrayView recv_count,
193 Int32ConstArrayView recv_index) override
194 {
195 ARCANE_UNUSED(send_count);
196 ARCANE_UNUSED(recv_count);
197 ARCANE_UNUSED(send_index);
198 ARCANE_UNUSED(recv_index);
199 recv_buf.copy(send_buf);
200 }
201 void allToAllVariable(Span<const Type> send_buf,
202 ConstArrayView<Int32> send_count,
203 ConstArrayView<Int32> send_index,
204 Span<Type> recv_buf,
205 ConstArrayView<Int32> recv_count,
206 ConstArrayView<Int32> recv_index) override
207 {
208 ARCANE_UNUSED(send_count);
209 ARCANE_UNUSED(recv_count);
210 ARCANE_UNUSED(send_index);
211 ARCANE_UNUSED(recv_index);
212 recv_buf.copy(send_buf);
213 }
214 Request send(ConstArrayView<Type> send_buffer, Int32 rank, bool is_blocked) override
215 {
216 return send(Span<const Type>(send_buffer), rank, is_blocked);
217 }
218 Request send(Span<const Type> send_buffer, Int32 rank, bool is_blocked) override
219 {
220 ARCANE_UNUSED(send_buffer);
221 ARCANE_UNUSED(rank);
222 if (is_blocked)
223 throw NotSupportedException(A_FUNCINFO, "blocking send is not allowed in sequential");
224 return Request();
225 }
226 Request send(Span<const Type> send_buffer, const PointToPointMessageInfo& message) override
227 {
228 ARCANE_UNUSED(send_buffer);
229 if (message.isBlocking())
230 throw NotSupportedException(A_FUNCINFO, "blocking send is not allowed in sequential");
231 return Request();
232 }
233 Request recv(ArrayView<Type> recv_buffer, Int32 rank, bool is_blocked) override
234 {
235 return receive(Span<Type>(recv_buffer), rank, is_blocked);
236 }
237 void send(ConstArrayView<Type> send_buffer, Int32 rank) override
238 {
239 ARCANE_UNUSED(send_buffer);
240 ARCANE_UNUSED(rank);
241 throw NotSupportedException(A_FUNCINFO, "send is not allowed in sequential");
242 }
243 void recv(ArrayView<Type> recv_buffer, Int32 rank) override
244 {
245 ARCANE_UNUSED(recv_buffer);
246 ARCANE_UNUSED(rank);
247 throw NotSupportedException(A_FUNCINFO, "recv is not allowed in sequential");
248 }
249 Request receive(Span<Type> recv_buffer, Int32 rank, bool is_blocked) override
250 {
251 ARCANE_UNUSED(recv_buffer);
252 ARCANE_UNUSED(rank);
253 if (is_blocked)
254 throw NotSupportedException(A_FUNCINFO, "blocking receive is not allowed in sequential");
255 return Request();
256 }
257 Request receive(Span<Type> recv_buffer, const PointToPointMessageInfo& message) override
258 {
259 ARCANE_UNUSED(recv_buffer);
260 if (message.isBlocking())
261 throw NotSupportedException(A_FUNCINFO, "blocking receive is not allowed in sequential");
262 return Request();
263 }
264 void sendRecv(ConstArrayView<Type> send_buffer, ArrayView<Type> recv_buffer, Int32 rank) override
265 {
266 ARCANE_UNUSED(rank);
267 recv_buffer.copy(send_buffer);
268 }
269 Type allReduce(eReduceType op, Type v) override
270 {
271 ARCANE_UNUSED(op);
272 return v;
273 }
274 void allReduce(eReduceType op, ArrayView<Type> send_buf) override
275 {
276 ARCANE_UNUSED(op);
277 ARCANE_UNUSED(send_buf);
278 }
279 void allReduce(eReduceType op, ConstArrayView<Type> send_buf, ArrayView<Type> receive_buf) override
280 {
281 ARCANE_UNUSED(op);
282 receive_buf.copy(send_buf);
283 }
284 void allReduce(eReduceType op, Span<Type> send_buf) override
285 {
286 ARCANE_UNUSED(op);
287 ARCANE_UNUSED(send_buf);
288 }
289 void allReduce(eReduceType op, Span<const Type> send_buf, Span<Type> receive_buf) override
290 {
291 ARCANE_UNUSED(op);
292 receive_buf.copy(send_buf);
293 }
294 Request nonBlockingAllReduce(eReduceType op, Span<const Type> send_buf, Span<Type> recv_buf) override
295 {
296 ARCANE_UNUSED(op);
297 ARCANE_UNUSED(send_buf);
298 ARCANE_UNUSED(recv_buf);
299 return Request();
300 }
301 Request nonBlockingAllGather(Span<const Type> send_buf, Span<Type> recv_buf) override
302 {
303 recv_buf.copy(send_buf);
304 return Request();
305 }
306 Request nonBlockingBroadcast(Span<Type> send_buf, Int32 rank) override
307 {
308 ARCANE_UNUSED(send_buf);
309 ARCANE_UNUSED(rank);
310 return Request();
311 }
312 Request nonBlockingGather(Span<const Type> send_buf, Span<Type> recv_buf, Int32 rank) override
313 {
314 ARCANE_UNUSED(rank);
315 recv_buf.copy(send_buf);
316 return Request();
317 }
318 Request nonBlockingAllToAll(Span<const Type> send_buf, Span<Type> recv_buf, Int32 count) override
319 {
320 ARCANE_UNUSED(count);
321 recv_buf.copy(send_buf);
322 return Request();
323 }
324 Request nonBlockingAllToAllVariable(Span<const Type> send_buf, ConstArrayView<Int32> send_count,
325 ConstArrayView<Int32> send_index, Span<Type> recv_buf,
326 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) override
327 {
328 ARCANE_UNUSED(send_count);
329 ARCANE_UNUSED(recv_count);
330 ARCANE_UNUSED(send_index);
331 ARCANE_UNUSED(recv_index);
332 recv_buf.copy(send_buf);
333 return Request();
334 }
335 Type scan(eReduceType op, Type v) override
336 {
337 ARCANE_UNUSED(op);
338 return v;
339 }
340 void scan(eReduceType op, ArrayView<Type> send_buf) override
341 {
342 ARCANE_UNUSED(op);
343 ARCANE_UNUSED(send_buf);
344 }
345 void computeMinMaxSum(Type val, Type& min_val, Type& max_val, Type& sum_val,
346 Int32& min_rank,
347 Int32& max_rank) override
348 {
349 min_val = max_val = sum_val = val;
350 min_rank = max_rank = 0;
351 }
352 void computeMinMaxSum(ConstArrayView<Type> values,
353 ArrayView<Type> min_values,
354 ArrayView<Type> max_values,
355 ArrayView<Type> sum_values,
356 ArrayView<Int32> min_ranks,
357 ArrayView<Int32> max_ranks) override
358 {
359 const Integer n = values.size();
360 for (Integer i = 0; i < n; ++i) {
361 min_values[i] = max_values[i] = sum_values[i] = values[i];
362 min_ranks[i] = max_ranks[i] = 0;
363 }
364 }
365 ITypeDispatcher<Type>* toArccoreDispatcher() override { return this; }
366};
367
368/*---------------------------------------------------------------------------*/
369/*---------------------------------------------------------------------------*/
370
371class SequentialContigMachineShMemWinBaseInternal
373{
374 public:
375
376 SequentialContigMachineShMemWinBaseInternal(Int64 sizeof_segment, Int32 sizeof_type)
377 : m_sizeof_segment(sizeof_segment)
378 , m_max_sizeof_segment(sizeof_segment)
379 , m_sizeof_type(sizeof_type)
380 , m_segment(sizeof_segment)
381 {}
382
383 ~SequentialContigMachineShMemWinBaseInternal() override = default;
384
385 public:
386
387 Int32 sizeofOneElem() const override
388 {
389 return m_sizeof_type;
390 }
391
393 {
394 return m_segment.span().subSpan(0, m_sizeof_segment);
395 }
396 Span<std::byte> segmentView(const Int32 rank) override
397 {
398 if (rank != 0) {
399 ARCANE_FATAL("Rank {0} is unavailable (Sequential)", rank);
400 }
401 return m_segment.span().subSpan(0, m_sizeof_segment);
402 }
404 {
405 return m_segment.span().subSpan(0, m_sizeof_segment);
406 }
407
409 {
410 return m_segment.constSpan().subSpan(0, m_sizeof_segment);
411 }
413 {
414 if (rank != 0) {
415 ARCANE_FATAL("Rank {0} is unavailable (Sequential)", rank);
416 }
417 return m_segment.constSpan().subSpan(0, m_sizeof_segment);
418 }
420 {
421 return m_segment.constSpan().subSpan(0, m_sizeof_segment);
422 }
423
424 void resizeSegment(const Int64 new_sizeof_segment) override
425 {
426 if (new_sizeof_segment > m_max_sizeof_segment) {
427 ARCANE_FATAL("New size of window (sum of size of all segments) is superior than the old size");
428 }
429 m_sizeof_segment = new_sizeof_segment;
430 }
431
433 {
434 return ConstArrayView<Int32>{ 1, &m_my_rank };
435 }
436
437 void barrier() const override {}
438
439 private:
440
441 Int64 m_sizeof_segment = 0;
442 Int64 m_max_sizeof_segment = 0;
443
444 Int32 m_sizeof_type = 0;
445 UniqueArray<std::byte> m_segment;
446 Int32 m_my_rank = 0;
447};
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
452class SequentialMachineShMemWinBaseInternal
454{
455 public:
456
457 SequentialMachineShMemWinBaseInternal(Int64 sizeof_segment, Int32 sizeof_type)
458 : m_sizeof_type(sizeof_type)
459 , m_segment(sizeof_segment)
460 {}
461 ~SequentialMachineShMemWinBaseInternal() override = default;
462
463 public:
464
465 Int32 sizeofOneElem() const override
466 {
467 return m_sizeof_type;
468 }
470 {
471 return ConstArrayView<Int32>{ 1, &m_my_rank };
472 }
473 void barrier() const override {}
474
476 {
477 return m_segment;
478 }
480 {
481 if (rank != 0) {
482 ARCANE_FATAL("Rank {0} is unavailable (Sequential)", rank);
483 }
484 return m_segment;
485 }
487 {
488 return m_segment;
489 }
491 {
492 if (rank != 0) {
493 ARCANE_FATAL("Rank {0} is unavailable (Sequential)", rank);
494 }
495 return m_segment;
496 }
497 void add(Span<const std::byte> elem) override
498 {
499 if (elem.size() % m_sizeof_type != 0) {
500 ARCCORE_FATAL("Sizeof elem not valid");
501 }
502 m_segment.addRange(elem);
503 }
504 void add() override {}
506 {
507 if (rank != 0) {
508 ARCANE_FATAL("Rank {0} is unavailable (Sequential)", rank);
509 }
510 if (elem.size() % m_sizeof_type != 0) {
511 ARCCORE_FATAL("Sizeof elem not valid");
512 }
513 m_segment.addRange(elem);
514 }
515 void addToAnotherSegment() override {}
516
517 void reserve(Int64 new_capacity) override
518 {
519 m_segment.reserve(new_capacity);
520 }
521 void reserve() override {}
522 void resize(Int64 new_size) override
523 {
524 m_segment.resize(new_size);
525 }
526 void resize() override {}
527 void shrink() override
528 {
529 m_segment.shrink();
530 }
531
532 private:
533
534 Int32 m_sizeof_type;
535 UniqueArray<std::byte> m_segment;
536 Int32 m_my_rank = 0;
537};
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
544{
545 public:
546
552 {
553 return makeRef(createNullVariableSynchronizer(pm, family->allItems()));
554 }
556 {
557 return makeRef(createNullVariableSynchronizer(pm, group));
558 }
559};
560
561/*---------------------------------------------------------------------------*/
562/*---------------------------------------------------------------------------*/
563
570class SequentialParallelMng
571: public ParallelMngDispatcher
572{
573 public:
574
575 class Impl;
576
577 private:
578
579 // Constructs a sequential manager.
580 SequentialParallelMng(const SequentialParallelMngBuildInfo& bi);
581
582 public:
583
584 ~SequentialParallelMng();
585
586 bool isParallel() const override { return false; }
587 Int32 commRank() const override { return 0; }
588 Int32 commSize() const override { return 1; }
589 void* getMPICommunicator() override { return m_communicator.communicatorAddress(); }
590 Parallel::Communicator communicator() const override { return m_communicator; }
591 Parallel::Communicator machineCommunicator() const override { return m_communicator; }
592 bool isThreadImplementation() const override { return false; }
593 bool isHybridImplementation() const override { return false; }
594 void setBaseObject(IBase* m);
595 ITraceMng* traceMng() const override { return m_trace.get(); }
596 IThreadMng* threadMng() const override { return m_thread_mng; }
597 ITimerMng* timerMng() const override { return m_timer_mng; }
598 IParallelMng* worldParallelMng() const override { return m_world_parallel_mng; }
599 IIOMng* ioMng() const override { return m_io_mng; }
600
601 void initialize() override;
602 bool isMasterIO() const override { return true; }
603 Int32 masterIORank() const override { return 0; }
604
605 public:
606
607 void allGather(ISerializer* send_serializer, ISerializer* recv_serializer) override
608 {
609 recv_serializer->copy(send_serializer);
610 }
611 void sendSerializer(ISerializer* values, Int32 rank) override
612 {
613 ARCANE_UNUSED(values);
614 ARCANE_UNUSED(rank);
615 }
616 Request sendSerializer(ISerializer* values, Int32 rank, ByteArray& bytes) override
617 {
618 ARCANE_UNUSED(values);
619 ARCANE_UNUSED(rank);
620 ARCANE_UNUSED(bytes);
621 return Parallel::Request();
622 }
624 {
625 ARCANE_UNUSED(rank);
626 return new SerializeMessage(0, 0, ISerializeMessage::MT_Send);
627 }
628 void recvSerializer(ISerializer* values, Int32 rank) override
629 {
630 ARCANE_UNUSED(values);
631 ARCANE_UNUSED(rank);
632 }
634 {
635 ARCANE_UNUSED(rank);
636 return new SerializeMessage(0, 0, ISerializeMessage::MT_Recv);
637 }
638
639 void broadcastString(String& str, Int32 rank) override
640 {
641 ARCANE_UNUSED(str);
642 ARCANE_UNUSED(rank);
643 }
644 void broadcastMemoryBuffer(ByteArray& bytes, Int32 rank) override
645 {
646 ARCANE_UNUSED(bytes);
647 ARCANE_UNUSED(rank);
648 }
649 void broadcastSerializer(ISerializer* values, Int32 rank) override
650 {
651 ARCANE_UNUSED(values);
652 ARCANE_UNUSED(rank);
653 }
654 MessageId probe(const PointToPointMessageInfo& message) override
655 {
656 ARCANE_UNUSED(message);
657 return MessageId();
658 }
660 {
661 ARCANE_UNUSED(message);
662 return MessageSourceInfo();
663 }
664 Request sendSerializer(const ISerializer* values, const PointToPointMessageInfo& message) override
665 {
666 ARCANE_UNUSED(values);
667 ARCANE_UNUSED(message);
668 return Parallel::Request();
669 }
670 Request receiveSerializer(ISerializer* values, const PointToPointMessageInfo& message) override
671 {
672 ARCANE_UNUSED(values);
673 ARCANE_UNUSED(message);
674 return Parallel::Request();
675 }
676
678 {
679 ARCANE_UNUSED(messages);
680 }
682 {
683 ARCANE_UNUSED(requests);
684 }
685
686 void printStats() override {}
687 void barrier() override {}
688
689 IParallelMng* sequentialParallelMng() override { return this; }
690 Ref<IParallelMng> sequentialParallelMngRef() override { return makeRef<IParallelMng>(this); }
691
692 void waitAllRequests(ArrayView<Request> requests) override
693 {
694 ARCANE_UNUSED(requests);
695 }
696
697 // The requests are necessarily already satisfied.
699 {
700 ARCANE_UNUSED(requests);
701 return UniqueArray<Integer>();
702 }
704 {
705 return waitSomeRequests(requests);
706 }
707
708 ISerializeMessageList* _createSerializeMessageList() override
709 {
711 }
712 Real reduceRank(eReduceType rt, Real v, Int32* rank)
713 {
714 Real rv = reduce(rt, v);
715 if (rank)
716 *rank = 0;
717 return rv;
718 }
728 {
729 return new ParallelExchanger(this);
730 }
732 {
733 return createNullVariableSynchronizer(this, family->allItems());
734 }
736 {
737 return createNullVariableSynchronizer(this, group);
738 }
740 {
741 ParallelTopology* t = new ParallelTopology(this);
742 t->initialize();
743 return t;
744 }
745
747 {
748 return m_replication;
749 }
750
752 {
753 delete m_replication;
754 m_replication = v;
755 }
756
758 {
760 return makeRef(r);
761 }
762
764 {
765 return m_utils_factory;
766 }
767
769 {
770 return m_stat;
771 }
772
773 void build() override;
774
776
777 IParallelMngInternal* _internalApi() override { return m_parallel_mng_internal; }
778
779 public:
780
781 static IParallelMng* create(const SequentialParallelMngBuildInfo& bi)
782 {
783 if (!bi.traceMng())
784 ARCANE_THROW(ArgumentException, "null traceMng()");
785 if (!bi.threadMng())
786 ARCANE_THROW(ArgumentException, "null threadMng()");
787 auto x = new SequentialParallelMng(bi);
788 x->build();
789 return x;
790 }
792 {
793 return makeRef(create(bi));
794 }
795
796 protected:
797
798 IParallelMng* _createSubParallelMng(Int32ConstArrayView kept_ranks) override
799 {
800 ARCANE_UNUSED(kept_ranks);
801 SequentialParallelMngBuildInfo bi(m_timer_mng, m_world_parallel_mng);
802 bi.setThreadMng(m_thread_mng);
803 bi.setTraceMng(m_trace.get());
804 bi.setCommunicator(m_communicator);
805 return create(bi);
806 }
807
808 private:
809
810 ReferenceCounter<ITraceMng> m_trace;
811 IThreadMng* m_thread_mng = nullptr;
812 ITimerMng* m_timer_mng = nullptr;
813 IParallelMng* m_world_parallel_mng = nullptr;
814 IIOMng* m_io_mng;
815 Parallel::IStat* m_stat;
816 IParallelReplication* m_replication;
817 MP::Communicator m_communicator;
818 Ref<IParallelMngUtilsFactory> m_utils_factory;
819 IParallelMngInternal* m_parallel_mng_internal = nullptr;
820};
821
822/*---------------------------------------------------------------------------*/
823/*---------------------------------------------------------------------------*/
824
825extern "C++" IIOMng*
826arcaneCreateIOMng(IParallelMng* psm);
827
828/*---------------------------------------------------------------------------*/
829/*---------------------------------------------------------------------------*/
830
831extern "C++" IParallelMng*
832arcaneCreateSequentialParallelMng(const SequentialParallelMngBuildInfo& bi)
833{
834 return SequentialParallelMng::create(bi);
835}
836extern "C++" Ref<IParallelMng>
837arcaneCreateSequentialParallelMngRef(const SequentialParallelMngBuildInfo& bi)
838{
839 return SequentialParallelMng::createRef(bi);
840}
841
842/*---------------------------------------------------------------------------*/
843/*---------------------------------------------------------------------------*/
844
846: public ParallelMngInternal
847{
848 public:
849
850 explicit Impl(SequentialParallelMng* pm)
851 : ParallelMngInternal(pm)
852 , m_alloc(makeRef(new MachineShMemWinMemoryAllocator(pm)))
853 {}
854
855 ~Impl() override = default;
856
857 public:
858
859 Int32 masterParallelIORank() const override { return 0; }
860 Int32 nbSendersToMasterParallelIO() const override { return 1; }
861
862 void initializeWindowCreator() override {}
863
865 {
866 return true;
867 }
868
870 {
871 return makeRef(new SequentialContigMachineShMemWinBaseInternal(sizeof_segment, sizeof_type));
872 }
873
875 {
876 return makeRef(new SequentialMachineShMemWinBaseInternal(sizeof_segment, sizeof_type));
877 }
878
880 {
881 return MemoryAllocationOptions{ m_alloc.get() };
882 }
884 {
885 return { 1, &m_rank };
886 }
887 void machineBarrier() override {}
888
889 private:
890
892 const Int32 m_rank = 0;
893};
894
895/*---------------------------------------------------------------------------*/
896/*---------------------------------------------------------------------------*/
897
898SequentialParallelMng::
899SequentialParallelMng(const SequentialParallelMngBuildInfo& bi)
901, m_trace(bi.traceMng())
902, m_thread_mng(bi.threadMng())
903, m_timer_mng(bi.m_timer_mng)
904, m_world_parallel_mng(bi.m_world_parallel_mng)
905, m_io_mng(nullptr)
906, m_stat(nullptr)
907, m_replication(new ParallelReplication())
908, m_communicator(bi.communicator())
910, m_parallel_mng_internal(new Impl(this))
911{
912 ARCANE_CHECK_PTR(m_trace);
913 ARCANE_CHECK_PTR(m_thread_mng);
914 if (!m_world_parallel_mng)
915 m_world_parallel_mng = this;
917 _setCommunicator(m_communicator);
918}
919
920/*---------------------------------------------------------------------------*/
921/*---------------------------------------------------------------------------*/
922
923SequentialParallelMng::
924~SequentialParallelMng()
925{
926 delete m_parallel_mng_internal;
927 delete m_stat;
928 delete m_replication;
929 delete m_io_mng;
930}
931
932/*---------------------------------------------------------------------------*/
933/*---------------------------------------------------------------------------*/
934
935void SequentialParallelMng::
936setBaseObject(IBase* sd)
937{
938 ARCANE_UNUSED(sd);
939}
940
941/*---------------------------------------------------------------------------*/
942/*---------------------------------------------------------------------------*/
943
944namespace
945{
946 // Class to create the different dispatchers
947 class DispatchCreator
948 {
949 public:
950
951 DispatchCreator(ITraceMng* tm)
952 : m_tm(tm)
953 {}
954
955 public:
956
957 template <typename DataType> SequentialParallelDispatchT<DataType>*
958 create()
959 {
960 return new SequentialParallelDispatchT<DataType>(m_tm);
961 }
962 ITraceMng* m_tm;
963 };
964} // namespace
965
967build()
968{
969 m_io_mng = arcaneCreateIOMng(this);
970 DispatchCreator creator(m_trace.get());
971 this->createDispatchers(creator);
972}
973
974/*---------------------------------------------------------------------------*/
975/*---------------------------------------------------------------------------*/
976
979{
980 traceMng()->info() << "** ** MPI Communicator = " << getMPICommunicator();
981}
982
983/*---------------------------------------------------------------------------*/
984/*---------------------------------------------------------------------------*/
985
986/*---------------------------------------------------------------------------*/
987/*---------------------------------------------------------------------------*/
988
989// Constructs a sequential supervisor linked to the \a sm supervisor
990SequentialParallelSuperMng::
991SequentialParallelSuperMng(const ServiceBuildInfo& sbi)
992: AbstractService(sbi)
993, m_application(sbi.application())
994, m_thread_mng(new NullThreadMng())
995, m_timer_mng(nullptr)
996{
997}
998
999/*---------------------------------------------------------------------------*/
1000/*---------------------------------------------------------------------------*/
1001
1002// Constructs a sequential supervisor linked to the \a sm supervisor
1003SequentialParallelSuperMng::
1004SequentialParallelSuperMng(const ServiceBuildInfo& sbi, Parallel::Communicator comm)
1005: AbstractService(sbi)
1006, m_application(sbi.application())
1007, m_thread_mng(new NullThreadMng())
1008, m_timer_mng(nullptr)
1009, m_communicator(comm)
1010{
1011}
1012
1013/*---------------------------------------------------------------------------*/
1014/*---------------------------------------------------------------------------*/
1015
1016// Constructs a sequential supervisor linked to the \a sm supervisor
1017SequentialParallelSuperMng::
1018~SequentialParallelSuperMng()
1019{
1020 delete m_thread_mng;
1021}
1022
1023/*---------------------------------------------------------------------------*/
1024/*---------------------------------------------------------------------------*/
1025
1037
1038/*---------------------------------------------------------------------------*/
1039/*---------------------------------------------------------------------------*/
1040
1042build()
1043{
1044 if (!m_timer_mng) {
1045 m_owned_timer_mng = new TimerMng(traceMng());
1046 m_timer_mng = m_owned_timer_mng.get();
1047 }
1048}
1049
1050/*---------------------------------------------------------------------------*/
1051/*---------------------------------------------------------------------------*/
1052
1055{
1056 if (local_rank != 0)
1057 ARCANE_THROW(ArgumentException, "Bad local_rank '{0}' (should be 0)", local_rank);
1058
1059 SequentialParallelMngBuildInfo bi(m_timer_mng, nullptr);
1060 bi.setThreadMng(threadMng());
1061 bi.setTraceMng(traceMng());
1062 bi.setCommunicator(communicator());
1063 return SequentialParallelMng::createRef(bi);
1064}
1065
1066/*---------------------------------------------------------------------------*/
1067/*---------------------------------------------------------------------------*/
1068
1073
1074/*---------------------------------------------------------------------------*/
1075/*---------------------------------------------------------------------------*/
1076
1079
1080/*---------------------------------------------------------------------------*/
1081/*---------------------------------------------------------------------------*/
1082
1083class SequentialParallelMngBuilder
1085{
1086 public:
1087
1088 SequentialParallelMngBuilder(IApplication* app, Parallel::Communicator comm)
1089 : m_application(app)
1090 , m_thread_mng(new NullThreadMng())
1091 , m_timer_mng(new TimerMng(app->traceMng()))
1092 , m_communicator(comm)
1093 {}
1094 ~SequentialParallelMngBuilder() override
1095 {
1096 delete m_timer_mng;
1097 delete m_thread_mng;
1098 }
1099
1100 public:
1101
1102 void build() {}
1103 Ref<IParallelMng> _createParallelMng(Int32 local_rank, ITraceMng* tm) override;
1104
1105 public:
1106
1107 IApplication* m_application;
1108 IThreadMng* m_thread_mng;
1109 ITimerMng* m_timer_mng;
1110 Parallel::Communicator m_communicator;
1111};
1112
1113/*---------------------------------------------------------------------------*/
1114/*---------------------------------------------------------------------------*/
1115
1117_createParallelMng(Int32 local_rank, ITraceMng* tm)
1118{
1119 if (local_rank != 0)
1120 ARCANE_THROW(ArgumentException, "Bad local_rank '{0}' (should be 0)", local_rank);
1121
1122 SequentialParallelMngBuildInfo bi(m_timer_mng, nullptr);
1123 bi.setTraceMng(tm);
1124 bi.setThreadMng(m_thread_mng);
1125 bi.setCommunicator(m_communicator);
1126 return arcaneCreateSequentialParallelMngRef(bi);
1127}
1128
1129/*---------------------------------------------------------------------------*/
1130/*---------------------------------------------------------------------------*/
1131
1132class SequentialParallelMngContainerFactory
1133: public AbstractService
1135{
1136 public:
1137
1138 SequentialParallelMngContainerFactory(const ServiceBuildInfo& sbi)
1139 : AbstractService(sbi)
1140 , m_application(sbi.application())
1141 {}
1142
1143 public:
1144
1147 {
1148 ARCANE_UNUSED(nb_rank);
1149 ARCANE_UNUSED(machine_comm);
1150 auto x = new SequentialParallelMngBuilder(m_application, comm);
1151 x->build();
1153 }
1154
1155 private:
1156
1157 IApplication* m_application;
1158};
1159
1160/*---------------------------------------------------------------------------*/
1161/*---------------------------------------------------------------------------*/
1162
1164 ServiceProperty("SequentialParallelMngContainerFactory", ST_Application),
1166
1167/*---------------------------------------------------------------------------*/
1168/*---------------------------------------------------------------------------*/
1169
1170} // End namespace Arcane
1171
1172/*---------------------------------------------------------------------------*/
1173/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
Base class of a service.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
Modifiable view of an array of type T.
void copy(const U &copy_array)
Copies the array copy_array into the instance.
constexpr Integer size() const noexcept
Returns the size of the array.
Base class for 1D data vectors.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Operations to access variable values from another subdomain.
Application interface.
Interface of the base class for main arcane objects.
Definition IBase.h:32
virtual ITraceMng * traceMng() const =0
Trace manager.
Operations to access variable values from another subdomain.
Interface of the input/output manager.
Definition IIOMng.h:37
Interface of an entity family.
Definition IItemFamily.h:85
virtual ItemGroup allItems() const =0
Group of all entities.
Parallel message handling for the type Type.
Information exchange between processors.
Interface for an 'IParallelMng' container factory.
Internal part of IParallelMng.
Interface of a factory for the utility functions of IParallelMng.
Interface of the parallelism manager for a subdomain.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
Interface for non-blocking collective parallel operations.
Brief information on parallel subdomain replication.
Abstract class of the parallelism supervisor.
Information on the computing core allocation topology.
virtual void copy(const ISerializer *from)=0
Copies the data from from into this instance.
Interface of a thread manager.
Definition IThreadMng.h:32
Interface of a timer manager.
Definition ITimerMng.h:50
virtual TraceMessage info()=0
Stream for an information message.
Sends values across different processors.
Interface of a variable synchronization service.
Mesh entity group.
Definition ItemGroup.h:51
Communicator for message exchange.
Class allowing the creation of a memory window for a node of computation.
Class allowing the creation of memory windows for a computing node.
Parallel message handling for the type Type.
Information about the source of a message.
Information for sending/receiving a point-to-point message.
bool isBlocking() const
Indicates if the message is blocking.
Thread manager in single-threaded mode.
Information exchange between processors.
Redirects the message management of sub-domains according to the argument type.
IMessagePassingMng * messagePassingMng() const override
Associated Arccore message passing manager.
Base class of a factory for IParallelMng utility functions.
Brief information on parallel subdomain replication.
Information on the topology for allocating computing cores.
virtual void initialize()
Initializes the instance. This operation is collective.
Reference to an instance.
Span< std::byte > segmentView() override
Method allowing the retrieval of a view of its segment.
Int32 sizeofOneElem() const override
Method allowing the retrieval of the size of an element in the window.
void resizeSegment(const Int64 new_sizeof_segment) override
Method allowing the resizing of the window segments.
Span< const std::byte > windowConstView() const override
Method allowing the retrieval of a view of the entire window.
Span< const std::byte > segmentConstView() const override
Method allowing the retrieval of a view of its segment.
ConstArrayView< Int32 > machineRanks() const override
Method allowing the retrieval of the ranks that possess a segment in the window.
Span< std::byte > segmentView(const Int32 rank) override
Method allowing the retrieval of a view of the segment of another subdomain of the node.
void barrier() const override
Method allowing waiting until all processes/threads of the node call this method to continue executio...
Span< const std::byte > segmentConstView(const Int32 rank) const override
Method allowing the retrieval of a view of the segment of another subdomain of the node.
Span< std::byte > windowView() override
Method allowing the retrieval of a view of the entire window.
Span< const std::byte > segmentConstView() const override
Method to get a view of our segment.
Span< const std::byte > segmentConstView(Int32 rank) const override
Method to get a view of the segment of another subdomain of the node.
void addToAnotherSegment(Int32 rank, Span< const std::byte > elem) override
Method to add elements into the segment of another subdomain.
void barrier() const override
Method to wait until all processes/threads of the node call this method to continue execution.
ConstArrayView< Int32 > machineRanks() const override
Method to get the ranks that possess a segment in the window.
void shrink() override
Method to reduce the reserved memory space for the segments to the minimum necessary.
void add(Span< const std::byte > elem) override
Method to add elements into our segment.
Span< std::byte > segmentView() override
Method to get a view of our segment.
void reserve(Int64 new_capacity) override
Method to reserve memory space in our segment.
Int32 sizeofOneElem() const override
Method to get the size of an element in the window.
Span< std::byte > segmentView(Int32 rank) override
Method to get a view of the segment of another subdomain of the node.
void resize(Int64 new_size) override
Method to resize our segment.
Message interface for type Type.
Ref< IParallelMng > _createParallelMng(Int32 local_rank, ITraceMng *tm) override
Creates the IParallelMng for the local rank local_rank.
Ref< IParallelMngContainer > _createParallelMngBuilder(Int32 nb_rank, Parallel::Communicator comm, Parallel::Communicator machine_comm) override
Creates a container for nb_local_rank local ranks and with communicator as the communicator.
Ref< ITransferValuesParallelOperation > createTransferValuesOperation(IParallelMng *) override
Returns an operation to transfer values between ranks.
Ref< IVariableSynchronizer > createSynchronizer(IParallelMng *pm, const ItemGroup &group) override
Returns an interface to synchronize variables on the group group.
Ref< IVariableSynchronizer > createSynchronizer(IParallelMng *pm, IItemFamily *family) override
Returns an interface to synchronize variables on the group of the family family.
Ref< IMachineShMemWinBaseInternal > createMachineShMemWinBase(Int64 sizeof_segment, Int32 sizeof_type) override
Method allowing the creation of a dynamic memory window on the node.
Ref< IContigMachineShMemWinBaseInternal > createContigMachineShMemWinBase(Int64 sizeof_segment, Int32 sizeof_type) override
Method allowing the creation of a memory window on the node.
ConstArrayView< Int32 > machineRanks() override
Method allowing retrieval of the ranks of the sub-domains of the computing node.
void machineBarrier() override
Method allowing a barrier for the sub-domains of the computing node.
void initializeWindowCreator() override
Method allowing the initialization of the windowCreator specific to the implementation.
bool isMachineShMemWinAvailable() override
Method allowing to know if shared memory mode is supported.
MemoryAllocationOptions machineShMemWinMemoryAllocator() override
Method allowing retrieval of a shared memory allocator.
Sequential mode parallelism manager.
Parallel::Communicator communicator() const override
MPI communicator associated with this instance.
ISerializeMessage * createReceiveSerializer(Int32 rank) override
Creates a non-blocking message to receive serialized data from rank rank.
IParallelNonBlockingCollective * nonBlockingCollective() const override
Interface for non-blocking collective operations.
ITransferValuesParallelOperation * createTransferValuesOperation() override
Returns an operation to transfer values between subdomains.
IThreadMng * threadMng() const override
Thread manager.
UniqueArray< Integer > testSomeRequests(ArrayView< Request > requests) override
Tests if one of the rvalues requests is complete.
Int32 commRank() const override
Rank of this instance in the communicator.
ISerializeMessage * createSendSerializer(Int32 rank) override
Creates a non-blocking message to send serialized data to rank rank.
Int32 commSize() const override
Number of instances in the communicator.
IParallelMng * sequentialParallelMng() override
Returns a sequential parallelism manager.
void build() override
Constructs the instance.
void barrier() override
Performs a barrier.
void allGather(ISerializer *send_serializer, ISerializer *recv_serializer) override
Redefines allGather here to avoid hiding the symbol in derived classes.
Parallel::Communicator machineCommunicator() const override
MPI communicator derived from the communicator communicator() gathering all processes of the compute ...
IGetVariablesValuesParallelOperation * createGetVariablesValuesOperation() override
Returns an operation to retrieve the values of a variable on the entities of another subdomain.
IParallelReplication * replication() const override
Replication information.
ITimerMng * timerMng() const override
Timer manager.
MessageId probe(const PointToPointMessageInfo &message) override
Probes if messages are available.
Ref< IParallelMngUtilsFactory > _internalUtilsFactory() const override
Factory for utility functions.
MessageSourceInfo legacyProbe(const PointToPointMessageInfo &message) override
Probes if messages are available.
void processMessages(ConstArrayView< ISerializeMessage * > messages) override
Executes the operations of messages messages.
bool isMasterIO() const override
true if the instance is a master I/O manager.
bool isThreadImplementation() const override
Indicates if the implementation uses threads.
Ref< IRequestList > createRequestListRef() override
Creates a request list for this manager.
Parallel::IStat * stat() override
Statistics manager.
void printStats() override
Prints statistics related to this parallelism manager.
ITraceMng * traceMng() const override
Trace manager.
void initialize() override
Initializes the parallelism manager.
IParallelMng * worldParallelMng() const override
Parallelism manager over all allocated resources.
bool isHybridImplementation() const override
Indicates if the implementation uses hybrid mode.
IParallelTopology * createTopology() override
Creates an instance containing information about the rank topology of this manager.
bool isParallel() const override
Returns true if the execution is parallel.
void setReplication(IParallelReplication *v) override
Sets the Replication Information.
void freeRequests(ArrayView< Parallel::Request > requests) override
Frees the requests.
void waitAllRequests(ArrayView< Request > requests) override
Blocks while waiting for the rvalues requests to complete.
UniqueArray< Integer > waitSomeRequests(ArrayView< Request > requests) override
Blocks while waiting for one of the rvalues requests to complete.
IParallelMngInternal * _internalApi() override
Internal Arcane API.
void broadcastMemoryBuffer(ByteArray &bytes, Int32 rank) override
Performs a broadcast of a memory region.
IVariableSynchronizer * createSynchronizer(const ItemGroup &group) override
Returns an interface for synchronizing variables on the group.
IIOMng * ioMng() const override
I/O manager.
Int32 masterIORank() const override
Rank of the instance managing I/O (for which isMasterIO() is true).
IVariableSynchronizer * createSynchronizer(IItemFamily *family) override
Returns an interface for synchronizing variables on the group of the family.
IParallelExchanger * createExchanger() override
Returns an interface for transferring messages between processors.
Request sendSerializer(ISerializer *values, Int32 rank, ByteArray &bytes) override
void * getMPICommunicator() override
Address of the MPI communicator associated with this manager.
Sequential parallelism supervisor.
void initialize() override
Initializes the instance.
Ref< IParallelMng > internalCreateWorldParallelMng(Int32 local_rank) override
Creates a parallelism manager for all allocated cores.
MP::Communicator communicator() const override
MPI communicator associated with this manager.
void tryAbort() override
Attempts to abort.
void build() override
Build-level construction of the service.
IApplication * m_application
Associated supervisor.
IThreadMng * threadMng() const override
Thread manager.
void _wait(Parallel::eWaitType wait_mode)
Performs the wait or test.
Message using a SerializeBuffer.
IApplication * application() const
Access to the associated IApplication.
Structure containing the information to create a service.
Service creation properties.
__host__ __device__ void copy(const U &copy_array)
Copies the array copy_array into the instance.
Definition Span.h:475
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:325
View of an array of elements of type T.
Definition Span.h:633
constexpr __host__ __device__ Span< T, DynExtent > subSpan(Int64 abegin, Int64 asize) const
Sub-view starting from element abegin and containing asize elements.
Definition Span.h:734
Timer manager.
Definition TimerMng.h:40
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
Declarations of types and methods used by message exchange mechanisms.
eReduceType
Supported reduction types.
IStat * createDefaultStat()
Creates a default instance.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Ref< TrueType > createRef(Args &&... args)
Creates an instance of type TrueType with arguments Args and returns a reference to it.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
Array< Byte > ByteArray
Dynamic one-dimensional array of characters.
Definition UtilsTypes.h:115
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:476
@ ST_Application
The service is used at the application level.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.
Type
Type of JSON value.
Definition rapidjson.h:730
Information to construct a SequentialParallelMng.