Trait Root

Source
pub trait Root: AsCommunicator {
Show 23 methods // Required method fn root_rank(&self) -> Rank; // Provided methods fn broadcast_into<Buf>(&self, buffer: &mut Buf) where Buf: BufferMut + ?Sized { ... } fn gather_into<S>(&self, sendbuf: &S) where S: Buffer + ?Sized { ... } fn gather_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R) where S: Buffer + ?Sized, R: BufferMut + ?Sized { ... } fn gather_varcount_into<S>(&self, sendbuf: &S) where S: Buffer + ?Sized { ... } fn gather_varcount_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R) where S: Buffer + ?Sized, R: PartitionedBufferMut + ?Sized { ... } fn scatter_into<R>(&self, recvbuf: &mut R) where R: BufferMut + ?Sized { ... } fn scatter_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R) where S: Buffer + ?Sized, R: BufferMut + ?Sized { ... } fn scatter_varcount_into<R>(&self, recvbuf: &mut R) where R: BufferMut + ?Sized { ... } fn scatter_varcount_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R) where S: PartitionedBuffer + ?Sized, R: BufferMut + ?Sized { ... } fn reduce_into<S, O>(&self, sendbuf: &S, op: O) where S: Buffer + ?Sized, O: Operation { ... } fn reduce_into_root<S, R, O>(&self, sendbuf: &S, recvbuf: &mut R, op: O) where S: Buffer + ?Sized, R: BufferMut + ?Sized, O: Operation { ... } fn immediate_broadcast_into<'a, Sc, Buf>( &self, scope: Sc, buf: &'a mut Buf, ) -> Request<'a, Sc> where Buf: 'a + BufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_gather_into<'a, Sc, S>( &self, scope: Sc, sendbuf: &'a S, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, Sc: Scope<'a> { ... } fn immediate_gather_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, R: 'a + BufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_gather_varcount_into<'a, Sc, S>( &self, scope: Sc, sendbuf: &'a S, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, Sc: Scope<'a> { ... } fn immediate_gather_varcount_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, R: 'a + PartitionedBufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_scatter_into<'a, Sc, R>( &self, scope: Sc, recvbuf: &'a mut R, ) -> Request<'a, Sc> where R: 'a + BufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_scatter_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, R: 'a + BufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_scatter_varcount_into<'a, Sc, R>( &self, scope: Sc, recvbuf: &'a mut R, ) -> Request<'a, Sc> where R: 'a + BufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_scatter_varcount_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc> where S: 'a + PartitionedBuffer + ?Sized, R: 'a + BufferMut + ?Sized, Sc: Scope<'a> { ... } fn immediate_reduce_into<'a, Sc, S, O>( &self, scope: Sc, sendbuf: &'a S, op: O, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, O: 'a + Operation, Sc: Scope<'a> { ... } fn immediate_reduce_into_root<'a, Sc, S, R, O>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, op: O, ) -> Request<'a, Sc> where S: 'a + Buffer + ?Sized, R: 'a + BufferMut + ?Sized, O: 'a + Operation, Sc: Scope<'a> { ... }
}
Expand description

Something that can take the role of ‘root’ in a collective operation.

Many collective operations define a ‘root’ process that takes a special role in the communication. These collective operations are implemented as default methods of this trait.

Required Methods§

Source

fn root_rank(&self) -> Rank

Rank of the root process

Provided Methods§

Source

fn broadcast_into<Buf>(&self, buffer: &mut Buf)
where Buf: BufferMut + ?Sized,

Broadcast of the contents of a buffer

After the call completes, the Buffer on all processes in the Communicator of the Root &self will contain what it contains on the Root.

§Examples

See examples/broadcast.rs

§Standard section(s)

5.4

Examples found in repository?
examples/structured.rs (line 31)
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/datatype_dup.rs (line 24)
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 67)
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/broadcast_complex.rs (line 23)
5fn main() {
6    let universe = mpi::initialize().unwrap();
7    let world = universe.world();
8
9    let root_process = world.process_at_rank(0);
10
11    let mut data = if world.rank() == 0 {
12        [
13            Complex::<f64>::new(1., -2.),
14            Complex::<f64>::new(8., -4.),
15            Complex::<f64>::new(3., -9.),
16            Complex::<f64>::new(7., -5.),
17        ]
18    } else {
19        [Complex::<f64>::new(0., 0.); 4]
20    };
21
22    // root_process.broadcast_into(&mut data);
23    root_process.broadcast_into(&mut data[..]);
24
25    assert_eq!(
26        data,
27        [
28            Complex::<f64>::new(1., -2.),
29            Complex::<f64>::new(8., -4.),
30            Complex::<f64>::new(3., -9.),
31            Complex::<f64>::new(7., -5.),
32        ]
33    );
34}
examples/broadcast.rs (line 19)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let root_rank = 0;
10    let root_process = world.process_at_rank(root_rank);
11
12    let mut x;
13    if world.rank() == root_rank {
14        x = 2_u64.pow(10);
15        println!("Root broadcasting value: {}.", x);
16    } else {
17        x = 0_u64;
18    }
19    root_process.broadcast_into(&mut x);
20    println!("Rank {} received value: {}.", world.rank(), x);
21    assert_eq!(x, 1024);
22    println!();
23
24    let mut a;
25    let n = 4;
26    if world.rank() == root_rank {
27        a = (1..).map(|i| 2_u64.pow(i)).take(n).collect::<Vec<_>>();
28        println!("Root broadcasting value: {:?}.", &a[..]);
29    } else {
30        a = std::iter::repeat(0_u64).take(n).collect::<Vec<_>>();
31    }
32    root_process.broadcast_into(&mut a[..]);
33    println!("Rank {} received value: {:?}.", world.rank(), &a[..]);
34    assert_eq!(&a[..], &[2, 4, 8, 16]);
35}
examples/readme.rs (line 44)
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}
Source

fn gather_into<S>(&self, sendbuf: &S)
where S: Buffer + ?Sized,

Gather contents of buffers on Root.

After the call completes, the contents of the Buffers on all ranks will be concatenated into the Buffer on Root.

All send Buffers must have the same count of elements.

This function must be called on all non-root processes.

§Examples

See examples/gather.rs

§Standard section(s)

5.5

Examples found in repository?
examples/gather.rs (line 26)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    let root_rank = 0;
12    let root_process = world.process_at_rank(root_rank);
13
14    let count = world.size() as usize;
15    let i = 2_u64.pow(world.rank() as u32 + 1);
16
17    if world.rank() == root_rank {
18        let mut a = vec![0u64; count];
19        root_process.gather_into_root(&i, &mut a[..]);
20        println!("Root gathered sequence: {:?}.", a);
21        assert!(a
22            .iter()
23            .enumerate()
24            .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
25    } else {
26        root_process.gather_into(&i);
27    }
28
29    let factor = world.rank() as u64 + 1;
30    let a = (1_u64..)
31        .take(count)
32        .map(|x| x * factor)
33        .collect::<Vec<_>>();
34
35    if world.rank() == root_rank {
36        let mut t = vec![0u64; count * count];
37        root_process.gather_into_root(&a[..], &mut t[..]);
38        println!("Root gathered table:");
39        for r in t.chunks(count) {
40            println!("{:?}", r);
41        }
42        assert!((0_u64..)
43            .zip(t.iter())
44            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
45    } else {
46        root_process.gather_into(&a[..]);
47    }
48
49    let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
50    let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
51
52    if world.rank() == root_rank {
53        let mut t = vec![0u64; count * count];
54
55        {
56            let mut rv =
57                unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
58            root_process.gather_into_root(&sv, &mut rv);
59        }
60
61        println!("Root gathered table:");
62        for r in t.chunks(count) {
63            println!("{:?}", r);
64        }
65        assert!((0_u64..)
66            .zip(t.iter())
67            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
68    } else {
69        root_process.gather_into(&sv);
70    }
71}
Source

fn gather_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R)
where S: Buffer + ?Sized, R: BufferMut + ?Sized,

Gather contents of buffers on Root.

After the call completes, the contents of the Buffers on all ranks will be concatenated into the Buffer on Root.

All send Buffers must have the same count of elements.

This function must be called on the root process.

§Examples

See examples/gather.rs

§Standard section(s)

5.5

Examples found in repository?
examples/gather.rs (line 19)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    let root_rank = 0;
12    let root_process = world.process_at_rank(root_rank);
13
14    let count = world.size() as usize;
15    let i = 2_u64.pow(world.rank() as u32 + 1);
16
17    if world.rank() == root_rank {
18        let mut a = vec![0u64; count];
19        root_process.gather_into_root(&i, &mut a[..]);
20        println!("Root gathered sequence: {:?}.", a);
21        assert!(a
22            .iter()
23            .enumerate()
24            .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
25    } else {
26        root_process.gather_into(&i);
27    }
28
29    let factor = world.rank() as u64 + 1;
30    let a = (1_u64..)
31        .take(count)
32        .map(|x| x * factor)
33        .collect::<Vec<_>>();
34
35    if world.rank() == root_rank {
36        let mut t = vec![0u64; count * count];
37        root_process.gather_into_root(&a[..], &mut t[..]);
38        println!("Root gathered table:");
39        for r in t.chunks(count) {
40            println!("{:?}", r);
41        }
42        assert!((0_u64..)
43            .zip(t.iter())
44            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
45    } else {
46        root_process.gather_into(&a[..]);
47    }
48
49    let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
50    let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
51
52    if world.rank() == root_rank {
53        let mut t = vec![0u64; count * count];
54
55        {
56            let mut rv =
57                unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
58            root_process.gather_into_root(&sv, &mut rv);
59        }
60
61        println!("Root gathered table:");
62        for r in t.chunks(count) {
63            println!("{:?}", r);
64        }
65        assert!((0_u64..)
66            .zip(t.iter())
67            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
68    } else {
69        root_process.gather_into(&sv);
70    }
71}
Source

fn gather_varcount_into<S>(&self, sendbuf: &S)
where S: Buffer + ?Sized,

Gather contents of buffers on Root.

After the call completes, the contents of the Buffers on all ranks will be concatenated into the Buffer on Root.

The send Buffers may contain different counts of elements on different processes. The distribution of elements in the receive Buffer is specified via Partitioned.

This function must be called on all non-root processes.

§Examples

See examples/gather_varcount.rs

§Standard section(s)

5.5

Examples found in repository?
examples/gather_varcount.rs (line 43)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let msg: Vec<_> = (0..rank).collect();
19
20    if rank == root_rank {
21        let counts: Vec<Count> = (0..size).collect();
22        let displs: Vec<Count> = counts
23            .iter()
24            .scan(0, |acc, &x| {
25                let tmp = *acc;
26                *acc += x;
27                Some(tmp)
28            })
29            .collect();
30
31        let mut buf = vec![0; (size * (size - 1) / 2) as usize];
32        {
33            let mut partition = PartitionMut::new(&mut buf[..], counts, &displs[..]);
34            root_process.gather_varcount_into_root(&msg[..], &mut partition);
35        }
36
37        assert!(buf
38            .iter()
39            .zip((0..size).flat_map(|r| (0..r)))
40            .all(|(&i, j)| i == j));
41        println!("{:?}", buf);
42    } else {
43        root_process.gather_varcount_into(&msg[..]);
44    }
45}
Source

fn gather_varcount_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R)

Gather contents of buffers on Root.

After the call completes, the contents of the Buffers on all ranks will be concatenated into the Buffer on Root.

The send Buffers may contain different counts of elements on different processes. The distribution of elements in the receive Buffer is specified via Partitioned.

This function must be called on the root process.

§Examples

See examples/gather_varcount.rs

§Standard section(s)

5.5

Examples found in repository?
examples/gather_varcount.rs (line 34)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let msg: Vec<_> = (0..rank).collect();
19
20    if rank == root_rank {
21        let counts: Vec<Count> = (0..size).collect();
22        let displs: Vec<Count> = counts
23            .iter()
24            .scan(0, |acc, &x| {
25                let tmp = *acc;
26                *acc += x;
27                Some(tmp)
28            })
29            .collect();
30
31        let mut buf = vec![0; (size * (size - 1) / 2) as usize];
32        {
33            let mut partition = PartitionMut::new(&mut buf[..], counts, &displs[..]);
34            root_process.gather_varcount_into_root(&msg[..], &mut partition);
35        }
36
37        assert!(buf
38            .iter()
39            .zip((0..size).flat_map(|r| (0..r)))
40            .all(|(&i, j)| i == j));
41        println!("{:?}", buf);
42    } else {
43        root_process.gather_varcount_into(&msg[..]);
44    }
45}
Source

fn scatter_into<R>(&self, recvbuf: &mut R)
where R: BufferMut + ?Sized,

Scatter contents of a buffer on the root process to all processes.

After the call completes each participating process will have received a part of the send Buffer on the root process.

All send Buffers must have the same count of elements.

This function must be called on all non-root processes.

§Examples

See examples/scatter.rs

§Standard section(s)

5.6

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

fn scatter_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R)
where S: Buffer + ?Sized, R: BufferMut + ?Sized,

Scatter contents of a buffer on the root process to all processes.

After the call completes each participating process will have received a part of the send Buffer on the root process.

All send Buffers must have the same count of elements.

This function must be called on the root process.

§Examples

See examples/scatter.rs

§Standard section(s)

5.6

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

fn scatter_varcount_into<R>(&self, recvbuf: &mut R)
where R: BufferMut + ?Sized,

Scatter contents of a buffer on the root process to all processes.

After the call completes each participating process will have received a part of the send Buffer on the root process.

The send Buffer may contain different counts of elements for different processes. The distribution of elements in the send Buffer is specified via Partitioned.

This function must be called on all non-root processes.

§Examples

See examples/scatter_varcount.rs

§Standard section(s)

5.6

Examples found in repository?
examples/scatter_varcount.rs (line 34)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let mut buf = vec![0; rank as usize];
19
20    if rank == root_rank {
21        let msg: Vec<_> = (0..size).flat_map(|i| (0..i)).collect();
22        let counts: Vec<Count> = (0..size).collect();
23        let displs: Vec<Count> = counts
24            .iter()
25            .scan(0, |acc, &x| {
26                let tmp = *acc;
27                *acc += x;
28                Some(tmp)
29            })
30            .collect();
31        let partition = Partition::new(&msg[..], counts, &displs[..]);
32        root_process.scatter_varcount_into_root(&partition, &mut buf[..]);
33    } else {
34        root_process.scatter_varcount_into(&mut buf[..]);
35    }
36
37    assert!(buf.iter().zip(0..rank).all(|(&i, j)| i == j));
38    println!("Process {} got message: {:?}", rank, buf);
39}
Source

fn scatter_varcount_into_root<S, R>(&self, sendbuf: &S, recvbuf: &mut R)

Scatter contents of a buffer on the root process to all processes.

After the call completes each participating process will have received a part of the send Buffer on the root process.

The send Buffer may contain different counts of elements for different processes. The distribution of elements in the send Buffer is specified via Partitioned.

This function must be called on the root process.

§Examples

See examples/scatter_varcount.rs

§Standard section(s)

5.6

Examples found in repository?
examples/scatter_varcount.rs (line 32)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let mut buf = vec![0; rank as usize];
19
20    if rank == root_rank {
21        let msg: Vec<_> = (0..size).flat_map(|i| (0..i)).collect();
22        let counts: Vec<Count> = (0..size).collect();
23        let displs: Vec<Count> = counts
24            .iter()
25            .scan(0, |acc, &x| {
26                let tmp = *acc;
27                *acc += x;
28                Some(tmp)
29            })
30            .collect();
31        let partition = Partition::new(&msg[..], counts, &displs[..]);
32        root_process.scatter_varcount_into_root(&partition, &mut buf[..]);
33    } else {
34        root_process.scatter_varcount_into(&mut buf[..]);
35    }
36
37    assert!(buf.iter().zip(0..rank).all(|(&i, j)| i == j));
38    println!("Process {} got message: {:?}", rank, buf);
39}
Source

fn reduce_into<S, O>(&self, sendbuf: &S, op: O)
where S: Buffer + ?Sized, O: Operation,

Performs a global reduction under the operation op of the input data in sendbuf and stores the result on the Root process.

This function must be called on all non-root processes.

§Examples

See examples/reduce.rs

§Standard section(s)

5.9.1

Examples found in repository?
examples/reduce.rs (line 85)
69fn main() {
70    let universe = mpi::initialize().unwrap();
71    let world = universe.world();
72    let rank = world.rank();
73    let size = world.size();
74    let root_rank = 0;
75
76    if rank == root_rank {
77        let mut sum: Rank = 0;
78        world
79            .process_at_rank(root_rank)
80            .reduce_into_root(&rank, &mut sum, SystemOperation::sum());
81        assert_eq!(sum, size * (size - 1) / 2);
82    } else {
83        world
84            .process_at_rank(root_rank)
85            .reduce_into(&rank, SystemOperation::sum());
86    }
87
88    let mut max: Rank = -1;
89
90    world.all_reduce_into(&rank, &mut max, SystemOperation::max());
91    assert_eq!(max, size - 1);
92
93    let a: u16 = 0b0000_1111_1111_0000;
94    let b: u16 = 0b0011_1100_0011_1100;
95
96    let mut c = b;
97    collective::reduce_local_into(&a, &mut c, SystemOperation::bitwise_and());
98    assert_eq!(c, 0b0000_1100_0011_0000);
99
100    let mut d = b;
101    collective::reduce_local_into(&a, &mut d, SystemOperation::bitwise_or());
102    assert_eq!(d, 0b0011_1111_1111_1100);
103
104    let mut e = b;
105    collective::reduce_local_into(&a, &mut e, SystemOperation::bitwise_xor());
106    assert_eq!(e, 0b0011_0011_1100_1100);
107
108    let f = (0..size).collect::<Vec<_>>();
109    let mut g: Rank = 0;
110
111    world.reduce_scatter_block_into(&f[..], &mut g, SystemOperation::product());
112    assert_eq!(g, rank.wrapping_pow(size as u32));
113
114    test_user_operations(universe.world());
115
116    let mut i = 0;
117    let op = unsafe { UnsafeUserOperation::commutative(unsafe_add) };
118    world.all_reduce_into(&(rank + 1), &mut i, &op);
119    assert_eq!(i, size * (size + 1) / 2);
120}
Source

fn reduce_into_root<S, R, O>(&self, sendbuf: &S, recvbuf: &mut R, op: O)
where S: Buffer + ?Sized, R: BufferMut + ?Sized, O: Operation,

Performs a global reduction under the operation op of the input data in sendbuf and stores the result on the Root process.

This function must be called on the root process.

§Examples

See examples/reduce.rs

§Standard section(s)

5.9.1

Examples found in repository?
examples/reduce.rs (line 80)
69fn main() {
70    let universe = mpi::initialize().unwrap();
71    let world = universe.world();
72    let rank = world.rank();
73    let size = world.size();
74    let root_rank = 0;
75
76    if rank == root_rank {
77        let mut sum: Rank = 0;
78        world
79            .process_at_rank(root_rank)
80            .reduce_into_root(&rank, &mut sum, SystemOperation::sum());
81        assert_eq!(sum, size * (size - 1) / 2);
82    } else {
83        world
84            .process_at_rank(root_rank)
85            .reduce_into(&rank, SystemOperation::sum());
86    }
87
88    let mut max: Rank = -1;
89
90    world.all_reduce_into(&rank, &mut max, SystemOperation::max());
91    assert_eq!(max, size - 1);
92
93    let a: u16 = 0b0000_1111_1111_0000;
94    let b: u16 = 0b0011_1100_0011_1100;
95
96    let mut c = b;
97    collective::reduce_local_into(&a, &mut c, SystemOperation::bitwise_and());
98    assert_eq!(c, 0b0000_1100_0011_0000);
99
100    let mut d = b;
101    collective::reduce_local_into(&a, &mut d, SystemOperation::bitwise_or());
102    assert_eq!(d, 0b0011_1111_1111_1100);
103
104    let mut e = b;
105    collective::reduce_local_into(&a, &mut e, SystemOperation::bitwise_xor());
106    assert_eq!(e, 0b0011_0011_1100_1100);
107
108    let f = (0..size).collect::<Vec<_>>();
109    let mut g: Rank = 0;
110
111    world.reduce_scatter_block_into(&f[..], &mut g, SystemOperation::product());
112    assert_eq!(g, rank.wrapping_pow(size as u32));
113
114    test_user_operations(universe.world());
115
116    let mut i = 0;
117    let op = unsafe { UnsafeUserOperation::commutative(unsafe_add) };
118    world.all_reduce_into(&(rank + 1), &mut i, &op);
119    assert_eq!(i, size * (size + 1) / 2);
120}
Source

fn immediate_broadcast_into<'a, Sc, Buf>( &self, scope: Sc, buf: &'a mut Buf, ) -> Request<'a, Sc>
where Buf: 'a + BufferMut + ?Sized, Sc: Scope<'a>,

Initiate broadcast of a value from the Root process to all other processes.

§Examples

See examples/immediate_broadcast.rs

§Standard section(s)

5.12.2

Examples found in repository?
examples/immediate_broadcast.rs (line 20)
6fn main() {
7    let universe = mpi::initialize().unwrap();
8    let world = universe.world();
9    let root_rank = 0;
10    let root_process = world.process_at_rank(root_rank);
11
12    let mut x;
13    if world.rank() == root_rank {
14        x = 2_u64.pow(10);
15        println!("Root broadcasting value: {}.", x);
16    } else {
17        x = 0_u64;
18    }
19    mpi::request::scope(|scope| {
20        root_process.immediate_broadcast_into(scope, &mut x).wait();
21    });
22    println!("Rank {} received value: {}.", world.rank(), x);
23    assert_eq!(x, 1024);
24    println!();
25
26    let mut a;
27    let n = 4;
28    if world.rank() == root_rank {
29        a = (1..).map(|i| 2_u64.pow(i)).take(n).collect::<Vec<_>>();
30        println!("Root broadcasting value: {:?}.", &a[..]);
31    } else {
32        a = std::iter::repeat(0_u64).take(n).collect::<Vec<_>>();
33    }
34    mpi::request::scope(|scope| {
35        root_process
36            .immediate_broadcast_into(scope, &mut a[..])
37            .wait();
38    });
39    println!("Rank {} received value: {:?}.", world.rank(), &a[..]);
40    assert_eq!(&a[..], &[2, 4, 8, 16]);
41}
Source

fn immediate_gather_into<'a, Sc, S>( &self, scope: Sc, sendbuf: &'a S, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, Sc: Scope<'a>,

Initiate non-blocking gather of the contents of all sendbufs on Root &self.

This function must be called on all non-root processes.

§Examples

See examples/immediate_gather.rs

§Standard section(s)

5.12.3

Examples found in repository?
examples/immediate_gather.rs (line 31)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    let root_rank = 0;
12    let root_process = world.process_at_rank(root_rank);
13
14    let count = world.size() as usize;
15    let i = 2_u64.pow(world.rank() as u32 + 1);
16
17    if world.rank() == root_rank {
18        let mut a = vec![0u64; count];
19        mpi::request::scope(|scope| {
20            root_process
21                .immediate_gather_into_root(scope, &i, &mut a[..])
22                .wait();
23        });
24        println!("Root gathered sequence: {:?}.", a);
25        assert!(a
26            .iter()
27            .enumerate()
28            .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
29    } else {
30        mpi::request::scope(|scope| {
31            root_process.immediate_gather_into(scope, &i).wait();
32        });
33    }
34
35    let factor = world.rank() as u64 + 1;
36    let a = (1_u64..)
37        .take(count)
38        .map(|x| x * factor)
39        .collect::<Vec<_>>();
40
41    if world.rank() == root_rank {
42        let mut t = vec![0u64; count * count];
43        mpi::request::scope(|scope| {
44            root_process
45                .immediate_gather_into_root(scope, &a[..], &mut t[..])
46                .wait();
47        });
48        println!("Root gathered table:");
49        for r in t.chunks(count) {
50            println!("{:?}", r);
51        }
52        assert!((0_u64..)
53            .zip(t.iter())
54            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
55    } else {
56        mpi::request::scope(|scope| {
57            root_process.immediate_gather_into(scope, &a[..]).wait();
58        });
59    }
60
61    let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
62    let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
63
64    if world.rank() == root_rank {
65        let mut t = vec![0u64; count * count];
66
67        {
68            let mut rv =
69                unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
70            mpi::request::scope(|scope| {
71                root_process
72                    .immediate_gather_into_root(scope, &sv, &mut rv)
73                    .wait();
74            });
75        }
76
77        println!("Root gathered table:");
78        for r in t.chunks(count) {
79            println!("{:?}", r);
80        }
81        assert!((0_u64..)
82            .zip(t.iter())
83            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
84    } else {
85        mpi::request::scope(|scope| {
86            root_process.immediate_gather_into(scope, &sv).wait();
87        });
88    }
89}
Source

fn immediate_gather_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, R: 'a + BufferMut + ?Sized, Sc: Scope<'a>,

Initiate non-blocking gather of the contents of all sendbufs on Root &self.

This function must be called on the root processes.

§Examples

See examples/immediate_gather.rs

§Standard section(s)

5.12.3

Examples found in repository?
examples/immediate_gather.rs (line 21)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11    let root_rank = 0;
12    let root_process = world.process_at_rank(root_rank);
13
14    let count = world.size() as usize;
15    let i = 2_u64.pow(world.rank() as u32 + 1);
16
17    if world.rank() == root_rank {
18        let mut a = vec![0u64; count];
19        mpi::request::scope(|scope| {
20            root_process
21                .immediate_gather_into_root(scope, &i, &mut a[..])
22                .wait();
23        });
24        println!("Root gathered sequence: {:?}.", a);
25        assert!(a
26            .iter()
27            .enumerate()
28            .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
29    } else {
30        mpi::request::scope(|scope| {
31            root_process.immediate_gather_into(scope, &i).wait();
32        });
33    }
34
35    let factor = world.rank() as u64 + 1;
36    let a = (1_u64..)
37        .take(count)
38        .map(|x| x * factor)
39        .collect::<Vec<_>>();
40
41    if world.rank() == root_rank {
42        let mut t = vec![0u64; count * count];
43        mpi::request::scope(|scope| {
44            root_process
45                .immediate_gather_into_root(scope, &a[..], &mut t[..])
46                .wait();
47        });
48        println!("Root gathered table:");
49        for r in t.chunks(count) {
50            println!("{:?}", r);
51        }
52        assert!((0_u64..)
53            .zip(t.iter())
54            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
55    } else {
56        mpi::request::scope(|scope| {
57            root_process.immediate_gather_into(scope, &a[..]).wait();
58        });
59    }
60
61    let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
62    let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
63
64    if world.rank() == root_rank {
65        let mut t = vec![0u64; count * count];
66
67        {
68            let mut rv =
69                unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
70            mpi::request::scope(|scope| {
71                root_process
72                    .immediate_gather_into_root(scope, &sv, &mut rv)
73                    .wait();
74            });
75        }
76
77        println!("Root gathered table:");
78        for r in t.chunks(count) {
79            println!("{:?}", r);
80        }
81        assert!((0_u64..)
82            .zip(t.iter())
83            .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
84    } else {
85        mpi::request::scope(|scope| {
86            root_process.immediate_gather_into(scope, &sv).wait();
87        });
88    }
89}
Source

fn immediate_gather_varcount_into<'a, Sc, S>( &self, scope: Sc, sendbuf: &'a S, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, Sc: Scope<'a>,

Initiate non-blocking gather of the contents of all sendbufs on Root &self.

This function must be called on all non-root processes.

§Examples

See examples/immediate_gather_varcount.rs

§Standard section(s)

5.12.3

Examples found in repository?
examples/immediate_gather_varcount.rs (line 49)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let msg: Vec<_> = (0..rank).collect();
19
20    if rank == root_rank {
21        let counts: Vec<Count> = (0..size).collect();
22        let displs: Vec<Count> = counts
23            .iter()
24            .scan(0, |acc, &x| {
25                let tmp = *acc;
26                *acc += x;
27                Some(tmp)
28            })
29            .collect();
30
31        let mut buf = vec![0; (size * (size - 1) / 2) as usize];
32        {
33            let mut partition = PartitionMut::new(&mut buf[..], counts, &displs[..]);
34            mpi::request::scope(|scope| {
35                root_process
36                    .immediate_gather_varcount_into_root(scope, &msg[..], &mut partition)
37                    .wait();
38            })
39        }
40
41        assert!(buf
42            .iter()
43            .zip((0..size).flat_map(|r| (0..r)))
44            .all(|(&i, j)| i == j));
45        println!("{:?}", buf);
46    } else {
47        mpi::request::scope(|scope| {
48            root_process
49                .immediate_gather_varcount_into(scope, &msg[..])
50                .wait();
51        });
52    }
53}
Source

fn immediate_gather_varcount_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, R: 'a + PartitionedBufferMut + ?Sized, Sc: Scope<'a>,

Initiate non-blocking gather of the contents of all sendbufs on Root &self.

This function must be called on the root processes.

§Examples

See examples/immediate_gather_varcount.rs

§Standard section(s)

5.12.3

Examples found in repository?
examples/immediate_gather_varcount.rs (line 36)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let msg: Vec<_> = (0..rank).collect();
19
20    if rank == root_rank {
21        let counts: Vec<Count> = (0..size).collect();
22        let displs: Vec<Count> = counts
23            .iter()
24            .scan(0, |acc, &x| {
25                let tmp = *acc;
26                *acc += x;
27                Some(tmp)
28            })
29            .collect();
30
31        let mut buf = vec![0; (size * (size - 1) / 2) as usize];
32        {
33            let mut partition = PartitionMut::new(&mut buf[..], counts, &displs[..]);
34            mpi::request::scope(|scope| {
35                root_process
36                    .immediate_gather_varcount_into_root(scope, &msg[..], &mut partition)
37                    .wait();
38            })
39        }
40
41        assert!(buf
42            .iter()
43            .zip((0..size).flat_map(|r| (0..r)))
44            .all(|(&i, j)| i == j));
45        println!("{:?}", buf);
46    } else {
47        mpi::request::scope(|scope| {
48            root_process
49                .immediate_gather_varcount_into(scope, &msg[..])
50                .wait();
51        });
52    }
53}
Source

fn immediate_scatter_into<'a, Sc, R>( &self, scope: Sc, recvbuf: &'a mut R, ) -> Request<'a, Sc>
where R: 'a + BufferMut + ?Sized, Sc: Scope<'a>,

Initiate non-blocking scatter of the contents of sendbuf from Root &self.

This function must be called on all non-root processes.

§Examples

See examples/immediate_scatter.rs

§Standard section(s)

5.12.4

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

fn immediate_scatter_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, R: 'a + BufferMut + ?Sized, Sc: Scope<'a>,

Initiate non-blocking scatter of the contents of sendbuf from Root &self.

This function must be called on the root processes.

§Examples

See examples/immediate_scatter.rs

§Standard section(s)

5.12.4

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

fn immediate_scatter_varcount_into<'a, Sc, R>( &self, scope: Sc, recvbuf: &'a mut R, ) -> Request<'a, Sc>
where R: 'a + BufferMut + ?Sized, Sc: Scope<'a>,

Initiate non-blocking scatter of the contents of sendbuf from Root &self.

This function must be called on all non-root processes.

§Examples

See examples/immediate_scatter_varcount.rs

§Standard section(s)

5.12.4

Examples found in repository?
examples/immediate_scatter_varcount.rs (line 40)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let mut buf = vec![0; rank as usize];
19
20    if rank == root_rank {
21        let msg: Vec<_> = (0..size).flat_map(|i| (0..i)).collect();
22        let counts: Vec<Count> = (0..size).collect();
23        let displs: Vec<Count> = counts
24            .iter()
25            .scan(0, |acc, &x| {
26                let tmp = *acc;
27                *acc += x;
28                Some(tmp)
29            })
30            .collect();
31        let partition = Partition::new(&msg[..], counts, &displs[..]);
32        mpi::request::scope(|scope| {
33            root_process
34                .immediate_scatter_varcount_into_root(scope, &partition, &mut buf[..])
35                .wait();
36        });
37    } else {
38        mpi::request::scope(|scope| {
39            root_process
40                .immediate_scatter_varcount_into(scope, &mut buf[..])
41                .wait();
42        });
43    }
44
45    assert!(buf.iter().zip(0..rank).all(|(&i, j)| i == j));
46    println!("Process {} got message: {:?}", rank, buf);
47}
Source

fn immediate_scatter_varcount_into_root<'a, Sc, S, R>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, ) -> Request<'a, Sc>
where S: 'a + PartitionedBuffer + ?Sized, R: 'a + BufferMut + ?Sized, Sc: Scope<'a>,

Initiate non-blocking scatter of the contents of sendbuf from Root &self.

This function must be called on the root processes.

§Examples

See examples/immediate_scatter_varcount.rs

§Standard section(s)

5.12.4

Examples found in repository?
examples/immediate_scatter_varcount.rs (line 34)
8fn main() {
9    let universe = mpi::initialize().unwrap();
10    let world = universe.world();
11
12    let rank = world.rank();
13    let size = world.size();
14
15    let root_rank = 0;
16    let root_process = world.process_at_rank(root_rank);
17
18    let mut buf = vec![0; rank as usize];
19
20    if rank == root_rank {
21        let msg: Vec<_> = (0..size).flat_map(|i| (0..i)).collect();
22        let counts: Vec<Count> = (0..size).collect();
23        let displs: Vec<Count> = counts
24            .iter()
25            .scan(0, |acc, &x| {
26                let tmp = *acc;
27                *acc += x;
28                Some(tmp)
29            })
30            .collect();
31        let partition = Partition::new(&msg[..], counts, &displs[..]);
32        mpi::request::scope(|scope| {
33            root_process
34                .immediate_scatter_varcount_into_root(scope, &partition, &mut buf[..])
35                .wait();
36        });
37    } else {
38        mpi::request::scope(|scope| {
39            root_process
40                .immediate_scatter_varcount_into(scope, &mut buf[..])
41                .wait();
42        });
43    }
44
45    assert!(buf.iter().zip(0..rank).all(|(&i, j)| i == j));
46    println!("Process {} got message: {:?}", rank, buf);
47}
Source

fn immediate_reduce_into<'a, Sc, S, O>( &self, scope: Sc, sendbuf: &'a S, op: O, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, O: 'a + Operation, Sc: Scope<'a>,

Initiates a non-blacking global reduction under the operation op of the input data in sendbuf and stores the result on the Root process.

This function must be called on all non-root processes.

§Examples

See examples/immediate_reduce.rs

§Standard section(s)

5.12.7

Examples found in repository?
examples/immediate_reduce.rs (line 88)
68fn main() {
69    let universe = mpi::initialize().unwrap();
70    let world = universe.world();
71    let rank = world.rank();
72    let size = world.size();
73    let root_rank = 0;
74
75    if rank == root_rank {
76        let mut sum: Rank = 0;
77        mpi::request::scope(|scope| {
78            world
79                .process_at_rank(root_rank)
80                .immediate_reduce_into_root(scope, &rank, &mut sum, SystemOperation::sum())
81                .wait();
82        });
83        assert_eq!(sum, size * (size - 1) / 2);
84    } else {
85        mpi::request::scope(|scope| {
86            world
87                .process_at_rank(root_rank)
88                .immediate_reduce_into(scope, &rank, SystemOperation::sum())
89                .wait();
90        });
91    }
92
93    let mut max: Rank = -1;
94
95    mpi::request::scope(|scope| {
96        world
97            .immediate_all_reduce_into(scope, &rank, &mut max, SystemOperation::max())
98            .wait();
99    });
100    assert_eq!(max, size - 1);
101
102    let a = (0..size).collect::<Vec<_>>();
103    let mut b: Rank = 0;
104
105    mpi::request::scope(|scope| {
106        world
107            .immediate_reduce_scatter_block_into(scope, &a[..], &mut b, SystemOperation::product())
108            .wait();
109    });
110    assert_eq!(b, rank.wrapping_pow(size as u32));
111
112    test_user_operations(universe.world());
113
114    let mut d = 0;
115    let op = unsafe { UnsafeUserOperation::commutative(unsafe_add) };
116    mpi::request::scope(|scope| {
117        world
118            .immediate_all_reduce_into(scope, &rank, &mut d, &op)
119            .wait();
120    });
121    assert_eq!(d, size * (size - 1) / 2);
122}
Source

fn immediate_reduce_into_root<'a, Sc, S, R, O>( &self, scope: Sc, sendbuf: &'a S, recvbuf: &'a mut R, op: O, ) -> Request<'a, Sc>
where S: 'a + Buffer + ?Sized, R: 'a + BufferMut + ?Sized, O: 'a + Operation, Sc: Scope<'a>,

Initiates a non-blocking global reduction under the operation op of the input data in sendbuf and stores the result on the Root process.

§Examples

See examples/immediate_reduce.rs

This function must be called on the root process.

§Standard section(s)

5.12.7

Examples found in repository?
examples/immediate_reduce.rs (line 80)
68fn main() {
69    let universe = mpi::initialize().unwrap();
70    let world = universe.world();
71    let rank = world.rank();
72    let size = world.size();
73    let root_rank = 0;
74
75    if rank == root_rank {
76        let mut sum: Rank = 0;
77        mpi::request::scope(|scope| {
78            world
79                .process_at_rank(root_rank)
80                .immediate_reduce_into_root(scope, &rank, &mut sum, SystemOperation::sum())
81                .wait();
82        });
83        assert_eq!(sum, size * (size - 1) / 2);
84    } else {
85        mpi::request::scope(|scope| {
86            world
87                .process_at_rank(root_rank)
88                .immediate_reduce_into(scope, &rank, SystemOperation::sum())
89                .wait();
90        });
91    }
92
93    let mut max: Rank = -1;
94
95    mpi::request::scope(|scope| {
96        world
97            .immediate_all_reduce_into(scope, &rank, &mut max, SystemOperation::max())
98            .wait();
99    });
100    assert_eq!(max, size - 1);
101
102    let a = (0..size).collect::<Vec<_>>();
103    let mut b: Rank = 0;
104
105    mpi::request::scope(|scope| {
106        world
107            .immediate_reduce_scatter_block_into(scope, &a[..], &mut b, SystemOperation::product())
108            .wait();
109    });
110    assert_eq!(b, rank.wrapping_pow(size as u32));
111
112    test_user_operations(universe.world());
113
114    let mut d = 0;
115    let op = unsafe { UnsafeUserOperation::commutative(unsafe_add) };
116    mpi::request::scope(|scope| {
117        world
118            .immediate_all_reduce_into(scope, &rank, &mut d, &op)
119            .wait();
120    });
121    assert_eq!(d, size * (size - 1) / 2);
122}

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§

Source§

impl<'a, C: 'a + Communicator> Root for Process<'a, C>