Skip to main content

rma/
rma.rs

1//! One-sided (RMA) self test: `put`, `get`, and `accumulate` over [`Window`]s.
2//! Exits non-zero on any mismatch.
3
4use mpi::collective::SystemOperation;
5use mpi::traits::*;
6use mpi::window::Window;
7
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}