Arcane  v4.1.7.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
HybridMachineShMemWinBaseInternalCreator.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/* HybridMachineShMemWinBaseInternalCreator.cc (C) 2000-2026 */
9/* */
10/* Classe permettant de créer des objets de type */
11/* HybridContigMachineShMemWinBaseInternal. Une instance de cet objet doit */
12/* être partagée par tous les threads d'un processus. */
13/*---------------------------------------------------------------------------*/
14
15#include "arcane/utils/FatalErrorException.h"
16
17#include "arcane/parallel/mpithread/internal/HybridMachineShMemWinBaseInternalCreator.h"
18
19#include "arcane/parallel/mpi/MpiParallelMng.h"
20#include "arcane/parallel/mpithread/internal/HybridContigMachineShMemWinBaseInternal.h"
21#include "arcane/parallel/mpithread/internal/HybridMachineShMemWinBaseInternal.h"
22#include "arcane/parallel/mpithread/HybridMessageQueue.h"
23
24#include "arccore/concurrency/IThreadBarrier.h"
25#include "arccore/message_passing_mpi/internal/MpiAdapter.h"
26#include "arccore/message_passing_mpi/internal/MpiMachineShMemWinBaseInternalCreator.h"
27#include "arccore/message_passing_mpi/internal/MpiContigMachineShMemWinBaseInternal.h"
28#include "arccore/message_passing_mpi/internal/MpiMultiMachineShMemWinBaseInternal.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39HybridMachineShMemWinBaseInternalCreator::
40HybridMachineShMemWinBaseInternalCreator(Int32 nb_rank_local_proc, IThreadBarrier* barrier)
41: m_nb_rank_local_proc(nb_rank_local_proc)
42, m_barrier(barrier)
43, m_sizeof_resize_segments(nb_rank_local_proc)
44{}
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49void HybridMachineShMemWinBaseInternalCreator::
50initializeMpiWindowCreator(Int32 my_rank_global, MpiParallelMng* mpi_parallel_mng)
51{
52 FullRankInfo my_fri = FullRankInfo::compute(MP::MessageRank(my_rank_global), m_nb_rank_local_proc);
53 Int32 my_rank_local_proc = my_fri.localRankValue();
54 if (my_rank_local_proc == 0) {
55 // mpi_parallel_mng->adapter()->initializeWindowCreator(mpi_parallel_mng->machineCommunicator()); // Géré par le MpiParallelMng
56 _buildMachineRanksArray(mpi_parallel_mng->adapter()->windowCreator()->machineRanks());
57 }
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63HybridContigMachineShMemWinBaseInternal* HybridMachineShMemWinBaseInternalCreator::
64createWindow(Int32 my_rank_global, Int64 sizeof_segment, Int32 sizeof_type, MpiParallelMng* mpi_parallel_mng)
65{
66 // On est dans un contexte où chaque processus doit avoir plusieurs segments, un par thread.
67 // Pour que chaque processus puisse avoir accès à toutes les positions des segments de tous les
68 // threads de tous les processus, chaque processus doit partager les positions de ces segments avec
69 // les autres processus. Pour faire ça, on utilise des fenêtres mémoire MPI.
70
71 FullRankInfo my_fri = FullRankInfo::compute(MP::MessageRank(my_rank_global), m_nb_rank_local_proc);
72 Int32 my_rank_local_proc = my_fri.localRankValue();
73 Int32 my_rank_mpi = my_fri.mpiRankValue();
74
75 Mpi::MpiMachineShMemWinBaseInternalCreator* mpi_window_creator = nullptr;
76
77 if (my_rank_local_proc == 0) {
78 mpi_window_creator = mpi_parallel_mng->adapter()->windowCreator();
79
80 // Le nombre d'éléments de chaque segment. Cette fenêtre fera une taille de nb_thread * nb_proc_sur_le_même_noeud.
81 m_sizeof_sub_segments = makeRef(mpi_window_creator->createWindow(m_nb_rank_local_proc * static_cast<Int64>(sizeof(Int64)), sizeof(Int64)));
82 m_sum_sizeof_sub_segments = makeRef(mpi_window_creator->createWindow(m_nb_rank_local_proc * static_cast<Int64>(sizeof(Int64)), sizeof(Int64)));
83 }
84 m_barrier->wait();
85
86 // nb_elem est le segment de notre processus (qui contient les segments de tous nos threads).
87 Span<Int64> sizeof_sub_segments = asSpan<Int64>(m_sizeof_sub_segments->segmentView());
88
89 sizeof_sub_segments[my_rank_local_proc] = sizeof_segment;
90 m_barrier->wait();
91
92 if (my_rank_local_proc == 0) {
93 m_sizeof_segment_local_proc = 0;
94 Span<Int64> sum_sizeof_sub_segments = asSpan<Int64>(m_sum_sizeof_sub_segments->segmentView());
95
96 for (Int32 i = 0; i < m_nb_rank_local_proc; ++i) {
97 sum_sizeof_sub_segments[i] = m_sizeof_segment_local_proc;
98 m_sizeof_segment_local_proc += sizeof_sub_segments[i];
99 }
100 }
101 m_barrier->wait();
102
103 if (my_rank_local_proc == 0) {
104 m_window = makeRef(mpi_window_creator->createWindow(m_sizeof_segment_local_proc, sizeof_type));
105 }
106 m_barrier->wait();
107
108 auto* window_obj = new HybridContigMachineShMemWinBaseInternal(my_rank_mpi, my_rank_local_proc, m_nb_rank_local_proc, m_machine_ranks, sizeof_type, m_sizeof_sub_segments, m_sum_sizeof_sub_segments, m_window, m_barrier);
109 m_barrier->wait();
110
111 // Ces tableaux doivent être delete par HybridContigMachineShMemWinBaseInternal.
112 if (my_rank_local_proc == 0) {
113 m_sizeof_sub_segments.reset();
114 m_sum_sizeof_sub_segments.reset();
115 m_sizeof_segment_local_proc = 0;
116 m_window.reset();
117 }
118
119 return window_obj;
120}
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
125HybridMachineShMemWinBaseInternal* HybridMachineShMemWinBaseInternalCreator::
126createDynamicWindow(Int32 my_rank_global, Int64 sizeof_segment, Int32 sizeof_type, MpiParallelMng* mpi_parallel_mng)
127{
128 FullRankInfo my_fri = FullRankInfo::compute(MP::MessageRank(my_rank_global), m_nb_rank_local_proc);
129 Int32 my_rank_local_proc = my_fri.localRankValue();
130 Int32 my_rank_mpi = my_fri.mpiRankValue();
131
132 Mpi::MpiMachineShMemWinBaseInternalCreator* mpi_window_creator = nullptr;
133
134 if (my_rank_local_proc == 0) {
135 mpi_window_creator = mpi_parallel_mng->adapter()->windowCreator();
136 }
137 m_barrier->wait();
138
139 m_sizeof_resize_segments[my_rank_local_proc] = sizeof_segment;
140 m_barrier->wait();
141
142 if (my_rank_local_proc == 0) {
143 m_windows = makeRef(mpi_window_creator->createDynamicMultiWindow(m_sizeof_resize_segments.smallSpan(), m_nb_rank_local_proc, sizeof_type));
144 m_sizeof_resize_segments.fill(0);
145 }
146 m_barrier->wait();
147
148 auto* window_obj = new HybridMachineShMemWinBaseInternal(my_rank_mpi, my_rank_local_proc, m_nb_rank_local_proc, m_machine_ranks, sizeof_type, m_windows, m_barrier);
149 m_barrier->wait();
150
151 // Ces tableaux doivent être delete par HybridMachineShMemWinBaseInternal.
152 if (my_rank_local_proc == 0) {
153 m_windows.reset();
154 }
155
156 return window_obj;
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
162ConstArrayView<Int32> HybridMachineShMemWinBaseInternalCreator::
163machineRanks()
164{
165 return m_machine_ranks;
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
171void HybridMachineShMemWinBaseInternalCreator::
172machineBarrier(Int32 my_rank_global, MpiParallelMng* mpi_parallel_mng) const
173{
174 FullRankInfo my_fri = FullRankInfo::compute(MP::MessageRank(my_rank_global), m_nb_rank_local_proc);
175 Int32 my_rank_local_proc = my_fri.localRankValue();
176 m_barrier->wait();
177 if (my_rank_local_proc == 0)
178 mpi_parallel_mng->barrier();
179 m_barrier->wait();
180}
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
184
185void HybridMachineShMemWinBaseInternalCreator::
186_buildMachineRanksArray(ConstArrayView<Int32> mpi_machine_ranks)
187{
188 m_machine_ranks.resize(mpi_machine_ranks.size() * m_nb_rank_local_proc);
189
190 Int32 iter = 0;
191 for (Int32 mpi_rank : mpi_machine_ranks) {
192 for (Int32 thread_rank = 0; thread_rank < m_nb_rank_local_proc; ++thread_rank) {
193 m_machine_ranks[iter++] = thread_rank + m_nb_rank_local_proc * mpi_rank;
194 }
195 }
196}
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201} // namespace Arcane::MessagePassing
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
Déclarations des types et méthodes utilisés par les mécanismes d'échange de messages.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.