pub struct View<'d, 'b, D, B>{ /* private fields */ }
Expand description
A buffer with a user specified count and datatype
§Safety
Views can be used to instruct the underlying MPI library to rummage around at arbitrary
locations in memory. This might be controlled later on using datatype bounds an slice lengths
but for now, all View constructors are marked unsafe
.
Implementations§
source§impl<'d, 'b, D, B> View<'d, 'b, D, B>
impl<'d, 'b, D, B> View<'d, 'b, D, B>
sourcepub unsafe fn with_count_and_datatype(
buffer: &'b B,
count: Count,
datatype: &'d D
) -> View<'d, 'b, D, B>
pub unsafe fn with_count_and_datatype( buffer: &'b B, count: Count, datatype: &'d D ) -> View<'d, 'b, D, B>
Return a view of buffer
containing count
instances of MPI datatype datatype
.
§Examples
See examples/contiguous.rs
, examples/vector.rs
§Safety
datatype
must map an element ofbuffer
without exposing any padding bytes or exceeding the bounds of the object.
Examples found in repository?
examples/contiguous.rs (line 27)
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let rank = world.rank();
let size = world.size();
let next_rank = (rank + 1) % size;
let next_process = world.process_at_rank(next_rank);
let previous_rank = (rank - 1 + size) % size;
let previous_process = world.process_at_rank(previous_rank);
let b1 = (1..).map(|x| rank * x).take(3).collect::<Vec<_>>();
let mut b2 = std::iter::repeat(-1).take(3).collect::<Vec<_>>();
println!("Rank {} sending message: {:?}.", rank, b1);
world.barrier();
let t = UserDatatype::contiguous(3, &Rank::equivalent_datatype());
let status;
{
let v1 = unsafe { View::with_count_and_datatype(&b1[..], 1, &t) };
let mut v2 = unsafe { MutView::with_count_and_datatype(&mut b2[..], 1, &t) };
status = p2p::send_receive_into(&v1, &next_process, &mut v2, &previous_process);
}
println!(
"Rank {} received message: {:?}, status: {:?}.",
rank, b2, status
);
world.barrier();
let b3 = (1..).map(|x| previous_rank * x).take(3).collect::<Vec<_>>();
assert_eq!(b3, b2);
}
More examples
examples/vector.rs (line 27)
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let rank = world.rank();
let size = world.size();
let next_rank = (rank + 1) % size;
let next_process = world.process_at_rank(next_rank);
let previous_rank = (rank - 1 + size) % size;
let previous_process = world.process_at_rank(previous_rank);
let b1 = (1..).map(|x| rank * x).take(6).collect::<Vec<_>>();
let mut b2 = std::iter::repeat(-1).take(6).collect::<Vec<_>>();
println!("Rank {} sending message: {:?}.", rank, b1);
world.barrier();
let t = UserDatatype::vector(2, 2, 3, &Rank::equivalent_datatype());
let status;
{
let v1 = unsafe { View::with_count_and_datatype(&b1[..], 1, &t) };
let mut v2 = unsafe { MutView::with_count_and_datatype(&mut b2[..], 1, &t) };
status = p2p::send_receive_into(&v1, &next_process, &mut v2, &previous_process);
}
println!(
"Rank {} received message: {:?}, status: {:?}.",
rank, b2, status
);
world.barrier();
let b3 = (1..)
.map(|x| if x % 3 == 0 { -1 } else { previous_rank * x })
.take(6)
.collect::<Vec<_>>();
assert_eq!(b3, b2);
}
examples/all_gather.rs (line 49)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let root_rank = 0;
let count = world.size() as usize;
let i = 2_u64.pow(world.rank() as u32 + 1);
let mut a = vec![0u64; count];
world.all_gather_into(&i, &mut a[..]);
if world.rank() == root_rank {
println!("Root gathered sequence: {:?}.", a);
}
assert!(a
.iter()
.enumerate()
.all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
let factor = world.rank() as u64 + 1;
let a = (1_u64..)
.take(count)
.map(|x| x * factor)
.collect::<Vec<_>>();
let mut t = vec![0u64; count * count];
world.all_gather_into(&a[..], &mut t[..]);
if world.rank() == root_rank {
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
t = vec![0u64; count * count];
{
let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
let mut rv = unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
world.all_gather_into(&sv, &mut rv);
}
if world.rank() == root_rank {
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
}
examples/immediate_all_gather.rs (line 57)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let root_rank = 0;
let count = world.size() as usize;
let i = 2_u64.pow(world.rank() as u32 + 1);
let mut a = vec![0u64; count];
mpi::request::scope(|scope| {
world
.immediate_all_gather_into(scope, &i, &mut a[..])
.wait();
});
if world.rank() == root_rank {
println!("Root gathered sequence: {:?}.", a);
}
assert!(a
.iter()
.enumerate()
.all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
let factor = world.rank() as u64 + 1;
let a = (1_u64..)
.take(count)
.map(|x| x * factor)
.collect::<Vec<_>>();
let mut t = vec![0u64; count * count];
mpi::request::scope(|scope| {
world
.immediate_all_gather_into(scope, &a[..], &mut t[..])
.wait();
});
if world.rank() == root_rank {
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
t = vec![0u64; count * count];
{
let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
let mut rv = unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
mpi::request::scope(|scope| {
world.immediate_all_gather_into(scope, &sv, &mut rv).wait();
});
}
if world.rank() == root_rank {
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
}
examples/gather.rs (line 49)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let root_rank = 0;
let root_process = world.process_at_rank(root_rank);
let count = world.size() as usize;
let i = 2_u64.pow(world.rank() as u32 + 1);
if world.rank() == root_rank {
let mut a = vec![0u64; count];
root_process.gather_into_root(&i, &mut a[..]);
println!("Root gathered sequence: {:?}.", a);
assert!(a
.iter()
.enumerate()
.all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
} else {
root_process.gather_into(&i);
}
let factor = world.rank() as u64 + 1;
let a = (1_u64..)
.take(count)
.map(|x| x * factor)
.collect::<Vec<_>>();
if world.rank() == root_rank {
let mut t = vec![0u64; count * count];
root_process.gather_into_root(&a[..], &mut t[..]);
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
} else {
root_process.gather_into(&a[..]);
}
let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
if world.rank() == root_rank {
let mut t = vec![0u64; count * count];
{
let mut rv =
unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
root_process.gather_into_root(&sv, &mut rv);
}
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
} else {
root_process.gather_into(&sv);
}
}
examples/immediate_gather.rs (line 61)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let root_rank = 0;
let root_process = world.process_at_rank(root_rank);
let count = world.size() as usize;
let i = 2_u64.pow(world.rank() as u32 + 1);
if world.rank() == root_rank {
let mut a = vec![0u64; count];
mpi::request::scope(|scope| {
root_process
.immediate_gather_into_root(scope, &i, &mut a[..])
.wait();
});
println!("Root gathered sequence: {:?}.", a);
assert!(a
.iter()
.enumerate()
.all(|(a, &b)| b == 2u64.pow(a as u32 + 1)));
} else {
mpi::request::scope(|scope| {
root_process.immediate_gather_into(scope, &i).wait();
});
}
let factor = world.rank() as u64 + 1;
let a = (1_u64..)
.take(count)
.map(|x| x * factor)
.collect::<Vec<_>>();
if world.rank() == root_rank {
let mut t = vec![0u64; count * count];
mpi::request::scope(|scope| {
root_process
.immediate_gather_into_root(scope, &a[..], &mut t[..])
.wait();
});
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
} else {
mpi::request::scope(|scope| {
root_process.immediate_gather_into(scope, &a[..]).wait();
});
}
let d = UserDatatype::contiguous(count as Count, &u64::equivalent_datatype());
let sv = unsafe { View::with_count_and_datatype(&a[..], 1, &d) };
if world.rank() == root_rank {
let mut t = vec![0u64; count * count];
{
let mut rv =
unsafe { MutView::with_count_and_datatype(&mut t[..], count as Count, &d) };
mpi::request::scope(|scope| {
root_process
.immediate_gather_into_root(scope, &sv, &mut rv)
.wait();
});
}
println!("Root gathered table:");
for r in t.chunks(count) {
println!("{:?}", r);
}
assert!((0_u64..)
.zip(t.iter())
.all(|(a, &b)| b == (a / count as u64 + 1) * (a % count as u64 + 1)));
} else {
mpi::request::scope(|scope| {
root_process.immediate_gather_into(scope, &sv).wait();
});
}
}
Trait Implementations§
source§impl<'d, 'b, D, B> AsDatatype for View<'d, 'b, D, B>
impl<'d, 'b, D, B> AsDatatype for View<'d, 'b, D, B>
source§impl<'d, 'b, D, B> Collection for View<'d, 'b, D, B>
impl<'d, 'b, D, B> Collection for View<'d, 'b, D, B>
impl<'d, 'b, D, B> Buffer for View<'d, 'b, D, B>
Auto Trait Implementations§
impl<'d, 'b, D, B> Freeze for View<'d, 'b, D, B>where
B: ?Sized,
impl<'d, 'b, D, B> RefUnwindSafe for View<'d, 'b, D, B>
impl<'d, 'b, D, B> Send for View<'d, 'b, D, B>
impl<'d, 'b, D, B> Sync for View<'d, 'b, D, B>
impl<'d, 'b, D, B> Unpin for View<'d, 'b, D, B>where
B: ?Sized,
impl<'d, 'b, D, B> UnwindSafe for View<'d, 'b, D, B>
Blanket Implementations§
source§impl<Src, Scheme> ApproxFrom<Src, Scheme> for Srcwhere
Scheme: ApproxScheme,
impl<Src, Scheme> ApproxFrom<Src, Scheme> for Srcwhere
Scheme: ApproxScheme,
source§fn approx_from(src: Src) -> Result<Src, <Src as ApproxFrom<Src, Scheme>>::Err>
fn approx_from(src: Src) -> Result<Src, <Src as ApproxFrom<Src, Scheme>>::Err>
Convert the given value into an approximately equivalent representation.
source§impl<Dst, Src, Scheme> ApproxInto<Dst, Scheme> for Srcwhere
Dst: ApproxFrom<Src, Scheme>,
Scheme: ApproxScheme,
impl<Dst, Src, Scheme> ApproxInto<Dst, Scheme> for Srcwhere
Dst: ApproxFrom<Src, Scheme>,
Scheme: ApproxScheme,
§type Err = <Dst as ApproxFrom<Src, Scheme>>::Err
type Err = <Dst as ApproxFrom<Src, Scheme>>::Err
The error type produced by a failed conversion.
source§fn approx_into(self) -> Result<Dst, <Src as ApproxInto<Dst, Scheme>>::Err>
fn approx_into(self) -> Result<Dst, <Src as ApproxInto<Dst, Scheme>>::Err>
Convert the subject into an approximately equivalent representation.
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
source§impl<T, Dst> ConvAsUtil<Dst> for T
impl<T, Dst> ConvAsUtil<Dst> for T
source§impl<T> ConvUtil for T
impl<T> ConvUtil for T
source§fn approx_as<Dst>(self) -> Result<Dst, Self::Err>where
Self: Sized + ApproxInto<Dst>,
fn approx_as<Dst>(self) -> Result<Dst, Self::Err>where
Self: Sized + ApproxInto<Dst>,
Approximate the subject to a given type with the default scheme.
source§fn approx_as_by<Dst, Scheme>(self) -> Result<Dst, Self::Err>
fn approx_as_by<Dst, Scheme>(self) -> Result<Dst, Self::Err>
Approximate the subject to a given type with a specific scheme.