pub struct MutView<'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> MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> MutView<'d, 'b, D, B>
sourcepub unsafe fn with_count_and_datatype(
buffer: &'b mut B,
count: Count,
datatype: &'d D
) -> MutView<'d, 'b, D, B>
pub unsafe fn with_count_and_datatype( buffer: &'b mut B, count: Count, datatype: &'d D ) -> MutView<'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 28)
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 28)
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 50)
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 58)
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 56)
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 68)
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 MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> AsDatatype for MutView<'d, 'b, D, B>
source§impl<'d, 'b, D, B> Collection for MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> Collection for MutView<'d, 'b, D, B>
source§impl<'d, 'b, D, B> PointerMut for MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> PointerMut for MutView<'d, 'b, D, B>
source§fn pointer_mut(&mut self) -> *mut c_void
fn pointer_mut(&mut self) -> *mut c_void
A mutable pointer to the starting address in memory
impl<'d, 'b, D, B> BufferMut for MutView<'d, 'b, D, B>
Auto Trait Implementations§
impl<'d, 'b, D, B> Freeze for MutView<'d, 'b, D, B>where
B: ?Sized,
impl<'d, 'b, D, B> RefUnwindSafe for MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> Send for MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> Sync for MutView<'d, 'b, D, B>
impl<'d, 'b, D, B> Unpin for MutView<'d, 'b, D, B>where
B: ?Sized,
impl<'d, 'b, D, B> !UnwindSafe for MutView<'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.