Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MpiContigMachineShMemWinBaseInternal.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/* MpiContigMachineShMemWinBaseInternal.cc (C) 2000-2026 */
9/* */
10/* Class allowing the creation of a memory window for a calculation node */
11/* with MPI. This window will be contiguous for all processes on the same */
12/* node. */
13/*---------------------------------------------------------------------------*/
14/*---------------------------------------------------------------------------*/
15
16#include "arccore/message_passing_mpi/internal/MpiContigMachineShMemWinBaseInternal.h"
17
18#include "arccore/base/FatalErrorException.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane::MessagePassing::Mpi
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29MpiContigMachineShMemWinBaseInternal::
30MpiContigMachineShMemWinBaseInternal(Int64 sizeof_segment, Int32 sizeof_type, const MPI_Comm& comm_machine, Int32 comm_machine_rank, Int32 comm_machine_size, ConstArrayView<Int32> machine_ranks)
31: m_win()
32, m_win_sizeof_segments()
33, m_win_sum_sizeof_segments()
34, m_comm_machine(comm_machine)
35, m_comm_machine_size(comm_machine_size)
36, m_comm_machine_rank(comm_machine_rank)
37, m_sizeof_type(sizeof_type)
38, m_machine_ranks(machine_ranks)
39, m_actual_sizeof_win(-1)
40{
41 // All windows of this class must be contiguous.
42 MPI_Info win_info;
43 MPI_Info_create(&win_info);
44 MPI_Info_set(win_info, "alloc_shared_noncontig", "false");
45
46 // Allocate the main window (which will contain the user data.
47 // We do not retrieve the segment pointer.
48 {
49 void* ptr_seg = nullptr;
50 int error = MPI_Win_allocate_shared(sizeof_segment, m_sizeof_type, win_info, m_comm_machine, &ptr_seg, &m_win);
51
52 if (error != MPI_SUCCESS) {
53 ARCCORE_FATAL("Error with MPI_Win_allocate_shared() call");
54 }
55 }
56
57 //--------------------------
58
59 // Allocate the window that will contain the size of each segment of the
60 // main window.
61 {
62 Int64* ptr_seg = nullptr;
63 int error = MPI_Win_allocate_shared(sizeof(Int64), sizeof(Int64), win_info, m_comm_machine, &ptr_seg, &m_win_sizeof_segments);
64
65 if (error != MPI_SUCCESS) {
66 ARCCORE_FATAL("Error with MPI_Win_allocate_shared() call");
67 }
68 // We use the pointer to our segment to set the size of
69 // our segment in the main window.
70 *ptr_seg = sizeof_segment;
71 }
72
73 // Allocate the window that will contain the position of each segment of the
74 // main window.
75 {
76 Int64* ptr_seg = nullptr;
77 int error = MPI_Win_allocate_shared(sizeof(Int64), sizeof(Int64), win_info, m_comm_machine, &ptr_seg, &m_win_sum_sizeof_segments);
78
79 if (error != MPI_SUCCESS) {
80 ARCCORE_FATAL("Error with MPI_Win_allocate_shared() call");
81 }
82 }
83
84 MPI_Info_free(&win_info);
85
86 MPI_Barrier(m_comm_machine);
87
88 //--------------------------
89
90#ifdef ARCCORE_DEBUG
91
92 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
93 // Create a view on the entire window containing the sizes.
94 // (The loop is only here in debug mode to verify that we have
95 // contiguous windows).
96 {
97 MPI_Aint size_seg;
98 int size_type;
99 Int64* ptr_seg = nullptr;
100 int error = MPI_Win_shared_query(m_win_sizeof_segments, i, &size_seg, &size_type, &ptr_seg);
101
102 if (error != MPI_SUCCESS) {
103 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
104 }
105 if (i == 0) {
106 m_sizeof_segments_span = SmallSpan<Int64>{ ptr_seg, m_comm_machine_size };
107 }
108
109 if (m_sizeof_segments_span.data() + i != ptr_seg) {
110 ARCCORE_FATAL("Segment address error");
111 }
112 if (m_sizeof_segments_span[i] != *ptr_seg) {
113 ARCCORE_FATAL("Segment size error");
114 }
115 }
116
117 // Create a view on the entire window containing the segment positions.
118 {
119 MPI_Aint size_seg;
120 int size_type;
121 Int64* ptr_seg = nullptr;
122 int error = MPI_Win_shared_query(m_win_sum_sizeof_segments, i, &size_seg, &size_type, &ptr_seg);
123
124 if (error != MPI_SUCCESS) {
125 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
126 }
127 if (i == 0) {
128 m_sum_sizeof_segments_span = SmallSpan<Int64>{ ptr_seg, m_comm_machine_size };
129 }
130
131 if (m_sum_sizeof_segments_span.data() + i != ptr_seg) {
132 ARCCORE_FATAL("Segment address error");
133 }
134 }
135 }
136#else
137 // Create a view on the entire window containing the sizes.
138 {
139 MPI_Aint size_seg;
140 int size_type;
141 Int64* ptr_seg = nullptr;
142 int error = MPI_Win_shared_query(m_win_sizeof_segments, 0, &size_seg, &size_type, &ptr_seg);
143 if (error != MPI_SUCCESS) {
144 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
145 }
146
147 m_sizeof_segments_span = SmallSpan<Int64>{ ptr_seg, m_comm_machine_size };
148 }
149
150 // Create a view on the entire window containing the segment positions.
151 {
152 MPI_Aint size_seg;
153 int size_type;
154 Int64* ptr_seg = nullptr;
155 int error = MPI_Win_shared_query(m_win_sum_sizeof_segments, 0, &size_seg, &size_type, &ptr_seg);
156
157 if (error != MPI_SUCCESS) {
158 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
159 }
160
161 m_sum_sizeof_segments_span = SmallSpan<Int64>{ ptr_seg, m_comm_machine_size };
162 }
163#endif
164
165 //--------------------------
166
167 // Only process 0 must fill the positions.
168 // Everyone calculates the size of the main window.
169 if (m_comm_machine_rank == 0) {
170 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
171 m_sum_sizeof_segments_span[i] = m_max_sizeof_win;
172 m_max_sizeof_win += m_sizeof_segments_span[i];
173 }
174 }
175 else {
176 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
177 m_max_sizeof_win += m_sizeof_segments_span[i];
178 }
179 }
180
181 MPI_Barrier(m_comm_machine);
182
183 // The current size of the window is its max size.
184 // Useful in case of resize.
185 m_actual_sizeof_win = m_max_sizeof_win;
186
187 //--------------------------
188
189#ifdef ARCCORE_DEBUG
190 Int64 sum = 0;
191
192 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
193 // Create the view to the main window.
194 // (The loop is only here in debug mode to verify that we have
195 // a contiguous window).
196 MPI_Aint size_seg;
197 int size_type;
198 std::byte* ptr_seg = nullptr;
199 int error = MPI_Win_shared_query(m_win, i, &size_seg, &size_type, &ptr_seg);
200
201 if (error != MPI_SUCCESS) {
202 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
203 }
204 if (i == 0) {
205 m_window_span = Span<std::byte>{ ptr_seg, m_max_sizeof_win };
206 }
207
208 if (ptr_seg != (m_window_span.data() + sum)) {
209 ARCCORE_FATAL("Segment address error");
210 }
211 if (size_seg != m_sizeof_segments_span[i]) {
212 ARCCORE_FATAL("Segment size error");
213 }
214 sum += size_seg;
215 }
216 if (sum != m_max_sizeof_win) {
217 ARCCORE_FATAL("Window size error -- Expected : {0} -- Found : {1}", m_max_sizeof_win, sum);
218 }
219#else
220 // Create the view to the main window.
221 {
222 MPI_Aint size_seg;
223 int size_type;
224 std::byte* ptr_seg = nullptr;
225 int error = MPI_Win_shared_query(m_win, 0, &size_seg, &size_type, &ptr_seg);
226
227 if (error != MPI_SUCCESS) {
228 ARCCORE_FATAL("Error with MPI_Win_shared_query() call");
229 }
230
231 m_window_span = Span<std::byte>{ ptr_seg, m_max_sizeof_win };
232 }
233#endif
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239MpiContigMachineShMemWinBaseInternal::
240~MpiContigMachineShMemWinBaseInternal()
241{
242 MPI_Win_free(&m_win);
243 MPI_Win_free(&m_win_sizeof_segments);
244 MPI_Win_free(&m_win_sum_sizeof_segments);
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250Int32 MpiContigMachineShMemWinBaseInternal::
251sizeofOneElem() const
252{
253 return m_sizeof_type;
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
259Span<std::byte> MpiContigMachineShMemWinBaseInternal::
260segmentView()
261{
262 const Int64 begin_segment = m_sum_sizeof_segments_span[m_comm_machine_rank];
263 const Int64 size_segment = m_sizeof_segments_span[m_comm_machine_rank];
264
265 return m_window_span.subSpan(begin_segment, size_segment);
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
271Span<std::byte> MpiContigMachineShMemWinBaseInternal::
272segmentView(Int32 rank)
273{
274 Int32 pos = -1;
275 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
276 if (m_machine_ranks[i] == rank) {
277 pos = i;
278 break;
279 }
280 }
281 if (pos == -1) {
282 ARCCORE_FATAL("Rank is not in machine");
283 }
284
285 const Int64 begin_segment = m_sum_sizeof_segments_span[pos];
286 const Int64 size_segment = m_sizeof_segments_span[pos];
287
288 return m_window_span.subSpan(begin_segment, size_segment);
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294Span<std::byte> MpiContigMachineShMemWinBaseInternal::
295windowView()
296{
297 return m_window_span;
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
303Span<const std::byte> MpiContigMachineShMemWinBaseInternal::
304segmentConstView() const
305{
306 const Int64 begin_segment = m_sum_sizeof_segments_span[m_comm_machine_rank];
307 const Int64 size_segment = m_sizeof_segments_span[m_comm_machine_rank];
308
309 return m_window_span.subSpan(begin_segment, size_segment);
310}
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
314
315Span<const std::byte> MpiContigMachineShMemWinBaseInternal::
316segmentConstView(Int32 rank) const
317{
318 Int32 pos = -1;
319 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
320 if (m_machine_ranks[i] == rank) {
321 pos = i;
322 break;
323 }
324 }
325 if (pos == -1) {
326 ARCCORE_FATAL("Rank is not in machine");
327 }
328
329 const Int64 begin_segment = m_sum_sizeof_segments_span[pos];
330 const Int64 size_segment = m_sizeof_segments_span[pos];
331
332 return m_window_span.subSpan(begin_segment, size_segment);
333}
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
338Span<const std::byte> MpiContigMachineShMemWinBaseInternal::
339windowConstView() const
340{
341 return m_window_span;
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347void MpiContigMachineShMemWinBaseInternal::
348resizeSegment(Int64 new_sizeof_segment)
349{
350 m_sizeof_segments_span[m_comm_machine_rank] = new_sizeof_segment;
351
352 MPI_Barrier(m_comm_machine);
353
354 if (m_comm_machine_rank == 0) {
355 Int64 sum = 0;
356 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
357 m_sum_sizeof_segments_span[i] = sum;
358 sum += m_sizeof_segments_span[i];
359 }
360 if (sum > m_max_sizeof_win) {
361 ARCCORE_FATAL("New size of window (sum of size of all segments) is superior than the old size");
362 }
363 m_actual_sizeof_win = sum;
364 }
365 else {
366 Int64 sum = 0;
367 for (Int32 i = 0; i < m_comm_machine_size; ++i) {
368 sum += m_sizeof_segments_span[i];
369 }
370 if (sum > m_max_sizeof_win) {
371 ARCCORE_FATAL("New size of window (sum of size of all segments) is superior than the old size");
372 }
373 m_actual_sizeof_win = sum;
374 }
375
376 m_window_span = Span<std::byte>{ m_window_span.data(), m_actual_sizeof_win };
377
378 MPI_Barrier(m_comm_machine);
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384ConstArrayView<Int32> MpiContigMachineShMemWinBaseInternal::
385machineRanks() const
386{
387 return m_machine_ranks;
388}
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
393void MpiContigMachineShMemWinBaseInternal::
394barrier() const
395{
396 MPI_Barrier(m_comm_machine);
397}
398
399/*---------------------------------------------------------------------------*/
400/*---------------------------------------------------------------------------*/
401
402} // namespace Arcane::MessagePassing::Mpi
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
std::int64_t Int64
Signed integer type of 64 bits.
std::int32_t Int32
Signed integer type of 32 bits.