pub trait Communicator: AsHandle {
Show 26 methods
// Required method
fn target_size(&self) -> Rank;
// Provided methods
fn size(&self) -> Rank { ... }
fn rank(&self) -> Rank { ... }
fn process_at_rank(&self, r: Rank) -> Process<'_> { ... }
fn any_process(&self) -> AnyProcess<'_> { ... }
fn this_process(&self) -> Process<'_> { ... }
fn compare(&self, other: &dyn Communicator) -> CommunicatorRelation { ... }
fn duplicate(&self) -> SimpleCommunicator { ... }
fn split_by_color(&self, color: Color) -> Option<SimpleCommunicator> { ... }
fn split_by_color_with_key(
&self,
color: Color,
key: Key,
) -> Option<SimpleCommunicator> { ... }
fn split_shared(&self, key: c_int) -> SimpleCommunicator { ... }
fn split_by_subgroup_collective(
&self,
group: &dyn Group,
) -> Option<SimpleCommunicator> { ... }
fn split_by_subgroup(&self, group: &dyn Group) -> Option<SimpleCommunicator> { ... }
fn split_by_subgroup_with_tag(
&self,
group: &dyn Group,
tag: Tag,
) -> Option<SimpleCommunicator> { ... }
fn group(&self) -> UserGroup { ... }
fn abort(&self, errorcode: c_int) -> ! { ... }
fn test_inter(&self) -> bool { ... }
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,
Self: Sized { ... }
fn pack<Buf>(&self, inbuf: &Buf) -> Vec<u8> ⓘ
where Buf: ?Sized + Buffer,
Self: Sized { ... }
fn pack_into<Buf>(
&self,
inbuf: &Buf,
outbuf: &mut [u8],
position: Count,
) -> Count
where Buf: ?Sized + Buffer,
Self: Sized { ... }
unsafe fn unpack_into<Buf>(
&self,
inbuf: &[u8],
outbuf: &mut Buf,
position: Count,
) -> Count
where Buf: ?Sized + BufferMut,
Self: Sized { ... }
fn parent(&self) -> Option<InterCommunicator> { ... }
}
Expand description
Communicators are contexts for communication
Required Methods§
Sourcefn target_size(&self) -> Rank
fn target_size(&self) -> Rank
Returns the number of processes available to communicate with in this Communicator
. For
intra-communicators, this is equivalent to size
. For inter-communicators,
this is equivalent to remote_size
.
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
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8
9 let rank = world.rank();
10 let count = world.size() as usize;
11
12 let mut a = vec![false; count];
13 world.all_gather_into(&(rank % 2 == 0), &mut a[..]);
14
15 let answer: Vec<_> = (0..count).map(|i| i % 2 == 0).collect();
16
17 assert_eq!(answer, a);
18}
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8 let rank = world.rank();
9 let size = world.size();
10
11 let u = vec![rank; size as usize];
12 let mut v = vec![0; size as usize];
13
14 world.all_to_all_into(&u[..], &mut v[..]);
15
16 println!("u: {:?}", u);
17 println!("v: {:?}", v);
18
19 assert!(v.into_iter().zip(0..size).all(|(i, j)| i == j));
20}
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9 let rank = world.rank();
10 let size = world.size();
11 let root_rank = 0;
12 let root_process = world.process_at_rank(root_rank);
13
14 let mut x = 0 as Rank;
15 if rank == root_rank {
16 let v = (0..size).collect::<Vec<_>>();
17 root_process.scatter_into_root(&v, &mut x);
18 } else {
19 root_process.scatter_into(&mut x);
20 }
21 assert_eq!(x, rank);
22}
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8 let rank = world.rank();
9 let size = world.size();
10
11 let u = vec![rank; size as usize];
12 let mut v = vec![0; size as usize];
13
14 mpi::request::scope(|scope| {
15 world
16 .immediate_all_to_all_into(scope, &u[..], &mut v[..])
17 .wait();
18 });
19
20 println!("u: {:?}", u);
21 println!("v: {:?}", v);
22
23 assert!(v.into_iter().zip(0..size).all(|(i, j)| i == j));
24}
- examples/reduce.rs
- examples/immediate_reduce.rs
- examples/dyn_communicator.rs
- examples/immediate_scatter.rs
- examples/barrier.rs
- examples/structured.rs
- examples/all_gather_varcount.rs
- examples/attributes.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/spawn_multiple.rs
- examples/immediate_scatter_varcount.rs
- examples/vector.rs
- examples/readme.rs
- examples/spawn.rs
- examples/send_receive.rs
- examples/immediate_gather_varcount.rs
- examples/all_gather.rs
- examples/immediate_barrier.rs
- examples/immediate_multiple_test.rs
- examples/immediate_all_gather.rs
- examples/gather.rs
- examples/group.rs
- examples/cartesian.rs
- examples/split.rs
- examples/immediate_gather.rs
- examples/immediate_multiple_requests.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
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8
9 let rank = world.rank();
10 let count = world.size() as usize;
11
12 let mut a = vec![false; count];
13 world.all_gather_into(&(rank % 2 == 0), &mut a[..]);
14
15 let answer: Vec<_> = (0..count).map(|i| i % 2 == 0).collect();
16
17 assert_eq!(answer, a);
18}
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8 let rank = world.rank();
9 let size = world.size();
10
11 let u = vec![rank; size as usize];
12 let mut v = vec![0; size as usize];
13
14 world.all_to_all_into(&u[..], &mut v[..]);
15
16 println!("u: {:?}", u);
17 println!("v: {:?}", v);
18
19 assert!(v.into_iter().zip(0..size).all(|(i, j)| i == j));
20}
11fn main() {
12 let universe = mpi::initialize().unwrap();
13 let world = universe.world();
14 let rank = world.rank();
15
16 let mut x = 0;
17 world.scan_into(&rank, &mut x, &SystemOperation::sum());
18 assert_eq!(x, (rank * (rank + 1)) / 2);
19
20 let y = rank + 1;
21 let mut z = 0;
22 world.exclusive_scan_into(&y, &mut z, &SystemOperation::product());
23 if rank > 0 {
24 assert_eq!(z, fac(y - 1));
25 }
26}
- 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/all_gather_varcount.rs
- examples/broadcast.rs
- examples/ready_send.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/spawn_multiple.rs
- examples/immediate_scatter_varcount.rs
- examples/vector.rs
- examples/readme.rs
- examples/spawn.rs
- examples/send_receive.rs
- examples/immediate_gather_varcount.rs
- examples/all_gather.rs
- examples/immediate_barrier.rs
- examples/immediate_multiple_test.rs
- examples/immediate_all_gather.rs
- examples/gather.rs
- examples/group.rs
- examples/cartesian.rs
- examples/split.rs
- examples/immediate_gather.rs
- examples/immediate_multiple_requests.rs
Sourcefn process_at_rank(&self, r: Rank) -> Process<'_>
fn process_at_rank(&self, r: Rank) -> Process<'_>
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?
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9 let rank = world.rank();
10 let size = world.size();
11 let root_rank = 0;
12 let root_process = world.process_at_rank(root_rank);
13
14 let mut x = 0 as Rank;
15 if rank == root_rank {
16 let v = (0..size).collect::<Vec<_>>();
17 root_process.scatter_into_root(&v, &mut x);
18 } else {
19 root_process.scatter_into(&mut x);
20 }
21 assert_eq!(x, rank);
22}
More examples
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9
10 let root_process = world.process_at_rank(0);
11
12 let int_type = i32::equivalent_datatype().dup();
13
14 let mut ints = if world.rank() == 0 {
15 [1i32, 2, 3, 4]
16 } else {
17 [0, 0, 0, 0]
18 };
19
20 let mut buffer =
21 unsafe { DynBufferMut::from_raw(ints.as_mut_ptr(), ints.count(), int_type.as_ref()) };
22
23 root_process.broadcast_into(&mut buffer);
24
25 assert_eq!([1, 2, 3, 4], ints);
26}
9fn send_recv<'a, S: Scope<'a> + Copy>(
10 world: &impl Communicator,
11 scope: S,
12 coll: &mut RequestCollection<'a, [i32; 4]>,
13 next_proc: Rank,
14 prev_proc: Rank,
15 x: &'a [[i32; 4]],
16 recv: &'a mut [[i32; 4]],
17) {
18 for elm in x {
19 let sreq = world.process_at_rank(next_proc).immediate_send(scope, elm);
20 coll.add(sreq);
21 }
22 for elm in recv.iter_mut() {
23 let rreq = world
24 .process_at_rank(prev_proc)
25 .immediate_receive_into(scope, elm);
26 coll.add(rreq);
27 }
28}
50fn main() {
51 let universe = mpi::initialize().unwrap();
52 let world = universe.world();
53
54 let root_process = world.process_at_rank(0);
55
56 let mut data = if world.rank() == 0 {
57 ComplexDatatype {
58 b: true,
59 ints: [1, -2, 3, -4],
60 tuple: TupleType([-0.1, 0.1], 7),
61 }
62 } else {
63 ComplexDatatype::default()
64 };
65
66 root_process.broadcast_into(&mut data);
67
68 assert_eq!(true, data.b);
69 assert_eq!([1, -2, 3, -4], data.ints);
70 assert_eq!([-0.1, 0.1], data.tuple.0);
71 assert_eq!(7, data.tuple.1);
72}
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9 let rank = world.rank();
10 let size = world.size();
11 let root_rank = 0;
12 let root_process = world.process_at_rank(root_rank);
13
14 let mut x = 0 as Rank;
15 if rank == root_rank {
16 let v = (0..size).collect::<Vec<_>>();
17 mpi::request::scope(|scope| {
18 let req = root_process.immediate_scatter_into_root(scope, &v[..], &mut x);
19 req.wait();
20 });
21 } else {
22 mpi::request::scope(|scope| {
23 let req = root_process.immediate_scatter_into(scope, &mut x);
24 req.wait();
25 });
26 }
27 assert_eq!(x, rank);
28}
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8 let receiver_rank = 0;
9
10 if world.rank() == receiver_rank {
11 let n = (world.size() - 1) as usize;
12 let mut buf = vec![0u64; 2 * n];
13 for x in buf[0..n].iter_mut() {
14 world.any_process().receive_into(x);
15 }
16 world.barrier();
17 for x in buf[n..2 * n].iter_mut() {
18 world.any_process().receive_into(x);
19 }
20 println!("{:?}", buf);
21 assert!(buf[0..n].iter().all(|&x| x == 1));
22 assert!(buf[n..2 * n].iter().all(|&x| x == 2));
23 } else {
24 world.process_at_rank(0).send(&1u64);
25 world.barrier();
26 world.process_at_rank(0).send(&2u64);
27 }
28}
- examples/structured.rs
- examples/broadcast.rs
- examples/ready_send.rs
- examples/scatter_varcount.rs
- examples/gather_varcount.rs
- examples/wait_any.rs
- examples/immediate_broadcast.rs
- examples/contiguous.rs
- examples/spawn_multiple.rs
- examples/immediate_scatter_varcount.rs
- examples/vector.rs
- examples/readme.rs
- examples/spawn.rs
- examples/send_receive.rs
- examples/immediate_gather_varcount.rs
- examples/immediate_reduce.rs
- examples/reduce.rs
- examples/immediate_barrier.rs
- examples/gather.rs
- examples/immediate_gather.rs
- examples/immediate_multiple_requests.rs
Sourcefn any_process(&self) -> AnyProcess<'_>
fn any_process(&self) -> AnyProcess<'_>
Returns an AnyProcess
identifier that can be used, e.g. as a Source
in point to point
communication.
Examples found in repository?
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8 let receiver_rank = 0;
9
10 if world.rank() == receiver_rank {
11 let n = (world.size() - 1) as usize;
12 let mut buf = vec![0u64; 2 * n];
13 for x in buf[0..n].iter_mut() {
14 world.any_process().receive_into(x);
15 }
16 world.barrier();
17 for x in buf[n..2 * n].iter_mut() {
18 world.any_process().receive_into(x);
19 }
20 println!("{:?}", buf);
21 assert!(buf[0..n].iter().all(|&x| x == 1));
22 assert!(buf[n..2 * n].iter().all(|&x| x == 2));
23 } else {
24 world.process_at_rank(0).send(&1u64);
25 world.barrier();
26 world.process_at_rank(0).send(&2u64);
27 }
28}
More examples
8fn main() {
9 let mut universe = mpi::initialize().unwrap();
10 // Try to attach a buffer.
11 universe.set_buffer_size(BUFFER_SIZE);
12 // Check buffer size matches.
13 assert_eq!(universe.buffer_size(), BUFFER_SIZE);
14 // Try to detach the buffer.
15 universe.detach_buffer();
16 // Attach another buffer.
17 universe.set_buffer_size(BUFFER_SIZE);
18
19 let world = universe.world();
20
21 let x = vec![std::f32::consts::PI; 1024];
22 let mut y = vec![0.0; 1024];
23 mpi::request::scope(|scope| {
24 let _rreq = WaitGuard::from(
25 world
26 .any_process()
27 .immediate_receive_into(scope, &mut y[..]),
28 );
29 world.this_process().buffered_send(&x[..]);
30 });
31 assert_eq!(x, y);
32}
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10
11 let x = std::f32::consts::PI;
12 let mut y: f32 = 0.0;
13
14 mpi::request::scope(|scope| {
15 if world.rank() == 0 {
16 let mut requests = Vec::new();
17 for i in 1..world.size() {
18 requests.push(
19 world
20 .process_at_rank(i)
21 .immediate_synchronous_send(scope, &x),
22 );
23 }
24
25 println!("World size {}", world.size());
26 while let Some((index, _status)) = mpi::request::wait_any(&mut requests) {
27 println!("Request with index {} completed", index);
28 }
29 println!("All requests completed");
30 } else {
31 let secs = time::Duration::from_secs(world.rank() as u64);
32
33 thread::sleep(secs);
34
35 let rreq = world.any_process().immediate_receive_into(scope, &mut y);
36 rreq.wait();
37 println!("Process {} received data", world.rank());
38 }
39 });
40}
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9 let size = world.size();
10 let rank = world.rank();
11
12 let next_rank = (rank + 1) % size;
13 let previous_rank = (rank - 1 + size) % size;
14
15 let msg = vec![rank, 2 * rank, 4 * rank];
16 mpi::request::scope(|scope| {
17 let _sreq = WaitGuard::from(
18 world
19 .process_at_rank(next_rank)
20 .immediate_send(scope, &msg[..]),
21 );
22
23 let (msg, status) = world.any_process().receive_vec();
24
25 println!(
26 "Process {} got message {:?}.\nStatus is: {:?}",
27 rank, msg, status
28 );
29 let x = status.source_rank();
30 assert_eq!(x, previous_rank);
31 assert_eq!(vec![x, 2 * x, 4 * x], msg);
32
33 let root_rank = 0;
34 let root_process = world.process_at_rank(root_rank);
35
36 let mut a;
37 if world.rank() == root_rank {
38 a = vec![2, 4, 8, 16];
39 println!("Root broadcasting value: {:?}.", &a[..]);
40 } else {
41 a = vec![0; 4];
42 }
43 root_process.broadcast_into(&mut a[..]);
44 println!("Rank {} received value: {:?}.", world.rank(), &a[..]);
45 assert_eq!(&a[..], &[2, 4, 8, 16]);
46 });
47}
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 = (rank + 1) % size;
14 let next_process = world.process_at_rank(next_rank);
15 let previous_rank = (rank - 1 + size) % size;
16 let previous_process = world.process_at_rank(previous_rank);
17
18 let (msg, status): (Rank, _) = p2p::send_receive(&rank, &previous_process, &next_process);
19 println!(
20 "Process {} got message {}.\nStatus is: {:?}",
21 rank, msg, status
22 );
23 world.barrier();
24 assert_eq!(msg, next_rank);
25
26 if rank > 0 {
27 let msg: [Rank; 3] = [rank, rank + 1, rank - 1];
28 world.process_at_rank(0).send(&msg);
29 } else {
30 for _ in 1..size {
31 let (msg, status) = world.any_process().receive_vec::<Rank>();
32 println!(
33 "Process {} got long message {:?}.\nStatus is: {:?}",
34 rank, msg, status
35 );
36
37 let x = status.source_rank();
38 let v = vec![x, x + 1, x - 1];
39 assert_eq!(v, msg);
40 }
41 }
42 world.barrier();
43
44 let mut x = rank;
45 p2p::send_receive_replace_into(&mut x, &next_process, &previous_process);
46 assert_eq!(x, previous_rank);
47}
10fn main() {
11 use mpi::traits::*;
12 let universe = mpi::initialize().unwrap();
13 let world = universe.world();
14 let size = world.size();
15 let receiver_rank = 0;
16
17 if world.rank() == receiver_rank {
18 // receiver process
19 let n = (size - 1) as usize;
20 let mut buf = vec![0u64; 3 * n];
21 // receive first 2 * n messages
22 for x in buf[0..2 * n].iter_mut() {
23 world.any_process().receive_into(x);
24 }
25 // signal the waiting senders that 2 * n messages have been received
26 let breq = world.immediate_barrier();
27 // receive remaining n messages
28 for x in buf[2 * n..3 * n].iter_mut() {
29 world.any_process().receive_into(x);
30 }
31 println!("{:?}", buf);
32 // messages "1" and "2" may be interleaved, but all have to be contained within the first
33 // 2 * n slots of the buffer
34 assert_eq!(buf[0..2 * n].iter().filter(|&&x| x == 1).count(), n);
35 assert_eq!(buf[0..2 * n].iter().filter(|&&x| x == 2).count(), n);
36 // the last n slots in the buffer may only contain message "3"
37 assert!(buf[2 * n..3 * n].iter().all(|&x| x == 3));
38 // clean up the barrier request
39 breq.wait();
40 } else {
41 // sender processes
42 // send message "1"
43 world.process_at_rank(0).send(&1u64);
44 // join barrier, but do not block
45 let breq = world.immediate_barrier();
46 // send message "2"
47 world.process_at_rank(0).send(&2u64);
48 // wait for receiver process to receive the first 2 * n messages
49 breq.wait();
50 // send message "3"
51 world.process_at_rank(0).send(&3u64);
52 }
53}
Sourcefn this_process(&self) -> Process<'_>
fn this_process(&self) -> Process<'_>
A Process
for the calling process
Examples found in repository?
8fn main() {
9 let mut universe = mpi::initialize().unwrap();
10 // Try to attach a buffer.
11 universe.set_buffer_size(BUFFER_SIZE);
12 // Check buffer size matches.
13 assert_eq!(universe.buffer_size(), BUFFER_SIZE);
14 // Try to detach the buffer.
15 universe.detach_buffer();
16 // Attach another buffer.
17 universe.set_buffer_size(BUFFER_SIZE);
18
19 let world = universe.world();
20
21 let x = vec![std::f32::consts::PI; 1024];
22 let mut y = vec![0.0; 1024];
23 mpi::request::scope(|scope| {
24 let _rreq = WaitGuard::from(
25 world
26 .any_process()
27 .immediate_receive_into(scope, &mut y[..]),
28 );
29 world.this_process().buffered_send(&x[..]);
30 });
31 assert_eq!(x, y);
32}
More examples
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10
11 let x = std::f32::consts::PI;
12 let mut y: f32 = 0.0;
13
14 mpi::request::scope(|scope| {
15 let mut sreq = world.this_process().immediate_send(scope, &x);
16 let rreq = world.any_process().immediate_receive_into(scope, &mut y);
17 rreq.wait();
18 loop {
19 match sreq.test() {
20 Ok(_) => {
21 break;
22 }
23 Err(req) => {
24 sreq = req;
25 }
26 }
27 }
28 });
29 assert_eq!(x, y);
30
31 y = 0.0;
32 mpi::request::scope(|scope| {
33 let _rreq = WaitGuard::from(world.any_process().immediate_receive_into(scope, &mut y));
34 // WARNING: the *ready* send is *only* permissible here because we're
35 // sending to self. Use of *ready* would be a race condition and thus
36 // erroneous otherwise.
37 //
38 // One would typically use `immediate_send` to avoid the unsafety.
39 let _sreq =
40 WaitGuard::from(unsafe { world.this_process().immediate_ready_send(scope, &x) });
41 });
42 assert_eq!(x, y);
43
44 assert!(world.any_process().immediate_probe().is_none());
45 assert!(world.any_process().immediate_matched_probe().is_none());
46
47 y = 0.0;
48 mpi::request::scope(|scope| {
49 let _sreq: WaitGuard<_, _> = world
50 .this_process()
51 .immediate_synchronous_send(scope, &x)
52 .into();
53 let (msg, _) = loop {
54 // Spin for message availability. There is no guarantee that
55 // immediate sends, even to the same process, will be immediately
56 // visible to an immediate probe.
57 let preq = world.any_process().immediate_matched_probe();
58 if let Some(p) = preq {
59 break p;
60 }
61 };
62 let _rreq: WaitGuard<_, _> = msg.immediate_matched_receive_into(scope, &mut y).into();
63 });
64 assert_eq!(x, y);
65
66 let future = world.any_process().immediate_receive();
67 world.this_process().send(&x);
68 let (msg, _) = future.get();
69 assert_eq!(x, msg);
70
71 let future = world.any_process().immediate_receive();
72 let res = future.r#try();
73 assert!(res.is_err());
74 let mut future = res.err().unwrap();
75 world.this_process().send(&x);
76 loop {
77 match future.r#try() {
78 Ok((msg, _)) => {
79 assert_eq!(x, msg);
80 break;
81 }
82 Err(f) => {
83 future = f;
84 }
85 }
86 }
87
88 mpi::request::scope(|scope| {
89 let sreq = world.this_process().immediate_send(scope, &x);
90 sreq.cancel();
91 sreq.wait();
92
93 let _sreq = CancelGuard::from(world.this_process().immediate_receive_into(scope, &mut y));
94 });
95}
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 x: i32 = 100;
14 let mut y: i32 = 0;
15
16 mpi::request::scope(|scope| {
17 let sreq = world.this_process().immediate_send(scope, &x);
18 let rreq = world.this_process().immediate_receive_into(scope, &mut y);
19 let result = rreq.wait_for_data();
20 assert_eq!(*result, x);
21 sreq.wait();
22 });
23
24 // Test wait_any()
25 let mut result: Vec<i32> = vec![0; COUNT];
26 let prev_proc = (rank - 1 + size) % size;
27 let next_proc = (rank + 1) % size;
28 mpi::request::multiple_scope(2 * COUNT, |scope, coll| {
29 for _ in 0..result.len() {
30 let sreq = world
31 .process_at_rank(next_proc)
32 .immediate_send(scope, &rank);
33 coll.add(sreq);
34 }
35 for val in result.iter_mut() {
36 let rreq = world
37 .process_at_rank(prev_proc)
38 .immediate_receive_into(scope, val);
39 coll.add(rreq);
40 }
41 let mut send_count = 0;
42 let mut recv_count = 0;
43 while coll.incomplete() > 0 {
44 let (_, _, result) = coll.wait_any().unwrap();
45 if *result == rank {
46 send_count += 1;
47 } else {
48 recv_count += 1;
49 }
50 }
51 assert_eq!(send_count, COUNT);
52 assert_eq!(recv_count, COUNT);
53 });
54
55 let mut result: Vec<i32> = vec![0; COUNT];
56 // Test wait_some()
57 mpi::request::multiple_scope(2 * COUNT, |scope, coll| {
58 for _ in 0..result.len() {
59 let sreq = world
60 .process_at_rank(next_proc)
61 .immediate_send(scope, &rank);
62 coll.add(sreq);
63 }
64 for val in result.iter_mut() {
65 let rreq = world
66 .process_at_rank(prev_proc)
67 .immediate_receive_into(scope, val);
68 coll.add(rreq);
69 }
70 let mut send_count = 0;
71 let mut recv_count = 0;
72 let mut some_buf = vec![];
73 let mut finished = 0;
74 while coll.incomplete() > 0 {
75 coll.wait_some(&mut some_buf);
76 println!("wait_some(): {} request(s) completed", some_buf.len());
77 finished += some_buf.len();
78 assert_eq!(coll.incomplete(), 2 * COUNT - finished);
79 for &(_, _, result) in some_buf.iter() {
80 if *result == rank {
81 send_count += 1;
82 } else {
83 recv_count += 1;
84 }
85 }
86 }
87 assert_eq!(send_count, COUNT);
88 assert_eq!(recv_count, COUNT);
89 });
90
91 let mut result: Vec<i32> = vec![0; COUNT];
92 // Test wait_all()
93 mpi::request::multiple_scope(2 * COUNT, |scope, coll| {
94 for _ in 0..result.len() {
95 let sreq = world
96 .process_at_rank(next_proc)
97 .immediate_send(scope, &rank);
98 coll.add(sreq);
99 }
100 for val in result.iter_mut() {
101 let rreq = world
102 .process_at_rank(prev_proc)
103 .immediate_receive_into(scope, val);
104 coll.add(rreq);
105 }
106
107 let mut out = vec![];
108 coll.wait_all(&mut out);
109 assert_eq!(out.len(), 2 * COUNT);
110 let mut send_count = 0;
111 let mut recv_count = 0;
112 for (_, _, result) in out {
113 if *result == rank {
114 send_count += 1;
115 } else {
116 recv_count += 1;
117 }
118 }
119 assert_eq!(send_count, COUNT);
120 assert_eq!(recv_count, COUNT);
121 });
122
123 // Check wait_*() with a buffer of increasing values
124 let x: Vec<i32> = (0..COUNT as i32).collect();
125 let mut result: Vec<i32> = vec![0; COUNT];
126 mpi::request::multiple_scope(2 * COUNT, |scope, coll| {
127 for elm in &x {
128 let sreq = world.process_at_rank(next_proc).immediate_send(scope, elm);
129 coll.add(sreq);
130 }
131 for val in result.iter_mut() {
132 let rreq = world
133 .process_at_rank(prev_proc)
134 .immediate_receive_into(scope, val);
135 coll.add(rreq);
136 }
137 let mut out: Vec<(usize, Status, &i32)> = vec![];
138 coll.wait_all(&mut out);
139 assert_eq!(out.len(), 2 * COUNT);
140 });
141 // Ensure the result and x are an incrementing array of integers
142 result.sort();
143 assert_eq!(result, x);
144}
Sourcefn compare(&self, other: &dyn Communicator) -> CommunicatorRelation
fn compare(&self, other: &dyn Communicator) -> CommunicatorRelation
Sourcefn duplicate(&self) -> SimpleCommunicator
fn duplicate(&self) -> SimpleCommunicator
Examples found in repository?
More examples
48fn main() {
49 let universe = mpi::initialize().unwrap();
50 println!("Universe: {:?}", universe.size());
51 let mut world = universe.world();
52 println!("World : {}", world.size());
53 world.set_attr(MyData1(10));
54 world.set_attr(MyData2(20));
55 assert_eq!(world.get_attr::<MyData1>(), Some(MyData1(10)).as_ref());
56 println!("Got from world: {:?}", world.get_attr::<MyData1>());
57 assert_eq!(world.get_attr::<MyData2>(), Some(MyData2(20)).as_ref());
58 println!("Got from world: {:?}", world.get_attr::<MyData2>());
59 let comm = world.duplicate();
60 assert_eq!(comm.get_attr::<MyData1>(), Some(MyData1(11)).as_ref());
61 println!("Got from comm: {:?}", comm.get_attr::<MyData1>());
62 assert_eq!(comm.get_attr::<MyData2>(), None);
63 println!("Got from comm: {:?}", comm.get_attr::<MyData2>());
64 let mut comm2 = comm.duplicate();
65 with_trait_object(&mut comm2);
66}
Sourcefn split_by_color(&self, color: Color) -> Option<SimpleCommunicator>
fn split_by_color(&self, color: Color) -> Option<SimpleCommunicator>
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?
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9
10 let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
11 let odd_group = world.group().include(&odd[..]);
12 let even_group = world.group().difference(&odd_group);
13 assert!(
14 (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
15 || (even_group.rank().is_none() && odd_group.rank().is_some())
16 );
17 let my_group = if odd_group.rank().is_some() {
18 &odd_group
19 } else {
20 &even_group
21 };
22 let empty_group = SystemGroup::empty();
23
24 let oddness_comm = world.split_by_subgroup_collective(my_group);
25 assert!(oddness_comm.is_some());
26 let oddness_comm = oddness_comm.unwrap();
27 assert_eq!(
28 GroupRelation::Identical,
29 oddness_comm.group().compare(my_group)
30 );
31
32 let odd_comm = if odd_group.rank().is_some() {
33 world.split_by_subgroup_collective(&odd_group)
34 } else {
35 world.split_by_subgroup_collective(&empty_group)
36 };
37 if odd_group.rank().is_some() {
38 assert!(odd_comm.is_some());
39 let odd_comm = odd_comm.unwrap();
40 assert_eq!(
41 GroupRelation::Identical,
42 odd_comm.group().compare(&odd_group)
43 );
44 } else {
45 assert!(odd_comm.is_none());
46 }
47
48 #[cfg(not(msmpi))]
49 {
50 if even_group.rank().is_some() {
51 let even_comm = world.split_by_subgroup(&even_group);
52 assert!(even_comm.is_some());
53 let even_comm = even_comm.unwrap();
54 assert_eq!(
55 GroupRelation::Identical,
56 even_comm.group().compare(&even_group)
57 );
58
59 let no_comm = world.split_by_subgroup(&odd_group);
60 assert!(no_comm.is_none());
61 }
62 }
63
64 let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
65 assert!(oddness_comm.is_some());
66 let oddness_comm = oddness_comm.unwrap();
67 assert_eq!(
68 GroupRelation::Identical,
69 oddness_comm.group().compare(my_group)
70 );
71
72 let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
73 Color::with_value(0)
74 } else {
75 Color::undefined()
76 });
77 if world.rank() % 2 != 0 {
78 assert!(odd_comm.is_some());
79 let odd_comm = odd_comm.unwrap();
80 assert_eq!(
81 GroupRelation::Identical,
82 odd_comm.group().compare(&odd_group)
83 );
84 } else {
85 assert!(odd_comm.is_none());
86 }
87}
Sourcefn split_by_color_with_key(
&self,
color: Color,
key: Key,
) -> Option<SimpleCommunicator>
fn split_by_color_with_key( &self, color: Color, key: Key, ) -> Option<SimpleCommunicator>
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(
&self,
group: &dyn Group,
) -> Option<SimpleCommunicator>
fn split_by_subgroup_collective( &self, group: &dyn Group, ) -> Option<SimpleCommunicator>
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 prefix_sum(&world, "World: ");
12
13 let g1 = world
14 .group()
15 .include(&(0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>());
16 let g2 = world
17 .group()
18 .include(&(0..world.size()).filter(|x| x % 2 == 0).collect::<Vec<_>>());
19 world
20 .split_by_subgroup_collective(&g1)
21 .map(|c| prefix_sum(&c, "Group 1: "));
22 world
23 .split_by_subgroup_collective(&g2)
24 .map(|c| prefix_sum(&c, "Group 2: "));
25}
More examples
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9
10 let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
11 let odd_group = world.group().include(&odd[..]);
12 let even_group = world.group().difference(&odd_group);
13 assert!(
14 (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
15 || (even_group.rank().is_none() && odd_group.rank().is_some())
16 );
17 let my_group = if odd_group.rank().is_some() {
18 &odd_group
19 } else {
20 &even_group
21 };
22 let empty_group = SystemGroup::empty();
23
24 let oddness_comm = world.split_by_subgroup_collective(my_group);
25 assert!(oddness_comm.is_some());
26 let oddness_comm = oddness_comm.unwrap();
27 assert_eq!(
28 GroupRelation::Identical,
29 oddness_comm.group().compare(my_group)
30 );
31
32 let odd_comm = if odd_group.rank().is_some() {
33 world.split_by_subgroup_collective(&odd_group)
34 } else {
35 world.split_by_subgroup_collective(&empty_group)
36 };
37 if odd_group.rank().is_some() {
38 assert!(odd_comm.is_some());
39 let odd_comm = odd_comm.unwrap();
40 assert_eq!(
41 GroupRelation::Identical,
42 odd_comm.group().compare(&odd_group)
43 );
44 } else {
45 assert!(odd_comm.is_none());
46 }
47
48 #[cfg(not(msmpi))]
49 {
50 if even_group.rank().is_some() {
51 let even_comm = world.split_by_subgroup(&even_group);
52 assert!(even_comm.is_some());
53 let even_comm = even_comm.unwrap();
54 assert_eq!(
55 GroupRelation::Identical,
56 even_comm.group().compare(&even_group)
57 );
58
59 let no_comm = world.split_by_subgroup(&odd_group);
60 assert!(no_comm.is_none());
61 }
62 }
63
64 let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
65 assert!(oddness_comm.is_some());
66 let oddness_comm = oddness_comm.unwrap();
67 assert_eq!(
68 GroupRelation::Identical,
69 oddness_comm.group().compare(my_group)
70 );
71
72 let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
73 Color::with_value(0)
74 } else {
75 Color::undefined()
76 });
77 if world.rank() % 2 != 0 {
78 assert!(odd_comm.is_some());
79 let odd_comm = odd_comm.unwrap();
80 assert_eq!(
81 GroupRelation::Identical,
82 odd_comm.group().compare(&odd_group)
83 );
84 } else {
85 assert!(odd_comm.is_none());
86 }
87}
Sourcefn split_by_subgroup(&self, group: &dyn Group) -> Option<SimpleCommunicator>
fn split_by_subgroup(&self, group: &dyn Group) -> Option<SimpleCommunicator>
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?
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9
10 let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
11 let odd_group = world.group().include(&odd[..]);
12 let even_group = world.group().difference(&odd_group);
13 assert!(
14 (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
15 || (even_group.rank().is_none() && odd_group.rank().is_some())
16 );
17 let my_group = if odd_group.rank().is_some() {
18 &odd_group
19 } else {
20 &even_group
21 };
22 let empty_group = SystemGroup::empty();
23
24 let oddness_comm = world.split_by_subgroup_collective(my_group);
25 assert!(oddness_comm.is_some());
26 let oddness_comm = oddness_comm.unwrap();
27 assert_eq!(
28 GroupRelation::Identical,
29 oddness_comm.group().compare(my_group)
30 );
31
32 let odd_comm = if odd_group.rank().is_some() {
33 world.split_by_subgroup_collective(&odd_group)
34 } else {
35 world.split_by_subgroup_collective(&empty_group)
36 };
37 if odd_group.rank().is_some() {
38 assert!(odd_comm.is_some());
39 let odd_comm = odd_comm.unwrap();
40 assert_eq!(
41 GroupRelation::Identical,
42 odd_comm.group().compare(&odd_group)
43 );
44 } else {
45 assert!(odd_comm.is_none());
46 }
47
48 #[cfg(not(msmpi))]
49 {
50 if even_group.rank().is_some() {
51 let even_comm = world.split_by_subgroup(&even_group);
52 assert!(even_comm.is_some());
53 let even_comm = even_comm.unwrap();
54 assert_eq!(
55 GroupRelation::Identical,
56 even_comm.group().compare(&even_group)
57 );
58
59 let no_comm = world.split_by_subgroup(&odd_group);
60 assert!(no_comm.is_none());
61 }
62 }
63
64 let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
65 assert!(oddness_comm.is_some());
66 let oddness_comm = oddness_comm.unwrap();
67 assert_eq!(
68 GroupRelation::Identical,
69 oddness_comm.group().compare(my_group)
70 );
71
72 let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
73 Color::with_value(0)
74 } else {
75 Color::undefined()
76 });
77 if world.rank() % 2 != 0 {
78 assert!(odd_comm.is_some());
79 let odd_comm = odd_comm.unwrap();
80 assert_eq!(
81 GroupRelation::Identical,
82 odd_comm.group().compare(&odd_group)
83 );
84 } else {
85 assert!(odd_comm.is_none());
86 }
87}
Sourcefn split_by_subgroup_with_tag(
&self,
group: &dyn Group,
tag: Tag,
) -> Option<SimpleCommunicator>
fn split_by_subgroup_with_tag( &self, group: &dyn Group, tag: Tag, ) -> Option<SimpleCommunicator>
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?
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10
11 prefix_sum(&world, "World: ");
12
13 let g1 = world
14 .group()
15 .include(&(0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>());
16 let g2 = world
17 .group()
18 .include(&(0..world.size()).filter(|x| x % 2 == 0).collect::<Vec<_>>());
19 world
20 .split_by_subgroup_collective(&g1)
21 .map(|c| prefix_sum(&c, "Group 1: "));
22 world
23 .split_by_subgroup_collective(&g2)
24 .map(|c| prefix_sum(&c, "Group 2: "));
25}
More examples
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10
11 let g = world.group();
12 // Group accessors and Communicator accessors agree
13 assert_eq!(world.size(), g.size());
14 assert_eq!(world.rank(), g.rank().unwrap());
15
16 // g == g
17 assert_eq!(GroupRelation::Identical, g.compare(&g));
18
19 let h = world.group();
20 // h == g
21 assert_eq!(GroupRelation::Identical, g.compare(&h));
22
23 let i = g.union(&h);
24 // g union h == g union g == g
25 assert_eq!(GroupRelation::Identical, g.compare(&i));
26
27 let empty = g.difference(&h);
28 // g difference h == g difference g = empty Group
29 assert_eq!(
30 GroupRelation::Identical,
31 SystemGroup::empty().compare(&empty)
32 );
33 assert_eq!(0, empty.size());
34
35 // g intersection empty == empty Group
36 assert_eq!(0, g.intersection(&empty).size());
37
38 let first_half: Vec<Rank> = (0..g.size() / 2).collect();
39
40 // f and s are first and second half of g
41 let f = g.include(&first_half[..]);
42 let s = g.exclude(&first_half[..]);
43 // f != s
44 assert_eq!(GroupRelation::Unequal, f.compare(&s));
45
46 // g intersection f == f
47 let f_ = g.intersection(&f);
48 assert_eq!(GroupRelation::Identical, f.compare(&f_));
49 // g intersection s == s
50 let s_ = g.intersection(&s);
51 assert_eq!(GroupRelation::Identical, s.compare(&s_));
52
53 // g difference s == f
54 let f__ = g.difference(&s);
55 assert_eq!(GroupRelation::Identical, f.compare(&f__));
56 // g difference f == s
57 let s__ = g.difference(&f);
58 assert_eq!(GroupRelation::Identical, s.compare(&s__));
59
60 // f union s == g
61 let fs = f.union(&s);
62 assert_eq!(GroupRelation::Identical, g.compare(&fs));
63
64 // f intersection s == empty Group
65 let fs = f.intersection(&s);
66 assert_eq!(GroupRelation::Identical, empty.compare(&fs));
67
68 // rank is either in f or in s
69 assert!(
70 (f.rank().is_some() && s.rank().is_none()) ^ (f.rank().is_none() && s.rank().is_some())
71 );
72
73 // inverting rank mappings
74 let rev: Vec<Rank> = (0..g.size()).rev().collect();
75 let r = g.include(&rev[..]);
76 assert_eq!(
77 Some(rev[g.rank().unwrap() as usize]),
78 r.translate_rank(g.rank().unwrap(), &g)
79 );
80}
6fn main() {
7 let universe = mpi::initialize().unwrap();
8 let world = universe.world();
9
10 let odd = (0..world.size()).filter(|x| x % 2 != 0).collect::<Vec<_>>();
11 let odd_group = world.group().include(&odd[..]);
12 let even_group = world.group().difference(&odd_group);
13 assert!(
14 (world.rank() % 2 == 0 && even_group.rank().is_some() && odd_group.rank().is_none())
15 || (even_group.rank().is_none() && odd_group.rank().is_some())
16 );
17 let my_group = if odd_group.rank().is_some() {
18 &odd_group
19 } else {
20 &even_group
21 };
22 let empty_group = SystemGroup::empty();
23
24 let oddness_comm = world.split_by_subgroup_collective(my_group);
25 assert!(oddness_comm.is_some());
26 let oddness_comm = oddness_comm.unwrap();
27 assert_eq!(
28 GroupRelation::Identical,
29 oddness_comm.group().compare(my_group)
30 );
31
32 let odd_comm = if odd_group.rank().is_some() {
33 world.split_by_subgroup_collective(&odd_group)
34 } else {
35 world.split_by_subgroup_collective(&empty_group)
36 };
37 if odd_group.rank().is_some() {
38 assert!(odd_comm.is_some());
39 let odd_comm = odd_comm.unwrap();
40 assert_eq!(
41 GroupRelation::Identical,
42 odd_comm.group().compare(&odd_group)
43 );
44 } else {
45 assert!(odd_comm.is_none());
46 }
47
48 #[cfg(not(msmpi))]
49 {
50 if even_group.rank().is_some() {
51 let even_comm = world.split_by_subgroup(&even_group);
52 assert!(even_comm.is_some());
53 let even_comm = even_comm.unwrap();
54 assert_eq!(
55 GroupRelation::Identical,
56 even_comm.group().compare(&even_group)
57 );
58
59 let no_comm = world.split_by_subgroup(&odd_group);
60 assert!(no_comm.is_none());
61 }
62 }
63
64 let oddness_comm = world.split_by_color(Color::with_value(world.rank() % 2));
65 assert!(oddness_comm.is_some());
66 let oddness_comm = oddness_comm.unwrap();
67 assert_eq!(
68 GroupRelation::Identical,
69 oddness_comm.group().compare(my_group)
70 );
71
72 let odd_comm = world.split_by_color(if world.rank() % 2 != 0 {
73 Color::with_value(0)
74 } else {
75 Color::undefined()
76 });
77 if world.rank() % 2 != 0 {
78 assert!(odd_comm.is_some());
79 let odd_comm = odd_comm.unwrap();
80 assert_eq!(
81 GroupRelation::Identical,
82 odd_comm.group().compare(&odd_group)
83 );
84 } else {
85 assert!(odd_comm.is_none());
86 }
87}
Sourcefn test_inter(&self) -> bool
fn test_inter(&self) -> bool
Tests if the communicator is an inter-communicator.
§Standard sections(s)
6.6.1, See MPI_Comm_test_inter
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?
6fn main() {
7 let universe = mpi::initialize().unwrap();
8
9 let comm = universe.world();
10
11 if comm.size() < 4 {
12 return;
13 }
14
15 let cart_comm = {
16 let dims = [2, 2];
17 let periodic = [false, true];
18 let reorder = true;
19 if let Some(cart_comm) = comm.create_cartesian_communicator(&dims, &periodic, reorder) {
20 cart_comm
21 } else {
22 assert!(comm.rank() >= 4);
23 return;
24 }
25 };
26
27 assert_eq!(2, cart_comm.num_dimensions());
28
29 let mpi::topology::CartesianLayout {
30 dims,
31 periods,
32 coords,
33 } = cart_comm.get_layout();
34
35 assert_eq!([2 as mpi::Count, 2], &dims[..]);
36 assert_eq!([false, true], &periods[..]);
37
38 let xrank = coords[0];
39 let yrank = coords[1];
40
41 assert!(0 <= xrank && xrank < 2);
42 assert!(0 <= yrank && yrank < 2);
43
44 let xcomm = cart_comm.subgroup(&[true, false]);
45 let ycomm = cart_comm.subgroup(&[false, true]);
46
47 assert_eq!(2, xcomm.size());
48 assert_eq!(xrank, xcomm.rank());
49
50 assert_eq!(2, ycomm.size());
51 assert_eq!(yrank, ycomm.rank());
52
53 // the first dimension is non-periodic
54 let (x_src, x_dest) = cart_comm.shift(0, 1);
55 if xrank == 0 {
56 assert!(x_src.is_none());
57 assert!(x_dest.is_some());
58
59 let coords = cart_comm.rank_to_coordinates(x_dest.unwrap());
60 assert_eq!(1, coords[0]);
61 } else {
62 assert_eq!(1, xrank);
63
64 assert!(x_src.is_some());
65 assert!(x_dest.is_none());
66
67 let coords = cart_comm.rank_to_coordinates(x_src.unwrap());
68 assert_eq!(0, coords[0]);
69 }
70
71 // the second dimension is periodic
72 {
73 let (y_src, y_dest) = cart_comm.shift(1, 1);
74 assert!(y_src.is_some());
75 assert!(y_dest.is_some());
76
77 let y_src_coords = cart_comm.rank_to_coordinates(y_src.unwrap());
78 assert_eq!((yrank - 1) & 0b1, y_src_coords[1]);
79
80 let y_dest_coords = cart_comm.rank_to_coordinates(y_dest.unwrap());
81 assert_eq!((yrank + 1) & 0b1, y_dest_coords[1]);
82 }
83
84 // second dimension shift by 2 should be identity
85 {
86 let (y_src, y_dest) = cart_comm.shift(1, 2);
87 assert_eq!(comm.rank(), y_src.unwrap());
88 assert_eq!(comm.rank(), y_dest.unwrap());
89 }
90}
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) -> Count
fn pack_size<Dt>(&self, incount: Count, datatype: &Dt) -> Count
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?
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8
9 let ints = [3i32, 2, 1];
10 let packed = world.pack(&ints[..]);
11
12 let mut new_ints = [0, 0, 0];
13 unsafe {
14 world.unpack_into(&packed, &mut new_ints[..], 0);
15 }
16
17 assert_eq!([3, 2, 1], new_ints);
18}
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
Examples found in repository?
5fn main() {
6 let universe = mpi::initialize().unwrap();
7 let world = universe.world();
8
9 let ints = [3i32, 2, 1];
10 let packed = world.pack(&ints[..]);
11
12 let mut new_ints = [0, 0, 0];
13 unsafe {
14 world.unpack_into(&packed, &mut new_ints[..], 0);
15 }
16
17 assert_eq!([3, 2, 1], new_ints);
18}
Sourcefn parent(&self) -> Option<InterCommunicator>
fn parent(&self) -> Option<InterCommunicator>
Examples found in repository?
7fn main() -> Result<(), mpi::MpiError> {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10
11 if let Some(parent) = world.parent() {
12 let child_name = env::args().skip(1).next().unwrap();
13 let appnum = universe.appnum().unwrap_or(-1);
14 println!(
15 "[{}/{}] {} ({}) has parent size {}, universe {:?}",
16 world.rank(),
17 world.size(),
18 child_name,
19 appnum,
20 parent.remote_size(),
21 universe.size(),
22 );
23 } else {
24 fn self_with_arg(arg: &str) -> Command {
25 let mut exe = Command::new(env::current_exe().unwrap());
26 exe.arg(arg);
27 exe
28 }
29 let child_sizes = [2, 1];
30 let commands = vec![self_with_arg("FirstChild"), self_with_arg("SecondChild")];
31
32 let child = world
33 .process_at_rank(0)
34 .spawn_multiple(&commands, &child_sizes)?;
35
36 assert_eq!(child_sizes.iter().sum::<i32>(), child.remote_size());
37
38 println!(
39 "[{}/{}] Parent universe {:?}",
40 world.rank(),
41 world.size(),
42 universe.size(),
43 );
44 }
45 Ok(())
46}
More examples
8fn main() -> Result<(), mpi::MpiError> {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11
12 let merged = if let Some(parent) = world.parent() {
13 assert_eq!("from_parent", env::args().skip(1).next().unwrap());
14
15 parent.process_at_rank(0).send(&7i32);
16
17 println!(
18 "[{}/{}] Child universe {:?}",
19 world.rank(),
20 world.size(),
21 universe.size()
22 );
23 parent.merge(MergeOrder::High)
24 } else {
25 let child_size = 1;
26 let mut exe = Command::new(env::current_exe().unwrap());
27 exe.arg("from_parent");
28
29 let child = world.process_at_rank(0).spawn(&exe, child_size)?;
30
31 assert_eq!(child_size, child.remote_size());
32
33 if world.rank() == 0 {
34 assert_eq!(7i32, child.process_at_rank(0).receive().0);
35 }
36 println!(
37 "[{}/{}] Parent universe {:?} appnum {}",
38 world.rank(),
39 world.size(),
40 universe.size(),
41 universe.appnum().unwrap_or(-1),
42 );
43 child.merge(MergeOrder::Low)
44 };
45 println!(
46 "[{}/{}] Merged is World {}/{}",
47 merged.rank(),
48 merged.size(),
49 world.rank(),
50 world.size()
51 );
52 Ok(())
53}