structured/
structured.rs

1#![deny(warnings)]
2
3use mpi::{datatype::UserDatatype, topology::Process, traits::*};
4use std::mem::size_of;
5
6struct MyInts([i32; 3]);
7
8unsafe impl Equivalence for MyInts {
9    type Out = UserDatatype;
10    fn equivalent_datatype() -> Self::Out {
11        UserDatatype::structured(
12            &[1, 1, 1],
13            &[
14                // Order the logical fields in reverse of their storage order
15                (size_of::<i32>() * 2) as mpi::Address,
16                size_of::<i32>() as mpi::Address,
17                0,
18            ],
19            &[i32::equivalent_datatype(); 3],
20        )
21    }
22}
23
24fn prepare_on_root(process: Process, ints: &mut [i32]) {
25    for i in ints.iter_mut() {
26        *i = if process.is_self() { *i + 10 } else { -1 };
27    }
28}
29
30fn main() {
31    let universe = mpi::initialize().unwrap();
32    let world = universe.world();
33
34    let root_process = world.process_at_rank(0);
35    let second_root = world.process_at_rank(1 % world.size());
36
37    if root_process.is_self() {
38        let mut ints = MyInts([3, 2, 1]);
39        root_process.broadcast_into(&mut ints);
40        assert_eq!([3, 2, 1], ints.0);
41        prepare_on_root(second_root, &mut ints.0);
42        second_root.broadcast_into(&mut ints);
43        assert_eq!([13, 12, 11], ints.0);
44    } else {
45        let mut ints: [i32; 3] = [0, 0, 0];
46        root_process.broadcast_into(&mut ints[..]);
47        assert_eq!([1, 2, 3], ints);
48        prepare_on_root(second_root, &mut ints);
49        second_root.broadcast_into(&mut ints);
50        assert_eq!([11, 12, 13], ints);
51    }
52}