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 (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}