Skip to main content

test_window/
test_window.rs

1// Window API test. Run under mpirun:
2//   mpirun -n 2 test_window
3
4use mpi::Threading;
5use mpi::collective::CommunicatorCollectives;
6use mpi::topology::Communicator;
7
8use mpi_rma::Error;
9use mpi_rma::traits::*;
10
11fn main() {
12    let (universe, provided) =
13        mpi::initialize_with_threading(Threading::Multiple).expect("MPI must initialize once");
14    assert_eq!(provided, Threading::Multiple);
15    let world = universe.world();
16    let rank = world.rank();
17    let size = world.size();
18    assert_eq!(size, 2);
19    let next = (rank + 1) % size;
20    let prev = (rank + size - 1) % size;
21
22    // Element type must agree across ranks.
23    if rank == 0 {
24        assert!(matches!(
25            world.allocate_window::<u8>(1),
26            Err(Error::Window("element type differs between ranks"))
27        ));
28    } else {
29        assert!(matches!(
30            world.allocate_window::<u64>(2),
31            Err(Error::Window("element type differs between ranks"))
32        ));
33    }
34
35    // Self put/get, bounds, fetch_add; relies on Drop for shutdown.
36    {
37        let win = world.allocate_window::<u64>(8).unwrap();
38        win.put(rank, 0, &[rank as u64 + 10, rank as u64 + 20])
39            .unwrap();
40        let mut got = [0; 8];
41        win.get(rank, 0, &mut got).unwrap();
42        assert_eq!(got[0], rank as u64 + 10);
43        assert_eq!(got[1], rank as u64 + 20);
44
45        assert!(matches!(
46            win.put(rank, win.len(), &[1]),
47            Err(Error::Range { .. })
48        ));
49        assert!(matches!(win.put(-1, 0, &[1]), Err(Error::Rank(-1))));
50        assert!(matches!(win.put(size, 0, &[1]), Err(Error::Rank(_))));
51        assert!(matches!(
52            win.get(rank, win.len(), &mut [0]),
53            Err(Error::Range { .. })
54        ));
55
56        assert_eq!(win.fetch_add(rank, 7, rank as u64 + 1).unwrap(), 0);
57        assert_eq!(win.fetch_add(rank, 7, 0).unwrap(), rank as u64 + 1);
58        world.barrier();
59    }
60
61    // Cross-rank exchange.
62    {
63        let win = world.allocate_window::<u64>(8).unwrap();
64        win.put(next, 0, &[rank as u64 + 100]).unwrap();
65        world.barrier();
66        let mut got = [0u64; 1];
67        win.get(rank, 0, &mut got).unwrap();
68        assert_eq!(got[0], prev as u64 + 100);
69        world.barrier();
70        win.close().unwrap();
71    }
72
73    if rank == 0 {
74        println!("test_window: ok");
75    }
76}