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§
Sourcefn size(&self) -> Rank
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?
More examples
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}
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}
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}
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}
- examples/reduce.rs
- examples/immediate_reduce.rs
- examples/immediate_scatter.rs
- examples/barrier.rs
- examples/all_gather_varcount.rs
- examples/ready_send.rs
- examples/immediate_all_gather_varcount.rs
- examples/scatter_varcount.rs
- examples/gather_varcount.rs
- examples/wait_any.rs
- examples/contiguous.rs
- examples/immediate_scatter_varcount.rs
- examples/vector.rs
- examples/immediate_gather_varcount.rs
- examples/readme.rs
- examples/send_receive.rs
- examples/all_gather.rs
- examples/immediate_barrier.rs
- examples/immediate_all_gather.rs
- examples/gather.rs
- examples/group.rs
- examples/cartesian.rs
- examples/split.rs
- examples/immediate_gather.rs
Sourcefn rank(&self) -> Rank
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?
More examples
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}
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}
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}
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}
- examples/scatter.rs
- examples/immediate_all_to_all.rs
- examples/reduce.rs
- examples/datatype_dup.rs
- examples/immediate_reduce.rs
- examples/complex_datatype.rs
- examples/immediate_scan.rs
- examples/immediate_scatter.rs
- examples/barrier.rs
- examples/broadcast_complex.rs
- examples/all_gather_varcount.rs
- examples/ready_send.rs
- examples/broadcast.rs
- examples/immediate_all_gather_varcount.rs
- examples/scatter_varcount.rs
- examples/gather_varcount.rs
- examples/wait_any.rs
- examples/immediate_broadcast.rs
- examples/contiguous.rs
- examples/immediate_scatter_varcount.rs
- examples/vector.rs
- examples/immediate_gather_varcount.rs
- examples/readme.rs
- examples/send_receive.rs
- examples/all_gather.rs
- examples/immediate_barrier.rs
- examples/immediate_all_gather.rs
- examples/gather.rs
- examples/group.rs
- examples/cartesian.rs
- examples/split.rs
- examples/immediate_gather.rs
Sourcefn process_at_rank(&self, r: Rank) -> Process<'_, Self>where
Self: Sized,
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?
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
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}
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}
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}
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}
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}
- examples/broadcast_complex.rs
- examples/ready_send.rs
- examples/broadcast.rs
- examples/scatter_varcount.rs
- examples/gather_varcount.rs
- examples/wait_any.rs
- examples/immediate_broadcast.rs
- examples/contiguous.rs
- examples/immediate_scatter_varcount.rs
- examples/vector.rs
- examples/immediate_gather_varcount.rs
- examples/readme.rs
- examples/send_receive.rs
- examples/immediate_reduce.rs
- examples/reduce.rs
- examples/immediate_barrier.rs
- examples/gather.rs
- examples/immediate_gather.rs
Sourcefn any_process(&self) -> AnyProcess<'_, Self>where
Self: Sized,
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?
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
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}
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}
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}
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}
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}
Sourcefn this_process(&self) -> Process<'_, Self>where
Self: Sized,
fn this_process(&self) -> Process<'_, Self>where
Self: Sized,
A Process
for the calling process
Examples found in repository?
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
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}
Sourcefn compare<C>(&self, other: &C) -> CommunicatorRelationwhere
C: Communicator + ?Sized,
fn compare<C>(&self, other: &C) -> CommunicatorRelationwhere
C: Communicator + ?Sized,
Sourcefn duplicate(&self) -> UserCommunicator
fn duplicate(&self) -> UserCommunicator
Sourcefn split_by_color(&self, color: Color) -> Option<UserCommunicator>
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?
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}
Sourcefn split_by_color_with_key(
&self,
color: Color,
key: Key,
) -> Option<UserCommunicator>
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
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
)
Sourcefn split_by_subgroup_collective<G>(&self, group: &G) -> Option<UserCommunicator>
fn split_by_subgroup_collective<G>(&self, group: &G) -> Option<UserCommunicator>
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?
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}
Sourcefn split_by_subgroup<G>(&self, group: &G) -> Option<UserCommunicator>
fn split_by_subgroup<G>(&self, group: &G) -> Option<UserCommunicator>
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?
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}
Sourcefn split_by_subgroup_with_tag<G>(
&self,
group: &G,
tag: Tag,
) -> Option<UserCommunicator>
fn split_by_subgroup_with_tag<G>( &self, group: &G, tag: Tag, ) -> Option<UserCommunicator>
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
Sourcefn group(&self) -> UserGroup
fn group(&self) -> UserGroup
Examples found in repository?
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
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}
Sourcefn create_cartesian_communicator(
&self,
dims: &[Count],
periods: &[bool],
reorder: bool,
) -> Option<CartesianCommunicator>
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 spaceperiods
- Must match length ofdims
. Fori
in 0 todims.len()
,periods[i]
indicates if axisi
is periodic. i.e. iftrue
, the element atdims[i] - 1
in axisi
is a neighbor of element 0 in axisi
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?
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}
Sourcefn cartesian_map(&self, dims: &[Count], periods: &[bool]) -> Option<Rank>
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 spaceperiods
- Must match length ofdims
. Fori
in 0 todims.len()
,periods[i]
indicates if axisi
is periodic. i.e. iftrue
, the element atdims[i] - 1
in axisi
is a neighbor of element 0 in axisi
§Standard section
7.5.8 [MPI_Cart_map
]
Sourcefn pack_size<Dt>(&self, incount: Count, datatype: &Dt) -> Countwhere
Dt: Datatype,
fn pack_size<Dt>(&self, incount: Count, datatype: &Dt) -> Countwhere
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
]
Sourcefn pack<Buf>(&self, inbuf: &Buf) -> Vec<u8> ⓘ
fn pack<Buf>(&self, inbuf: &Buf) -> Vec<u8> ⓘ
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?
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}
Sourcefn pack_into<Buf>(
&self,
inbuf: &Buf,
outbuf: &mut [u8],
position: Count,
) -> Count
fn pack_into<Buf>( &self, inbuf: &Buf, outbuf: &mut [u8], position: Count, ) -> Count
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
]
Sourceunsafe fn unpack_into<Buf>(
&self,
inbuf: &[u8],
outbuf: &mut Buf,
position: Count,
) -> Count
unsafe fn unpack_into<Buf>( &self, inbuf: &[u8], outbuf: &mut Buf, position: Count, ) -> Count
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?
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.