cartesian/
cartesian.rs

1#![deny(warnings)]
2#![allow(clippy::cognitive_complexity)]
3extern crate mpi_fork_fnsp as mpi;
4
5use mpi::traits::*;
6
7fn main() {
8    let universe = mpi::initialize().unwrap();
9
10    let comm = universe.world();
11
12    if comm.size() < 4 {
13        return;
14    }
15
16    let cart_comm = {
17        let dims = [2, 2];
18        let periodic = [false, true];
19        let reorder = true;
20        if let Some(cart_comm) = comm.create_cartesian_communicator(&dims, &periodic, reorder) {
21            cart_comm
22        } else {
23            assert!(comm.rank() >= 4);
24            return;
25        }
26    };
27
28    assert_eq!(2, cart_comm.num_dimensions());
29
30    let mpi::topology::CartesianLayout {
31        dims,
32        periods,
33        coords,
34    } = cart_comm.get_layout();
35
36    assert_eq!([2 as mpi::Count, 2], &dims[..]);
37    assert_eq!([false, true], &periods[..]);
38
39    let xrank = coords[0];
40    let yrank = coords[1];
41
42    assert!(0 <= xrank && xrank < 2);
43    assert!(0 <= yrank && yrank < 2);
44
45    let xcomm = cart_comm.subgroup(&[true, false]);
46    let ycomm = cart_comm.subgroup(&[false, true]);
47
48    assert_eq!(2, xcomm.size());
49    assert_eq!(xrank, xcomm.rank());
50
51    assert_eq!(2, ycomm.size());
52    assert_eq!(yrank, ycomm.rank());
53
54    // the first dimension is non-periodic
55    let (x_src, x_dest) = cart_comm.shift(0, 1);
56    if xrank == 0 {
57        assert!(x_src.is_none());
58        assert!(x_dest.is_some());
59
60        let coords = cart_comm.rank_to_coordinates(x_dest.unwrap());
61        assert_eq!(1, coords[0]);
62    } else {
63        assert_eq!(1, xrank);
64
65        assert!(x_src.is_some());
66        assert!(x_dest.is_none());
67
68        let coords = cart_comm.rank_to_coordinates(x_src.unwrap());
69        assert_eq!(0, coords[0]);
70    }
71
72    // the second dimension is periodic
73    {
74        let (y_src, y_dest) = cart_comm.shift(1, 1);
75        assert!(y_src.is_some());
76        assert!(y_dest.is_some());
77
78        let y_src_coords = cart_comm.rank_to_coordinates(y_src.unwrap());
79        assert_eq!((yrank - 1) & 0b1, y_src_coords[1]);
80
81        let y_dest_coords = cart_comm.rank_to_coordinates(y_dest.unwrap());
82        assert_eq!((yrank + 1) & 0b1, y_dest_coords[1]);
83    }
84
85    // second dimension shift by 2 should be identity
86    {
87        let (y_src, y_dest) = cart_comm.shift(1, 2);
88        assert_eq!(comm.rank(), y_src.unwrap());
89        assert_eq!(comm.rank(), y_dest.unwrap());
90    }
91}