Trait Communicator

Source
pub trait Communicator: AsRaw<Raw = MPI_Comm> {
Show 23 methods // Provided methods fn size(&self) -> Rank { ... } fn rank(&self) -> Rank { ... } fn process_at_rank(&self, r: Rank) -> Process<'_, Self> where Self: Sized { ... } fn any_process(&self) -> AnyProcess<'_, Self> where Self: Sized { ... } fn this_process(&self) -> Process<'_, Self> where Self: Sized { ... } fn compare<C>(&self, other: &C) -> CommunicatorRelation where C: Communicator + ?Sized { ... } fn duplicate(&self) -> UserCommunicator { ... } fn split_by_color(&self, color: Color) -> Option<UserCommunicator> { ... } fn split_by_color_with_key( &self, color: Color, key: Key, ) -> Option<UserCommunicator> { ... } fn split_shared(&self, key: c_int) -> UserCommunicator { ... } fn split_by_subgroup_collective<G>( &self, group: &G, ) -> Option<UserCommunicator> where G: Group + ?Sized { ... } fn split_by_subgroup<G>(&self, group: &G) -> Option<UserCommunicator> where G: Group + ?Sized { ... } fn split_by_subgroup_with_tag<G>( &self, group: &G, tag: Tag, ) -> Option<UserCommunicator> where G: Group + ?Sized { ... } fn group(&self) -> UserGroup { ... } fn abort(&self, errorcode: c_int) -> ! { ... } fn set_name(&self, name: &str) { ... } fn get_name(&self) -> String { ... } fn create_cartesian_communicator( &self, dims: &[Count], periods: &[bool], reorder: bool, ) -> Option<CartesianCommunicator> { ... } fn cartesian_map(&self, dims: &[Count], periods: &[bool]) -> Option<Rank> { ... } fn pack_size<Dt>(&self, incount: Count, datatype: &Dt) -> Count where Dt: Datatype { ... } fn pack<Buf>(&self, inbuf: &Buf) -> Vec<u8> where Buf: ?Sized + Buffer { ... } fn pack_into<Buf>( &self, inbuf: &Buf, outbuf: &mut [u8], position: Count, ) -> Count where Buf: ?Sized + Buffer { ... } unsafe fn unpack_into<Buf>( &self, inbuf: &[u8], outbuf: &mut Buf, position: Count, ) -> Count where Buf: ?Sized + BufferMut { ... }
}
Expand description

Communicators are contexts for communication

Provided Methods§

Source

fn size(&self) -> Rank

Number of processes in this communicator

§Examples

See examples/simple.rs

§Standard section(s)

6.4.1

Examples found in repository?
examples/simple.rs (line 12)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    println!(
10        "Hello parallel world from process {} of {}!",
11        world.rank(),
12        world.size()
13    );
14}
More examples
Hide additional examples
examples/cartesian_map.rs (line 11)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8
9    let comm = universe.world();
10
11    let new_rank = comm.cartesian_map(&[2, comm.size() / 4], &[false, false]);
12
13    println!("{} -> {:?}", comm.rank(), new_rank);
14}
examples/all_gather_bool.rs (line 11)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9
10    let rank = world.rank();
11    let count = world.size() as usize;
12
13    let mut a = vec![false; count];
14    world.all_gather_into(&(rank % 2 == 0), &mut a[..]);
15
16    let answer: Vec<_> = (0..count).map(|i| i % 2 == 0).collect();
17
18    assert_eq!(answer, a);
19}
examples/all_to_all.rs (line 10)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let rank = world.rank();
10    let size = world.size();
11
12    let u = vec![rank; size as usize];
13    let mut v = vec![0; size as usize];
14
15    world.all_to_all_into(&u[..], &mut v[..]);
16
17    println!("u: {:?}", u);
18    println!("v: {:?}", v);
19
20    assert!(v.into_iter().zip(0..size).all(|(i, j)| i == j));
21}
examples/scatter.rs (line 11)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10    let rank = world.rank();
11    let size = world.size();
12    let root_rank = 0;
13    let root_process = world.process_at_rank(root_rank);
14
15    let mut x = 0 as Rank;
16    if rank == root_rank {
17        let v = (0..size).collect::<Vec<_>>();
18        root_process.scatter_into_root(&v[..], &mut x);
19    } else {
20        root_process.scatter_into(&mut x);
21    }
22    assert_eq!(x, rank);
23}
examples/immediate_all_to_all.rs (line 10)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let rank = world.rank();
10    let size = world.size();
11
12    let u = vec![rank; size as usize];
13    let mut v = vec![0; size as usize];
14
15    mpi::request::scope(|scope| {
16        world
17            .immediate_all_to_all_into(scope, &u[..], &mut v[..])
18            .wait();
19    });
20
21    println!("u: {:?}", u);
22    println!("v: {:?}", v);
23
24    assert!(v.into_iter().zip(0..size).all(|(i, j)| i == j));
25}
Source

fn rank(&self) -> Rank

The Rank that identifies the calling process within this communicator

§Examples

See examples/simple.rs

§Standard section(s)

6.4.1

Examples found in repository?
examples/simple.rs (line 11)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    println!(
10        "Hello parallel world from process {} of {}!",
11        world.rank(),
12        world.size()
13    );
14}
More examples
Hide additional examples
examples/cartesian_map.rs (line 13)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8
9    let comm = universe.world();
10
11    let new_rank = comm.cartesian_map(&[2, comm.size() / 4], &[false, false]);
12
13    println!("{} -> {:?}", comm.rank(), new_rank);
14}
examples/all_gather_bool.rs (line 10)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9
10    let rank = world.rank();
11    let count = world.size() as usize;
12
13    let mut a = vec![false; count];
14    world.all_gather_into(&(rank % 2 == 0), &mut a[..]);
15
16    let answer: Vec<_> = (0..count).map(|i| i % 2 == 0).collect();
17
18    assert_eq!(answer, a);
19}
examples/structured.rs (line 30)
24fn main() {
25    let universe = mpi::initialize().unwrap();
26    let world = universe.world();
27
28    let root_process = world.process_at_rank(0);
29
30    if world.rank() == 0 {
31        root_process.broadcast_into(&mut MyInts([3, 2, 1]));
32    } else {
33        let mut ints: [i32; 3] = [0, 0, 0];
34        root_process.broadcast_into(&mut ints[..]);
35
36        assert_eq!([1, 2, 3], ints);
37    }
38}
examples/all_to_all.rs (line 9)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let rank = world.rank();
10    let size = world.size();
11
12    let u = vec![rank; size as usize];
13    let mut v = vec![0; size as usize];
14
15    world.all_to_all_into(&u[..], &mut v[..]);
16
17    println!("u: {:?}", u);
18    println!("v: {:?}", v);
19
20    assert!(v.into_iter().zip(0..size).all(|(i, j)| i == j));
21}
examples/scan.rs (line 15)
12fn main() {
13    let universe = mpi::initialize().unwrap();
14    let world = universe.world();
15    let rank = world.rank();
16
17    let mut x = 0;
18    world.scan_into(&rank, &mut x, &SystemOperation::sum());
19    assert_eq!(x, (rank * (rank + 1)) / 2);
20
21    let y = rank + 1;
22    let mut z = 0;
23    world.exclusive_scan_into(&y, &mut z, &SystemOperation::product());
24    if rank > 0 {
25        assert_eq!(z, fac(y - 1));
26    }
27}
Source

fn process_at_rank(&self, r: Rank) -> Process<'_, Self>
where Self: Sized,

Bundles a reference to this communicator with a specific Rank into a Process.

§Examples

See examples/broadcast.rs examples/gather.rs examples/send_receive.rs

Examples found in repository?
examples/structured.rs (line 28)
24fn main() {
25    let universe = mpi::initialize().unwrap();
26    let world = universe.world();
27
28    let root_process = world.process_at_rank(0);
29
30    if world.rank() == 0 {
31        root_process.broadcast_into(&mut MyInts([3, 2, 1]));
32    } else {
33        let mut ints: [i32; 3] = [0, 0, 0];
34        root_process.broadcast_into(&mut ints[..]);
35
36        assert_eq!([1, 2, 3], ints);
37    }
38}
More examples
Hide additional examples
examples/scatter.rs (line 13)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10    let rank = world.rank();
11    let size = world.size();
12    let root_rank = 0;
13    let root_process = world.process_at_rank(root_rank);
14
15    let mut x = 0 as Rank;
16    if rank == root_rank {
17        let v = (0..size).collect::<Vec<_>>();
18        root_process.scatter_into_root(&v[..], &mut x);
19    } else {
20        root_process.scatter_into(&mut x);
21    }
22    assert_eq!(x, rank);
23}
examples/datatype_dup.rs (line 11)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10
11    let root_process = world.process_at_rank(0);
12
13    let int_type = i32::equivalent_datatype().dup();
14
15    let mut ints = if world.rank() == 0 {
16        [1i32, 2, 3, 4]
17    } else {
18        [0, 0, 0, 0]
19    };
20
21    let mut buffer =
22        unsafe { DynBufferMut::from_raw(ints.as_mut_ptr(), ints.count(), int_type.as_ref()) };
23
24    root_process.broadcast_into(&mut buffer);
25
26    assert_eq!([1, 2, 3, 4], ints);
27}
examples/complex_datatype.rs (line 55)
51fn main() {
52    let universe = mpi::initialize().unwrap();
53    let world = universe.world();
54
55    let root_process = world.process_at_rank(0);
56
57    let mut data = if world.rank() == 0 {
58        ComplexDatatype {
59            b: true,
60            ints: [1, -2, 3, -4],
61            tuple: TupleType([-0.1, 0.1], 7),
62        }
63    } else {
64        ComplexDatatype::default()
65    };
66
67    root_process.broadcast_into(&mut data);
68
69    assert_eq!(true, data.b);
70    assert_eq!([1, -2, 3, -4], data.ints);
71    assert_eq!([-0.1, 0.1], data.tuple.0);
72    assert_eq!(7, data.tuple.1);
73}
examples/immediate_scatter.rs (line 13)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10    let rank = world.rank();
11    let size = world.size();
12    let root_rank = 0;
13    let root_process = world.process_at_rank(root_rank);
14
15    let mut x = 0 as Rank;
16    if rank == root_rank {
17        let v = (0..size).collect::<Vec<_>>();
18        mpi::request::scope(|scope| {
19            let req = root_process.immediate_scatter_into_root(scope, &v[..], &mut x);
20            req.wait();
21        });
22    } else {
23        mpi::request::scope(|scope| {
24            let req = root_process.immediate_scatter_into(scope, &mut x);
25            req.wait();
26        });
27    }
28    assert_eq!(x, rank);
29}
examples/barrier.rs (line 25)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let receiver_rank = 0;
10
11    if world.rank() == receiver_rank {
12        let n = (world.size() - 1) as usize;
13        let mut buf = vec![0u64; 2 * n];
14        for x in buf[0..n].iter_mut() {
15            world.any_process().receive_into(x);
16        }
17        world.barrier();
18        for x in buf[n..2 * n].iter_mut() {
19            world.any_process().receive_into(x);
20        }
21        println!("{:?}", buf);
22        assert!(buf[0..n].iter().all(|&x| x == 1));
23        assert!(buf[n..2 * n].iter().all(|&x| x == 2));
24    } else {
25        world.process_at_rank(0).send(&1u64);
26        world.barrier();
27        world.process_at_rank(0).send(&2u64);
28    }
29}
Source

fn any_process(&self) -> AnyProcess<'_, Self>
where Self: Sized,

Returns an AnyProcess identifier that can be used, e.g. as a Source in point to point communication.

Examples found in repository?
examples/barrier.rs (line 15)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let receiver_rank = 0;
10
11    if world.rank() == receiver_rank {
12        let n = (world.size() - 1) as usize;
13        let mut buf = vec![0u64; 2 * n];
14        for x in buf[0..n].iter_mut() {
15            world.any_process().receive_into(x);
16        }
17        world.barrier();
18        for x in buf[n..2 * n].iter_mut() {
19            world.any_process().receive_into(x);
20        }
21        println!("{:?}", buf);
22        assert!(buf[0..n].iter().all(|&x| x == 1));
23        assert!(buf[n..2 * n].iter().all(|&x| x == 2));
24    } else {
25        world.process_at_rank(0).send(&1u64);
26        world.barrier();
27        world.process_at_rank(0).send(&2u64);
28    }
29}
More examples
Hide additional examples
examples/buffered.rs (line 27)
9fn main() {
10    let mut universe = mpi::initialize().unwrap();
11    // Try to attach a buffer.
12    universe.set_buffer_size(BUFFER_SIZE);
13    // Check buffer size matches.
14    assert_eq!(universe.buffer_size(), BUFFER_SIZE);
15    // Try to detach the buffer.
16    universe.detach_buffer();
17    // Attach another buffer.
18    universe.set_buffer_size(BUFFER_SIZE);
19
20    let world = universe.world();
21
22    let x = vec![std::f32::consts::PI; 1024];
23    let mut y = vec![0.0; 1024];
24    mpi::request::scope(|scope| {
25        let _rreq = WaitGuard::from(
26            world
27                .any_process()
28                .immediate_receive_into(scope, &mut y[..]),
29        );
30        world.this_process().buffered_send(&x[..]);
31    });
32    assert_eq!(x, y);
33}
examples/wait_any.rs (line 36)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let x = std::f32::consts::PI;
13    let mut y: f32 = 0.0;
14
15    mpi::request::scope(|scope| {
16        if world.rank() == 0 {
17            let mut requests = Vec::new();
18            for i in 1..world.size() {
19                requests.push(
20                    world
21                        .process_at_rank(i)
22                        .immediate_synchronous_send(scope, &x),
23                );
24            }
25
26            println!("World size {}", world.size());
27            while let Some((index, _status)) = mpi::request::wait_any(&mut requests) {
28                println!("Request with index {} completed", index);
29            }
30            println!("All requests completed");
31        } else {
32            let secs = time::Duration::from_secs(world.rank() as u64);
33
34            thread::sleep(secs);
35
36            let rreq = world.any_process().immediate_receive_into(scope, &mut y);
37            rreq.wait();
38            println!("Process {} received data", world.rank());
39        }
40    });
41}
examples/readme.rs (line 24)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10    let size = world.size();
11    let rank = world.rank();
12
13    let next_rank = if rank + 1 < size { rank + 1 } else { 0 };
14    let previous_rank = if rank > 0 { rank - 1 } else { size - 1 };
15
16    let msg = vec![rank, 2 * rank, 4 * rank];
17    mpi::request::scope(|scope| {
18        let _sreq = WaitGuard::from(
19            world
20                .process_at_rank(next_rank)
21                .immediate_send(scope, &msg[..]),
22        );
23
24        let (msg, status) = world.any_process().receive_vec();
25
26        println!(
27            "Process {} got message {:?}.\nStatus is: {:?}",
28            rank, msg, status
29        );
30        let x = status.source_rank();
31        assert_eq!(x, previous_rank);
32        assert_eq!(vec![x, 2 * x, 4 * x], msg);
33
34        let root_rank = 0;
35        let root_process = world.process_at_rank(root_rank);
36
37        let mut a;
38        if world.rank() == root_rank {
39            a = vec![2, 4, 8, 16];
40            println!("Root broadcasting value: {:?}.", &a[..]);
41        } else {
42            a = vec![0; 4];
43        }
44        root_process.broadcast_into(&mut a[..]);
45        println!("Rank {} received value: {:?}.", world.rank(), &a[..]);
46        assert_eq!(&a[..], &[2, 4, 8, 16]);
47    });
48}
examples/send_receive.rs (line 32)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    let size = world.size();
12    let rank = world.rank();
13
14    let next_rank = if rank + 1 < size { rank + 1 } else { 0 };
15    let next_process = world.process_at_rank(next_rank);
16    let previous_rank = if rank > 0 { rank - 1 } else { size - 1 };
17    let previous_process = world.process_at_rank(previous_rank);
18
19    let (msg, status): (Rank, _) = p2p::send_receive(&rank, &previous_process, &next_process);
20    println!(
21        "Process {} got message {}.\nStatus is: {:?}",
22        rank, msg, status
23    );
24    world.barrier();
25    assert_eq!(msg, next_rank);
26
27    if rank > 0 {
28        let msg = vec![rank, rank + 1, rank - 1];
29        world.process_at_rank(0).send(&msg[..]);
30    } else {
31        for _ in 1..size {
32            let (msg, status) = world.any_process().receive_vec::<Rank>();
33            println!(
34                "Process {} got long message {:?}.\nStatus is: {:?}",
35                rank, msg, status
36            );
37
38            let x = status.source_rank();
39            let v = vec![x, x + 1, x - 1];
40            assert_eq!(v, msg);
41        }
42    }
43    world.barrier();
44
45    let mut x = rank;
46    p2p::send_receive_replace_into(&mut x, &next_process, &previous_process);
47    assert_eq!(x, previous_rank);
48}
examples/immediate_barrier.rs (line 24)
11fn main() {
12    use mpi::traits::*;
13    let universe = mpi::initialize().unwrap();
14    let world = universe.world();
15    let size = world.size();
16    let receiver_rank = 0;
17
18    if world.rank() == receiver_rank {
19        // receiver process
20        let n = (size - 1) as usize;
21        let mut buf = vec![0u64; 3 * n];
22        // receive first 2 * n messages
23        for x in buf[0..2 * n].iter_mut() {
24            world.any_process().receive_into(x);
25        }
26        // signal the waiting senders that 2 * n messages have been received
27        let breq = world.immediate_barrier();
28        // receive remaining n messages
29        for x in buf[2 * n..3 * n].iter_mut() {
30            world.any_process().receive_into(x);
31        }
32        println!("{:?}", buf);
33        // messages "1" and "2" may be interleaved, but all have to be contained within the first
34        // 2 * n slots of the buffer
35        assert_eq!(buf[0..2 * n].iter().filter(|&&x| x == 1).count(), n);
36        assert_eq!(buf[0..2 * n].iter().filter(|&&x| x == 2).count(), n);
37        // the last n slots in the buffer may only contain message "3"
38        assert!(buf[2 * n..3 * n].iter().all(|&x| x == 3));
39        // clean up the barrier request
40        breq.wait();
41    } else {
42        // sender processes
43        // send message "1"
44        world.process_at_rank(0).send(&1u64);
45        // join barrier, but do not block
46        let breq = world.immediate_barrier();
47        // send message "2"
48        world.process_at_rank(0).send(&2u64);
49        // wait for receiver process to receive the first 2 * n messages
50        breq.wait();
51        // send message "3"
52        world.process_at_rank(0).send(&3u64);
53    }
54}
Source

fn this_process(&self) -> Process<'_, Self>
where Self: Sized,

A Process for the calling process

Examples found in repository?
examples/buffered.rs (line 30)
9fn main() {
10    let mut universe = mpi::initialize().unwrap();
11    // Try to attach a buffer.
12    universe.set_buffer_size(BUFFER_SIZE);
13    // Check buffer size matches.
14    assert_eq!(universe.buffer_size(), BUFFER_SIZE);
15    // Try to detach the buffer.
16    universe.detach_buffer();
17    // Attach another buffer.
18    universe.set_buffer_size(BUFFER_SIZE);
19
20    let world = universe.world();
21
22    let x = vec![std::f32::consts::PI; 1024];
23    let mut y = vec![0.0; 1024];
24    mpi::request::scope(|scope| {
25        let _rreq = WaitGuard::from(
26            world
27                .any_process()
28                .immediate_receive_into(scope, &mut y[..]),
29        );
30        world.this_process().buffered_send(&x[..]);
31    });
32    assert_eq!(x, y);
33}
More examples
Hide additional examples
examples/immediate.rs (line 16)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let x = std::f32::consts::PI;
13    let mut y: f32 = 0.0;
14
15    mpi::request::scope(|scope| {
16        let mut sreq = world.this_process().immediate_send(scope, &x);
17        let rreq = world.any_process().immediate_receive_into(scope, &mut y);
18        rreq.wait();
19        loop {
20            match sreq.test() {
21                Ok(_) => {
22                    break;
23                }
24                Err(req) => {
25                    sreq = req;
26                }
27            }
28        }
29    });
30    assert_eq!(x, y);
31
32    y = 0.0;
33    mpi::request::scope(|scope| {
34        let _rreq = WaitGuard::from(world.any_process().immediate_receive_into(scope, &mut y));
35        let _sreq = WaitGuard::from(world.this_process().immediate_ready_send(scope, &x));
36    });
37    assert_eq!(x, y);
38
39    assert!(world.any_process().immediate_probe().is_none());
40    assert!(world.any_process().immediate_matched_probe().is_none());
41
42    y = 0.0;
43    mpi::request::scope(|scope| {
44        let _sreq: WaitGuard<_> = world
45            .this_process()
46            .immediate_synchronous_send(scope, &x)
47            .into();
48        let preq = world.any_process().immediate_matched_probe();
49        assert!(preq.is_some());
50        let (msg, _) = preq.unwrap();
51        let _rreq: WaitGuard<_> = msg.immediate_matched_receive_into(scope, &mut y).into();
52    });
53    assert_eq!(x, y);
54
55    let future = world.any_process().immediate_receive();
56    world.this_process().send(&x);
57    let (msg, _) = future.get();
58    assert_eq!(x, msg);
59
60    let future = world.any_process().immediate_receive();
61    let res = future.r#try();
62    assert!(res.is_err());
63    let mut future = res.err().unwrap();
64    world.this_process().send(&x);
65    loop {
66        match future.r#try() {
67            Ok((msg, _)) => {
68                assert_eq!(x, msg);
69                break;
70            }
71            Err(f) => {
72                future = f;
73            }
74        }
75    }
76
77    mpi::request::scope(|scope| {
78        let sreq = world.this_process().immediate_send(scope, &x);
79        sreq.cancel();
80        sreq.wait();
81
82        let _sreq = CancelGuard::from(world.this_process().immediate_receive_into(scope, &mut y));
83    });
84}
Source

fn compare<C>(&self, other: &C) -> CommunicatorRelation
where C: Communicator + ?Sized,

Compare two communicators.

See enum CommunicatorRelation.

§Standard section(s)

6.4.1

Examples found in repository?
examples/duplicate.rs (line 15)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10    let moon = world.duplicate();
11
12    world.barrier();
13    moon.barrier();
14
15    assert_eq!(CommunicatorRelation::Congruent, world.compare(&moon));
16}
Source

fn duplicate(&self) -> UserCommunicator

Duplicate a communicator.

§Examples

See examples/duplicate.rs

§Standard section(s)

6.4.2

Examples found in repository?
examples/duplicate.rs (line 10)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10    let moon = world.duplicate();
11
12    world.barrier();
13    moon.barrier();
14
15    assert_eq!(CommunicatorRelation::Congruent, world.compare(&moon));
16}
Source

fn split_by_color(&self, color: Color) -> Option<UserCommunicator>

Split a communicator by color.

Creates as many new communicators as distinct values of color are given. All processes with the same value of color join the same communicator. A process that passes the special undefined color will not join a new communicator and None is returned.

§Examples

See examples/split.rs

§Standard section(s)

6.4.2

Examples found in repository?
examples/split.rs (line 65)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10
11    let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
12    let odd_group = world.group().include(&odd[..]);
13    let even_group = world.group().difference(&odd_group);
14    assert!(
15        (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
16            || (even_group.rank().is_none() && odd_group.rank().is_some())
17    );
18    let my_group = if odd_group.rank().is_some() {
19        &odd_group
20    } else {
21        &even_group
22    };
23    let empty_group = SystemGroup::empty();
24
25    let oddness_comm = world.split_by_subgroup_collective(my_group);
26    assert!(oddness_comm.is_some());
27    let oddness_comm = oddness_comm.unwrap();
28    assert_eq!(
29        GroupRelation::Identical,
30        oddness_comm.group().compare(my_group)
31    );
32
33    let odd_comm = if odd_group.rank().is_some() {
34        world.split_by_subgroup_collective(&odd_group)
35    } else {
36        world.split_by_subgroup_collective(&empty_group)
37    };
38    if odd_group.rank().is_some() {
39        assert!(odd_comm.is_some());
40        let odd_comm = odd_comm.unwrap();
41        assert_eq!(
42            GroupRelation::Identical,
43            odd_comm.group().compare(&odd_group)
44        );
45    } else {
46        assert!(odd_comm.is_none());
47    }
48
49    #[cfg(not(msmpi))]
50    {
51        if even_group.rank().is_some() {
52            let even_comm = world.split_by_subgroup(&even_group);
53            assert!(even_comm.is_some());
54            let even_comm = even_comm.unwrap();
55            assert_eq!(
56                GroupRelation::Identical,
57                even_comm.group().compare(&even_group)
58            );
59
60            let no_comm = world.split_by_subgroup(&odd_group);
61            assert!(no_comm.is_none());
62        }
63    }
64
65    let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
66    assert!(oddness_comm.is_some());
67    let oddness_comm = oddness_comm.unwrap();
68    assert_eq!(
69        GroupRelation::Identical,
70        oddness_comm.group().compare(my_group)
71    );
72
73    let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
74        Color::with_value(0)
75    } else {
76        Color::undefined()
77    });
78    if world.rank() % 2 != 0 {
79        assert!(odd_comm.is_some());
80        let odd_comm = odd_comm.unwrap();
81        assert_eq!(
82            GroupRelation::Identical,
83            odd_comm.group().compare(&odd_group)
84        );
85    } else {
86        assert!(odd_comm.is_none());
87    }
88}
Source

fn split_by_color_with_key( &self, color: Color, key: Key, ) -> Option<UserCommunicator>

Split a communicator by color.

Like split() but orders processes according to the value of key in the new communicators.

§Standard section(s)

6.4.2

Source

fn split_shared(&self, key: c_int) -> UserCommunicator

Split the communicator into subcommunicators, each of which can create a shared memory region.

Within each subgroup, the processes are ranked in the order defined by the value of the argument key, with ties broken according to their rank in the old group.

§Standard section(s)

6.4.2 (See: MPI_Comm_split_type)

Source

fn split_by_subgroup_collective<G>(&self, group: &G) -> Option<UserCommunicator>
where G: Group + ?Sized,

Split a communicator collectively by subgroup.

Proceses pass in a group that is a subgroup of the group associated with the old communicator. Different processes may pass in different groups, but if two groups are different, they have to be disjunct. One new communicator is created for each distinct group. The new communicator is returned if a process is a member of the group he passed in, otherwise None.

This call is a collective operation on the old communicator so all processes have to partake.

§Examples

See examples/split.rs

§Standard section(s)

6.4.2

Examples found in repository?
examples/split.rs (line 25)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10
11    let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
12    let odd_group = world.group().include(&odd[..]);
13    let even_group = world.group().difference(&odd_group);
14    assert!(
15        (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
16            || (even_group.rank().is_none() && odd_group.rank().is_some())
17    );
18    let my_group = if odd_group.rank().is_some() {
19        &odd_group
20    } else {
21        &even_group
22    };
23    let empty_group = SystemGroup::empty();
24
25    let oddness_comm = world.split_by_subgroup_collective(my_group);
26    assert!(oddness_comm.is_some());
27    let oddness_comm = oddness_comm.unwrap();
28    assert_eq!(
29        GroupRelation::Identical,
30        oddness_comm.group().compare(my_group)
31    );
32
33    let odd_comm = if odd_group.rank().is_some() {
34        world.split_by_subgroup_collective(&odd_group)
35    } else {
36        world.split_by_subgroup_collective(&empty_group)
37    };
38    if odd_group.rank().is_some() {
39        assert!(odd_comm.is_some());
40        let odd_comm = odd_comm.unwrap();
41        assert_eq!(
42            GroupRelation::Identical,
43            odd_comm.group().compare(&odd_group)
44        );
45    } else {
46        assert!(odd_comm.is_none());
47    }
48
49    #[cfg(not(msmpi))]
50    {
51        if even_group.rank().is_some() {
52            let even_comm = world.split_by_subgroup(&even_group);
53            assert!(even_comm.is_some());
54            let even_comm = even_comm.unwrap();
55            assert_eq!(
56                GroupRelation::Identical,
57                even_comm.group().compare(&even_group)
58            );
59
60            let no_comm = world.split_by_subgroup(&odd_group);
61            assert!(no_comm.is_none());
62        }
63    }
64
65    let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
66    assert!(oddness_comm.is_some());
67    let oddness_comm = oddness_comm.unwrap();
68    assert_eq!(
69        GroupRelation::Identical,
70        oddness_comm.group().compare(my_group)
71    );
72
73    let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
74        Color::with_value(0)
75    } else {
76        Color::undefined()
77    });
78    if world.rank() % 2 != 0 {
79        assert!(odd_comm.is_some());
80        let odd_comm = odd_comm.unwrap();
81        assert_eq!(
82            GroupRelation::Identical,
83            odd_comm.group().compare(&odd_group)
84        );
85    } else {
86        assert!(odd_comm.is_none());
87    }
88}
Source

fn split_by_subgroup<G>(&self, group: &G) -> Option<UserCommunicator>
where G: Group + ?Sized,

Split a communicator by subgroup.

Like split_by_subgroup_collective() but not a collective operation.

§Examples

See examples/split.rs

§Standard section(s)

6.4.2

Examples found in repository?
examples/split.rs (line 52)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10
11    let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
12    let odd_group = world.group().include(&odd[..]);
13    let even_group = world.group().difference(&odd_group);
14    assert!(
15        (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
16            || (even_group.rank().is_none() && odd_group.rank().is_some())
17    );
18    let my_group = if odd_group.rank().is_some() {
19        &odd_group
20    } else {
21        &even_group
22    };
23    let empty_group = SystemGroup::empty();
24
25    let oddness_comm = world.split_by_subgroup_collective(my_group);
26    assert!(oddness_comm.is_some());
27    let oddness_comm = oddness_comm.unwrap();
28    assert_eq!(
29        GroupRelation::Identical,
30        oddness_comm.group().compare(my_group)
31    );
32
33    let odd_comm = if odd_group.rank().is_some() {
34        world.split_by_subgroup_collective(&odd_group)
35    } else {
36        world.split_by_subgroup_collective(&empty_group)
37    };
38    if odd_group.rank().is_some() {
39        assert!(odd_comm.is_some());
40        let odd_comm = odd_comm.unwrap();
41        assert_eq!(
42            GroupRelation::Identical,
43            odd_comm.group().compare(&odd_group)
44        );
45    } else {
46        assert!(odd_comm.is_none());
47    }
48
49    #[cfg(not(msmpi))]
50    {
51        if even_group.rank().is_some() {
52            let even_comm = world.split_by_subgroup(&even_group);
53            assert!(even_comm.is_some());
54            let even_comm = even_comm.unwrap();
55            assert_eq!(
56                GroupRelation::Identical,
57                even_comm.group().compare(&even_group)
58            );
59
60            let no_comm = world.split_by_subgroup(&odd_group);
61            assert!(no_comm.is_none());
62        }
63    }
64
65    let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
66    assert!(oddness_comm.is_some());
67    let oddness_comm = oddness_comm.unwrap();
68    assert_eq!(
69        GroupRelation::Identical,
70        oddness_comm.group().compare(my_group)
71    );
72
73    let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
74        Color::with_value(0)
75    } else {
76        Color::undefined()
77    });
78    if world.rank() % 2 != 0 {
79        assert!(odd_comm.is_some());
80        let odd_comm = odd_comm.unwrap();
81        assert_eq!(
82            GroupRelation::Identical,
83            odd_comm.group().compare(&odd_group)
84        );
85    } else {
86        assert!(odd_comm.is_none());
87    }
88}
Source

fn split_by_subgroup_with_tag<G>( &self, group: &G, tag: Tag, ) -> Option<UserCommunicator>
where G: Group + ?Sized,

Split a communicator by subgroup

Like split_by_subgroup() but can avoid collision of concurrent calls (i.e. multithreaded) by passing in distinct tags.

§Standard section(s)

6.4.2

Source

fn group(&self) -> UserGroup

The group associated with this communicator

§Standard section(s)

6.3.2

Examples found in repository?
examples/group.rs (line 12)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let g = world.group();
13    // Group accessors and Communicator accessors agree
14    assert_eq!(world.size(), g.size());
15    assert_eq!(world.rank(), g.rank().unwrap());
16
17    // g == g
18    assert_eq!(GroupRelation::Identical, g.compare(&g));
19
20    let h = world.group();
21    // h == g
22    assert_eq!(GroupRelation::Identical, g.compare(&h));
23
24    let i = g.union(&h);
25    // g union h == g union g == g
26    assert_eq!(GroupRelation::Identical, g.compare(&i));
27
28    let empty = g.difference(&h);
29    // g difference h == g difference g = empty Group
30    assert_eq!(
31        GroupRelation::Identical,
32        SystemGroup::empty().compare(&empty)
33    );
34    assert_eq!(0, empty.size());
35
36    // g intersection empty == empty Group
37    assert_eq!(0, g.intersection(&empty).size());
38
39    let first_half: Vec<Rank> = (0..g.size() / 2).collect();
40
41    // f and s are first and second half of g
42    let f = g.include(&first_half[..]);
43    let s = g.exclude(&first_half[..]);
44    // f != s
45    assert_eq!(GroupRelation::Unequal, f.compare(&s));
46
47    // g intersection f == f
48    let f_ = g.intersection(&f);
49    assert_eq!(GroupRelation::Identical, f.compare(&f_));
50    // g intersection s == s
51    let s_ = g.intersection(&s);
52    assert_eq!(GroupRelation::Identical, s.compare(&s_));
53
54    // g difference s == f
55    let f__ = g.difference(&s);
56    assert_eq!(GroupRelation::Identical, f.compare(&f__));
57    // g difference f == s
58    let s__ = g.difference(&f);
59    assert_eq!(GroupRelation::Identical, s.compare(&s__));
60
61    // f union s == g
62    let fs = f.union(&s);
63    assert_eq!(GroupRelation::Identical, g.compare(&fs));
64
65    // f intersection s == empty Group
66    let fs = f.intersection(&s);
67    assert_eq!(GroupRelation::Identical, empty.compare(&fs));
68
69    // rank is either in f or in s
70    assert!(
71        (f.rank().is_some() && s.rank().is_none()) ^ (f.rank().is_none() && s.rank().is_some())
72    );
73
74    // inverting rank mappings
75    let rev: Vec<Rank> = (0..g.size()).rev().collect();
76    let r = g.include(&rev[..]);
77    assert_eq!(
78        Some(rev[g.rank().unwrap() as usize]),
79        r.translate_rank(g.rank().unwrap(), &g)
80    );
81}
More examples
Hide additional examples
examples/split.rs (line 12)
7fn main() {
8    let universe = mpi::initialize().unwrap();
9    let world = universe.world();
10
11    let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
12    let odd_group = world.group().include(&odd[..]);
13    let even_group = world.group().difference(&odd_group);
14    assert!(
15        (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
16            || (even_group.rank().is_none() && odd_group.rank().is_some())
17    );
18    let my_group = if odd_group.rank().is_some() {
19        &odd_group
20    } else {
21        &even_group
22    };
23    let empty_group = SystemGroup::empty();
24
25    let oddness_comm = world.split_by_subgroup_collective(my_group);
26    assert!(oddness_comm.is_some());
27    let oddness_comm = oddness_comm.unwrap();
28    assert_eq!(
29        GroupRelation::Identical,
30        oddness_comm.group().compare(my_group)
31    );
32
33    let odd_comm = if odd_group.rank().is_some() {
34        world.split_by_subgroup_collective(&odd_group)
35    } else {
36        world.split_by_subgroup_collective(&empty_group)
37    };
38    if odd_group.rank().is_some() {
39        assert!(odd_comm.is_some());
40        let odd_comm = odd_comm.unwrap();
41        assert_eq!(
42            GroupRelation::Identical,
43            odd_comm.group().compare(&odd_group)
44        );
45    } else {
46        assert!(odd_comm.is_none());
47    }
48
49    #[cfg(not(msmpi))]
50    {
51        if even_group.rank().is_some() {
52            let even_comm = world.split_by_subgroup(&even_group);
53            assert!(even_comm.is_some());
54            let even_comm = even_comm.unwrap();
55            assert_eq!(
56                GroupRelation::Identical,
57                even_comm.group().compare(&even_group)
58            );
59
60            let no_comm = world.split_by_subgroup(&odd_group);
61            assert!(no_comm.is_none());
62        }
63    }
64
65    let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
66    assert!(oddness_comm.is_some());
67    let oddness_comm = oddness_comm.unwrap();
68    assert_eq!(
69        GroupRelation::Identical,
70        oddness_comm.group().compare(my_group)
71    );
72
73    let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
74        Color::with_value(0)
75    } else {
76        Color::undefined()
77    });
78    if world.rank() % 2 != 0 {
79        assert!(odd_comm.is_some());
80        let odd_comm = odd_comm.unwrap();
81        assert_eq!(
82            GroupRelation::Identical,
83            odd_comm.group().compare(&odd_group)
84        );
85    } else {
86        assert!(odd_comm.is_none());
87    }
88}
Source

fn abort(&self, errorcode: c_int) -> !

Abort program execution

§Standard section(s)

8.7

Source

fn set_name(&self, name: &str)

Set the communicator name

§Standard section(s)

6.8, see the MPI_Comm_set_name function

Examples found in repository?
examples/comm_name.rs (line 12)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    assert_eq!("MPI_COMM_WORLD", world.get_name());
12    world.set_name(CNAME);
13    assert_eq!(CNAME, world.get_name());
14}
Source

fn get_name(&self) -> String

Get the communicator name

§Standard section(s)

6.8, see the MPI_Comm_get_name function

Examples found in repository?
examples/comm_name.rs (line 11)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    assert_eq!("MPI_COMM_WORLD", world.get_name());
12    world.set_name(CNAME);
13    assert_eq!(CNAME, world.get_name());
14}
Source

fn create_cartesian_communicator( &self, dims: &[Count], periods: &[bool], reorder: bool, ) -> Option<CartesianCommunicator>

Creates a communicator with ranks laid out in a multi-dimensional space, allowing for easy neighbor-to-neighbor communication, while providing MPI with information to allow it to better optimize the physical locality of ranks that are logically close.

  • dims - array of spatial extents for the cartesian space
  • periods - Must match length of dims. For i in 0 to dims.len(), periods[i] indicates if axis i is periodic. i.e. if true, the element at dims[i] - 1 in axis i is a neighbor of element 0 in axis i
  • reorder - If true, MPI may re-order ranks in the new communicator.
§Standard section(s)

7.5.1 [MPI_Cart_create]

Examples found in repository?
examples/cartesian.rs (line 20)
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}
Source

fn cartesian_map(&self, dims: &[Count], periods: &[bool]) -> Option<Rank>

Gets the target rank of this rank as-if create_cartesian_communicator had been called with dims, periods, and reorder = true.

Returns None if the local process would not particate in the new CartesianCommunciator.

  • dims - array of spatial extents for the cartesian space
  • periods - Must match length of dims. For i in 0 to dims.len(), periods[i] indicates if axis i is periodic. i.e. if true, the element at dims[i] - 1 in axis i is a neighbor of element 0 in axis i
§Standard section

7.5.8 [MPI_Cart_map]

Examples found in repository?
examples/cartesian_map.rs (line 11)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8
9    let comm = universe.world();
10
11    let new_rank = comm.cartesian_map(&[2, comm.size() / 4], &[false, false]);
12
13    println!("{} -> {:?}", comm.rank(), new_rank);
14}
Source

fn pack_size<Dt>(&self, incount: Count, datatype: &Dt) -> Count
where Dt: Datatype,

Gets the implementation-defined buffer size required to pack ‘incount’ elements of type ‘datatype’.

§Standard section(s)

4.2, see [MPI_Pack_size]

Source

fn pack<Buf>(&self, inbuf: &Buf) -> Vec<u8>
where Buf: ?Sized + Buffer,

Packs inbuf into a byte array with an implementation-defined format. Often paired with unpack to convert back into a specific datatype.

§Standard Sections

4.2, see [MPI_Pack]

Examples found in repository?
examples/pack.rs (line 11)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9
10    let ints = [3i32, 2, 1];
11    let packed = world.pack(&ints[..]);
12
13    let mut new_ints = [0, 0, 0];
14    unsafe {
15        world.unpack_into(&packed, &mut new_ints[..], 0);
16    }
17
18    assert_eq!([3, 2, 1], new_ints);
19}
Source

fn pack_into<Buf>( &self, inbuf: &Buf, outbuf: &mut [u8], position: Count, ) -> Count
where Buf: ?Sized + Buffer,

Packs inbuf into a byte array with an implementation-defined format. Often paired with unpack to convert back into a specific datatype.

§Standard Sections

4.2, see [MPI_Pack]

Source

unsafe fn unpack_into<Buf>( &self, inbuf: &[u8], outbuf: &mut Buf, position: Count, ) -> Count
where Buf: ?Sized + BufferMut,

Unpacks an implementation-specific byte array from pack or pack_into into a buffer of a specific datatype.

§Standard Sections

4.2, see [MPI_Unpack]

§Safety

Unpacking must be succesfull

Examples found in repository?
examples/pack.rs (line 15)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9
10    let ints = [3i32, 2, 1];
11    let packed = world.pack(&ints[..]);
12
13    let mut new_ints = [0, 0, 0];
14    unsafe {
15        world.unpack_into(&packed, &mut new_ints[..], 0);
16    }
17
18    assert_eq!([3, 2, 1], new_ints);
19}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§