pub struct Window<T: Equivalence + Send + Sync> { /* private fields */ }Expand description
A window of memory exposed for one-sided access (MPI_Win).
Implementations§
Source§impl<T: Equivalence + Send + Sync> Window<T>
impl<T: Equivalence + Send + Sync> Window<T>
Sourcepub fn allocate<C: Communicator>(count: usize, comm: &C) -> Window<T>
pub fn allocate<C: Communicator>(count: usize, comm: &C) -> Window<T>
Collectively create a window of count elements (zero-initialized) on
every rank of comm (MPI_Win_allocate).
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}Sourcepub fn from_vec<C: Communicator>(data: Vec<T>, comm: &C) -> Window<T>
pub fn from_vec<C: Communicator>(data: Vec<T>, comm: &C) -> Window<T>
Collectively expose an existing buffer as a window (MPI_Win_create).
Sourcepub fn with_local<R>(&self, f: impl FnOnce(&[T]) -> R) -> R
pub fn with_local<R>(&self, f: impl FnOnce(&[T]) -> R) -> R
Inspect the local window memory.
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}Sourcepub fn with_local_mut<R>(&self, f: impl FnOnce(&mut [T]) -> R) -> R
pub fn with_local_mut<R>(&self, f: impl FnOnce(&mut [T]) -> R) -> R
Mutate the local window memory.
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}Sourcepub fn put(&self, target: Rank, target_disp: usize, data: &[T])
pub fn put(&self, target: Rank, target_disp: usize, data: &[T])
Write data into rank target’s window at element offset
target_disp (MPI_Put). Completes when the target acknowledges.
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}Sourcepub fn get(&self, target: Rank, target_disp: usize, buf: &mut [T])
pub fn get(&self, target: Rank, target_disp: usize, buf: &mut [T])
Read buf.len() elements from rank target’s window at element offset
target_disp into buf (MPI_Get).
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}Sourcepub fn accumulate(
&self,
target: Rank,
target_disp: usize,
data: &[T],
op: SystemOperation,
)
pub fn accumulate( &self, target: Rank, target_disp: usize, data: &[T], op: SystemOperation, )
Combine data into rank target’s window at element offset
target_disp using op (MPI_Accumulate).
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}Sourcepub fn fence(&self)
pub fn fence(&self)
Collective synchronization delimiting an access epoch (MPI_Win_fence).
Because operations are synchronous, this is a barrier over the window’s
communicator.
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 // ---- put: rank 0 writes distinct data into every other rank's window ----
15 let win = Window::<i32>::allocate(4, &world);
16 win.fence();
17 if rank == 0 {
18 for r in 1..size {
19 win.put(r, 0, &[r * 10, r * 10 + 1, r * 10 + 2, r * 10 + 3]);
20 }
21 win.with_local_mut(|m| {
22 for (i, v) in m.iter_mut().enumerate() {
23 *v = i as i32;
24 }
25 });
26 }
27 win.fence();
28 if rank != 0 {
29 win.with_local(|m| {
30 assert_eq!(
31 m,
32 [rank * 10, rank * 10 + 1, rank * 10 + 2, rank * 10 + 3],
33 "put mismatch"
34 );
35 });
36 }
37 win.fence();
38
39 // ---- get: every rank reads rank 0's window (0,1,2,3) ----
40 if rank != 0 {
41 let mut buf = [0i32; 4];
42 win.get(0, 0, &mut buf);
43 assert_eq!(buf, [0, 1, 2, 3], "get mismatch");
44 }
45 win.fence();
46
47 // ---- accumulate: every rank sums [1;4] into rank 0's window ----
48 let win2 = Window::<i32>::allocate(4, &world);
49 win2.fence();
50 win2.accumulate(0, 0, &[1, 1, 1, 1], SystemOperation::sum());
51 win2.fence();
52 if rank == 0 {
53 win2.with_local(|m| assert_eq!(m, [size, size, size, size], "accumulate mismatch"));
54 }
55 win2.fence();
56
57 if rank == 0 {
58 println!("RMA PASS: put/get/accumulate verified on {size} ranks.");
59 }
60}