pub struct UserDatatype(/* private fields */);
Expand description
Implementations§
Source§impl UserDatatype
impl UserDatatype
Sourcepub fn contiguous<D>(count: Count, oldtype: &D) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn contiguous<D>(count: Count, oldtype: &D) -> UserDatatypewhere
D: UncommittedDatatype,
Constructs a new datatype by concatenating count
repetitions of oldtype
§Examples
See examples/contiguous.rs
§Standard section(s)
4.1.2
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 let next_rank = (rank + 1) % size;
15 let next_process = world.process_at_rank(next_rank);
16 let previous_rank = (rank - 1 + size) % size;
17 let previous_process = world.process_at_rank(previous_rank);
18
19 let b1 = (1..).map(|x| rank * x).take(3).collect::<Vec<_>>();
20 let mut b2 = std::iter::repeat(-1).take(3).collect::<Vec<_>>();
21 println!("Rank {} sending message: {:?}.", rank, b1);
22 world.barrier();
23
24 let t = UserDatatype::contiguous(3, &Rank::equivalent_datatype());
25 let status;
26 {
27 let v1 = unsafe { View::with_count_and_datatype(&b1[..], 1, &t) };
28 let mut v2 = unsafe { MutView::with_count_and_datatype(&mut b2[..], 1, &t) };
29 status = p2p::send_receive_into(&v1, &next_process, &mut v2, &previous_process);
30 }
31
32 println!(
33 "Rank {} received message: {:?}, status: {:?}.",
34 rank, b2, status
35 );
36 world.barrier();
37
38 let b3 = (1..).map(|x| previous_rank * x).take(3).collect::<Vec<_>>();
39 assert_eq!(b3, b2);
40}
More examples
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10 let root_rank = 0;
11
12 let count = world.size() as usize;
13 let i = 2_u64.pow(world.rank() as u32 + 1);
14 let mut a = vec![0u64; count];
15
16 world.all_gather_into(&i, &mut a[..]);
17
18 if world.rank() == root_rank {
19 println!("Root gathered sequence: {:?}.", a);
20 }
21 assert!(a
22 .iter()
23 .enumerate()
24 .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
25
26 let factor = world.rank() as u64 + 1;
27 let a = (1_u64..)
28 .take(count)
29 .map(|x| x * factor)
30 .collect::<Vec<_>>();
31 let mut t = vec![0u64; count * count];
32
33 world.all_gather_into(&a[..], &mut t[..]);
34
35 if world.rank() == root_rank {
36 println!("Root gathered table:");
37 for r in t.chunks(count) {
38 println!("{:?}", r);
39 }
40 }
41 assert!((0_u64..)
42 .zip(t.iter())
43 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
44
45 let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
46 t = vec![0u64; count * count];
47
48 {
49 let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
50 let mut rv = unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
51
52 world.all_gather_into(&sv, &mut rv);
53 }
54
55 if world.rank() == root_rank {
56 println!("Root gathered table:");
57 for r in t.chunks(count) {
58 println!("{:?}", r);
59 }
60 }
61 assert!((0_u64..)
62 .zip(t.iter())
63 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
64}
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10 let root_rank = 0;
11
12 let count = world.size() as usize;
13 let i = 2_u64.pow(world.rank() as u32 + 1);
14 let mut a = vec![0u64; count];
15
16 mpi::request::scope(|scope| {
17 world
18 .immediate_all_gather_into(scope, &i, &mut a[..])
19 .wait();
20 });
21
22 if world.rank() == root_rank {
23 println!("Root gathered sequence: {:?}.", a);
24 }
25 assert!(a
26 .iter()
27 .enumerate()
28 .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
29
30 let factor = world.rank() as u64 + 1;
31 let a = (1_u64..)
32 .take(count)
33 .map(|x| x * factor)
34 .collect::<Vec<_>>();
35 let mut t = vec![0u64; count * count];
36
37 mpi::request::scope(|scope| {
38 world
39 .immediate_all_gather_into(scope, &a[..], &mut t[..])
40 .wait();
41 });
42
43 if world.rank() == root_rank {
44 println!("Root gathered table:");
45 for r in t.chunks(count) {
46 println!("{:?}", r);
47 }
48 }
49 assert!((0_u64..)
50 .zip(t.iter())
51 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
52
53 let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
54 t = vec![0u64; count * count];
55
56 {
57 let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
58 let mut rv = unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
59 mpi::request::scope(|scope| {
60 world.immediate_all_gather_into(scope, &sv, &mut rv).wait();
61 });
62 }
63
64 if world.rank() == root_rank {
65 println!("Root gathered table:");
66 for r in t.chunks(count) {
67 println!("{:?}", r);
68 }
69 }
70 assert!((0_u64..)
71 .zip(t.iter())
72 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
73}
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10 let root_rank = 0;
11 let root_process = world.process_at_rank(root_rank);
12
13 let count = world.size() as usize;
14 let i = 2_u64.pow(world.rank() as u32 + 1);
15
16 if world.rank() == root_rank {
17 let mut a = vec![0u64; count];
18 root_process.gather_into_root(&i, &mut a[..]);
19 println!("Root gathered sequence: {:?}.", a);
20 assert!(a
21 .iter()
22 .enumerate()
23 .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
24 } else {
25 root_process.gather_into(&i);
26 }
27
28 let factor = world.rank() as u64 + 1;
29 let a = (1_u64..)
30 .take(count)
31 .map(|x| x * factor)
32 .collect::<Vec<_>>();
33
34 if world.rank() == root_rank {
35 let mut t = vec![0u64; count * count];
36 root_process.gather_into_root(&a[..], &mut t[..]);
37 println!("Root gathered table:");
38 for r in t.chunks(count) {
39 println!("{:?}", r);
40 }
41 assert!((0_u64..)
42 .zip(t.iter())
43 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
44 } else {
45 root_process.gather_into(&a[..]);
46 }
47
48 let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
49 let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
50
51 if world.rank() == root_rank {
52 let mut t = vec![0u64; count * count];
53
54 {
55 let mut rv =
56 unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
57 root_process.gather_into_root(&sv, &mut rv);
58 }
59
60 println!("Root gathered table:");
61 for r in t.chunks(count) {
62 println!("{:?}", r);
63 }
64 assert!((0_u64..)
65 .zip(t.iter())
66 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
67 } else {
68 root_process.gather_into(&sv);
69 }
70}
7fn main() {
8 let universe = mpi::initialize().unwrap();
9 let world = universe.world();
10 let root_rank = 0;
11 let root_process = world.process_at_rank(root_rank);
12
13 let count = world.size() as usize;
14 let i = 2_u64.pow(world.rank() as u32 + 1);
15
16 if world.rank() == root_rank {
17 let mut a = vec![0u64; count];
18 mpi::request::scope(|scope| {
19 root_process
20 .immediate_gather_into_root(scope, &i, &mut a[..])
21 .wait();
22 });
23 println!("Root gathered sequence: {:?}.", a);
24 assert!(a
25 .iter()
26 .enumerate()
27 .all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
28 } else {
29 mpi::request::scope(|scope| {
30 root_process.immediate_gather_into(scope, &i).wait();
31 });
32 }
33
34 let factor = world.rank() as u64 + 1;
35 let a = (1_u64..)
36 .take(count)
37 .map(|x| x * factor)
38 .collect::<Vec<_>>();
39
40 if world.rank() == root_rank {
41 let mut t = vec![0u64; count * count];
42 mpi::request::scope(|scope| {
43 root_process
44 .immediate_gather_into_root(scope, &a[..], &mut t[..])
45 .wait();
46 });
47 println!("Root gathered table:");
48 for r in t.chunks(count) {
49 println!("{:?}", r);
50 }
51 assert!((0_u64..)
52 .zip(t.iter())
53 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
54 } else {
55 mpi::request::scope(|scope| {
56 root_process.immediate_gather_into(scope, &a[..]).wait();
57 });
58 }
59
60 let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
61 let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
62
63 if world.rank() == root_rank {
64 let mut t = vec![0u64; count * count];
65
66 {
67 let mut rv =
68 unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
69 mpi::request::scope(|scope| {
70 root_process
71 .immediate_gather_into_root(scope, &sv, &mut rv)
72 .wait();
73 });
74 }
75
76 println!("Root gathered table:");
77 for r in t.chunks(count) {
78 println!("{:?}", r);
79 }
80 assert!((0_u64..)
81 .zip(t.iter())
82 .all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
83 } else {
84 mpi::request::scope(|scope| {
85 root_process.immediate_gather_into(scope, &sv).wait();
86 });
87 }
88}
Sourcepub fn vector<D>(
count: Count,
blocklength: Count,
stride: Count,
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn vector<D>(
count: Count,
blocklength: Count,
stride: Count,
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
Construct a new datatype out of count
blocks of blocklength
elements of oldtype
concatenated with the start of consecutive blocks placed stride
elements apart.
§Examples
See examples/vector.rs
§Standard section(s)
4.1.2
Examples found in repository?
8fn main() {
9 let universe = mpi::initialize().unwrap();
10 let world = universe.world();
11 let rank = world.rank();
12 let size = world.size();
13
14 let next_rank = (rank + 1) % size;
15 let next_process = world.process_at_rank(next_rank);
16 let previous_rank = (rank - 1 + size) % size;
17 let previous_process = world.process_at_rank(previous_rank);
18
19 let b1 = (1..).map(|x| rank * x).take(6).collect::<Vec<_>>();
20 let mut b2 = std::iter::repeat(-1).take(6).collect::<Vec<_>>();
21 println!("Rank {} sending message: {:?}.", rank, b1);
22 world.barrier();
23
24 let t = UserDatatype::vector(2, 2, 3, &Rank::equivalent_datatype());
25 let status;
26 {
27 let v1 = unsafe { View::with_count_and_datatype(&b1[..], 1, &t) };
28 let mut v2 = unsafe { MutView::with_count_and_datatype(&mut b2[..], 1, &t) };
29 status = p2p::send_receive_into(&v1, &next_process, &mut v2, &previous_process);
30 }
31
32 println!(
33 "Rank {} received message: {:?}, status: {:?}.",
34 rank, b2, status
35 );
36 world.barrier();
37
38 let b3 = (1..)
39 .map(|x| if x % 3 == 0 { -1 } else { previous_rank * x })
40 .take(6)
41 .collect::<Vec<_>>();
42 assert_eq!(b3, b2);
43}
Sourcepub fn heterogeneous_vector<D>(
count: Count,
blocklength: Count,
stride: Address,
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn heterogeneous_vector<D>(
count: Count,
blocklength: Count,
stride: Address,
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
Like vector()
but stride
is given in bytes rather than elements of oldtype
.
§Standard section(s)
4.1.2
Sourcepub fn indexed<D>(
blocklengths: &[Count],
displacements: &[Count],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn indexed<D>(
blocklengths: &[Count],
displacements: &[Count],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
Constructs a new type out of multiple blocks of individual length and displacement.
Block i
will be blocklengths[i]
items of datytpe oldtype
long and displaced by
dispplacements[i]
items of the oldtype
.
§Standard section(s)
4.1.2
Sourcepub fn heterogeneous_indexed<D>(
blocklengths: &[Count],
displacements: &[Address],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn heterogeneous_indexed<D>(
blocklengths: &[Count],
displacements: &[Address],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
Constructs a new type out of multiple blocks of individual length and displacement.
Block i
will be blocklengths[i]
items of datytpe oldtype
long and displaced by
dispplacements[i]
bytes.
§Standard section(s)
4.1.2
Sourcepub fn indexed_block<D>(
blocklength: Count,
displacements: &[Count],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn indexed_block<D>(
blocklength: Count,
displacements: &[Count],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
Construct a new type out of blocks of the same length and individual displacements.
§Standard section(s)
4.1.2
Sourcepub fn heterogeneous_indexed_block<D>(
blocklength: Count,
displacements: &[Address],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
pub fn heterogeneous_indexed_block<D>(
blocklength: Count,
displacements: &[Address],
oldtype: &D,
) -> UserDatatypewhere
D: UncommittedDatatype,
Construct a new type out of blocks of the same length and individual displacements. Displacements are in bytes.
§Standard section(s)
4.1.2
Sourcepub fn structured<D>(
blocklengths: &[Count],
displacements: &[Address],
types: &[D],
) -> UserDatatype
pub fn structured<D>( blocklengths: &[Count], displacements: &[Address], types: &[D], ) -> UserDatatype
Constructs a new datatype out of blocks of different length, displacement and datatypes
§Examples
See examples/structured.rs
§Standard section(s)
4.1.2
Examples found in repository?
10 fn equivalent_datatype() -> Self::Out {
11 UserDatatype::structured(
12 &[1, 1, 1],
13 &[
14 // Order the logical fields in reverse of their storage order
15 (size_of::<i32>() * 2) as mpi::Address,
16 size_of::<i32>() as mpi::Address,
17 0,
18 ],
19 &[i32::equivalent_datatype(); 3],
20 )
21 }
More examples
25 fn equivalent_datatype() -> Self::Out {
26 UserDatatype::structured(
27 &[1, 1, 1],
28 &[
29 offset_of!(ComplexDatatype, b) as Address,
30 offset_of!(ComplexDatatype, ints) as Address,
31 offset_of!(ComplexDatatype, tuple) as Address,
32 ],
33 &[
34 bool::equivalent_datatype().into(),
35 UncommittedUserDatatype::contiguous(4, &i32::equivalent_datatype()).as_ref(),
36 UncommittedUserDatatype::structured(
37 &[2, 1],
38 &[
39 offset_of!(TupleType, 0) as Address,
40 offset_of!(TupleType, 1) as Address,
41 ],
42 &[f32::equivalent_datatype(), u8::equivalent_datatype()],
43 )
44 .as_ref(),
45 ],
46 )
47 }
Sourcepub fn as_ref(&self) -> DatatypeRef<'_>
pub fn as_ref(&self) -> DatatypeRef<'_>
Creates a DatatypeRef from this datatype object.
Examples found in repository?
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}