Arcane  v3.16.6.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MpiMachineMemoryWindowBaseInternal.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* MpiMachineMemoryWindowBaseInternal.h (C) 2000-2025 */
9/* */
10/* Classe permettant de créer une fenêtre mémoire pour un noeud */
11/* de calcul avec MPI. Cette fenêtre sera contigüe pour tous les processus */
12/* d'un même noeud. */
13/*---------------------------------------------------------------------------*/
14
15#include "arccore/message_passing_mpi/internal/MpiMachineMemoryWindowBaseInternal.h"
16
17#include "arccore/base/FatalErrorException.h"
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace Arcane::MessagePassing::Mpi
23{
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28MpiMachineMemoryWindowBaseInternal::
29MpiMachineMemoryWindowBaseInternal(Int64 sizeof_segment, Int32 sizeof_type, const MPI_Comm& comm_machine, Int32 comm_machine_rank, Int32 comm_machine_size, ConstArrayView<Int32> machine_ranks)
30: m_win()
31, m_win_sizeof_segments()
32, m_win_sum_sizeof_segments()
33, m_comm_machine(comm_machine)
34, m_comm_machine_size(comm_machine_size)
35, m_comm_machine_rank(comm_machine_rank)
36, m_sizeof_type(sizeof_type)
37, m_machine_ranks(machine_ranks)
38, m_max_sizeof_win(0)
39, m_actual_sizeof_win(-1)
40{
41 MPI_Info win_info;
42 MPI_Info_create(&win_info);
43 MPI_Info_set(win_info, "alloc_shared_noncontig", "false");
44
45 {
46 void* ptr_seg = nullptr;
47 int error = MPI_Win_allocate_shared(sizeof_segment, m_sizeof_type, win_info, m_comm_machine, &ptr_seg, &m_win);
48
49 if (error != MPI_SUCCESS) {
50 ARCCORE_FATAL("Error with MPI_Win_allocate_shared() call");
51 }
52 }
53
54 //--------------------------
55
56 {
57 Int64* ptr_seg = nullptr;
58 int error = MPI_Win_allocate_shared(sizeof(Int64), sizeof(Int64), win_info, m_comm_machine, &ptr_seg, &m_win_sizeof_segments);
59
60 if (error != MPI_SUCCESS) {
61 ARCCORE_FATAL("Error with MPI_Win_allocate_shared() call");
62 }
63 *ptr_seg = sizeof_segment;
64 }
65 {
66 Int64* ptr_seg = nullptr;
67 int error = MPI_Win_allocate_shared(sizeof(Int64), sizeof(Int64), win_info, m_comm_machine, &ptr_seg, &m_win_sum_sizeof_segments);
68
69 if (error != MPI_SUCCESS) {
70 ARCCORE_FATAL("Error with MPI_Win_allocate_shared() call");
71 }
72 }
73
74 MPI_Info_free(&win_info);
75
76 MPI_Barrier(m_comm_machine);
77 //--------------------------
78
79#ifdef ARCCORE_DEBUG
80 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
81 {
82 MPI_Aint size_seg;
83 int size_type;
84 Int64* ptr_seg = nullptr;
85 int error = MPI_Win_shared_query(m_win_sizeof_segments, i, &size_seg, &size_type, &ptr_seg);
86
87 if (error != MPI_SUCCESS) {
88 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
89 }
90 if (i == 0) {
91 m_sizeof_segments_span = Span<Int64>{ ptr_seg, m_comm_machine_size };
92 }
93
94 if (m_sizeof_segments_span.data() + i != ptr_seg) {
95 ARCCORE_FATAL("Pb d'adresse de segment");
96 }
97 if (m_sizeof_segments_span[i] != *ptr_seg) {
98 ARCCORE_FATAL("Pb taille de segment");
99 }
100 }
101 {
102 MPI_Aint size_seg;
103 int size_type;
104 Int64* ptr_seg = nullptr;
105 int error = MPI_Win_shared_query(m_win_sum_sizeof_segments, i, &size_seg, &size_type, &ptr_seg);
106
107 if (error != MPI_SUCCESS) {
108 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
109 }
110 if (i == 0) {
111 m_sum_sizeof_segments_span = Span<Int64>{ ptr_seg, m_comm_machine_size };
112 }
113
114 if (m_sum_sizeof_segments_span.data() + i != ptr_seg) {
115 ARCCORE_FATAL("Pb d'adresse de segment");
116 }
117 }
118 }
119#else
120 {
121 MPI_Aint size_seg;
122 int size_type;
123 Int64* ptr_seg = nullptr;
124 int error = MPI_Win_shared_query(m_win_sizeof_segments, 0, &size_seg, &size_type, &ptr_seg);
125 if (error != MPI_SUCCESS) {
126 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
127 }
128
129 m_sizeof_segments_span = Span<Int64>{ ptr_seg, m_comm_machine_size };
130 }
131 {
132 MPI_Aint size_seg;
133 int size_type;
134 Int64* ptr_seg = nullptr;
135 int error = MPI_Win_shared_query(m_win_sum_sizeof_segments, 0, &size_seg, &size_type, &ptr_seg);
136
137 if (error != MPI_SUCCESS) {
138 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
139 }
140
141 m_sum_sizeof_segments_span = Span<Int64>{ ptr_seg, m_comm_machine_size };
142 }
143#endif
144
145 //--------------------------
146
147 if (m_comm_machine_rank == 0) {
148 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
149 m_sum_sizeof_segments_span[i] = m_max_sizeof_win;
150 m_max_sizeof_win += m_sizeof_segments_span[i];
151 }
152 }
153 else {
154 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
155 m_max_sizeof_win += m_sizeof_segments_span[i];
156 }
157 }
158
159 MPI_Barrier(m_comm_machine);
160
161 m_actual_sizeof_win = m_max_sizeof_win;
162
163 //--------------------------
164
165 std::byte* ptr_win = nullptr;
166
167#ifdef ARCCORE_DEBUG
168 Int64 sum = 0;
169
170 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
171 MPI_Aint size_seg;
172 int size_type;
173 std::byte* ptr_seg = nullptr;
174 int error = MPI_Win_shared_query(m_win, i, &size_seg, &size_type, &ptr_seg);
175
176 if (error != MPI_SUCCESS) {
177 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
178 }
179 if (i == 0) {
180 ptr_win = ptr_seg;
181 }
182
183 if (ptr_seg != (ptr_win + sum)) {
184 ARCCORE_FATAL("Pb d'adresse de segment");
185 }
186 if (size_seg != m_sizeof_segments_span[i]) {
187 ARCCORE_FATAL("Pb taille de segment");
188 }
189 sum += size_seg;
190 }
191 if (sum != m_max_sizeof_win) {
192 ARCCORE_FATAL("Pb taille de window -- Expected : {0} -- Found : {1}", m_max_sizeof_win, sum);
193 }
194#else
195 {
196 MPI_Aint size_seg;
197 int size_type;
198 std::byte* ptr_seg = nullptr;
199 int error = MPI_Win_shared_query(m_win, 0, &size_seg, &size_type, &ptr_seg);
200
201 if (error != MPI_SUCCESS) {
202 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
203 }
204
205 ptr_win = ptr_seg;
206 }
207#endif
208
209 m_window_span = Span<std::byte>{ ptr_win, m_max_sizeof_win };
210}
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214
215MpiMachineMemoryWindowBaseInternal::
216~MpiMachineMemoryWindowBaseInternal()
217{
218 MPI_Win_free(&m_win);
219 MPI_Win_free(&m_win_sizeof_segments);
220 MPI_Win_free(&m_win_sum_sizeof_segments);
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
226Int32 MpiMachineMemoryWindowBaseInternal::
227sizeofOneElem() const
228{
229 return m_sizeof_type;
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235Span<std::byte> MpiMachineMemoryWindowBaseInternal::
236segment() const
237{
238 const Int64 begin_segment = m_sum_sizeof_segments_span[m_comm_machine_rank];
239 const Int64 size_segment = m_sizeof_segments_span[m_comm_machine_rank];
240
241 return m_window_span.subSpan(begin_segment, size_segment);
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
247Span<std::byte> MpiMachineMemoryWindowBaseInternal::
248segment(Int32 rank) const
249{
250 Int32 pos = -1;
251 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
252 if (m_machine_ranks[i] == rank) {
253 pos = i;
254 break;
255 }
256 }
257 if (pos == -1) {
258 ARCCORE_FATAL("Rank is not in machine");
259 }
260
261 const Int64 begin_segment = m_sum_sizeof_segments_span[pos];
262 const Int64 size_segment = m_sizeof_segments_span[pos];
263
264 return m_window_span.subSpan(begin_segment, size_segment);
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270Span<std::byte> MpiMachineMemoryWindowBaseInternal::
271window() const
272{
273 return m_window_span;
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
279void MpiMachineMemoryWindowBaseInternal::
280resizeSegment(Int64 new_sizeof_segment)
281{
282 m_sizeof_segments_span[m_comm_machine_rank] = new_sizeof_segment;
283
284 MPI_Barrier(m_comm_machine);
285
286 if (m_comm_machine_rank == 0) {
287 Int64 sum = 0;
288 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
289 m_sum_sizeof_segments_span[i] = sum;
290 sum += m_sizeof_segments_span[i];
291 }
292 if (sum > m_max_sizeof_win) {
293 ARCCORE_FATAL("New size of window (sum of size of all segments) is superior than the old size");
294 }
295 m_actual_sizeof_win = sum;
296 }
297 else {
298 Int64 sum = 0;
299 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
300 sum += m_sizeof_segments_span[i];
301 }
302 if (sum > m_max_sizeof_win) {
303 ARCCORE_FATAL("New size of window (sum of size of all segments) is superior than the old size");
304 }
305 m_actual_sizeof_win = sum;
306 }
307
308 m_window_span = Span<std::byte>{ m_window_span.data(), m_actual_sizeof_win };
309
310 MPI_Barrier(m_comm_machine);
311}
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316ConstArrayView<Int32> MpiMachineMemoryWindowBaseInternal::
317machineRanks() const
318{
319 return m_machine_ranks;
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
325void MpiMachineMemoryWindowBaseInternal::
326barrier() const
327{
328 MPI_Barrier(m_comm_machine);
329}
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333
334} // namespace Arcane::MessagePassing::Mpi
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
std::int64_t Int64
Type entier signé sur 64 bits.
std::int32_t Int32
Type entier signé sur 32 bits.