Struct mpi::datatype::MutView

source ·
pub struct MutView<'d, 'b, D, B>
where D: 'd + Datatype, B: 'b + PointerMut + ?Sized,
{ /* 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>
where D: 'd + Datatype, B: 'b + PointerMut + ?Sized,

source

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 of buffer 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
Hide additional 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>
where D: 'd + Datatype, B: 'b + PointerMut + ?Sized,

§

type Out = &'d D

The type of the associated MPI datatype (e.g. SystemDatatype or UserDatatype)
source§

fn as_datatype(&self) -> Self::Out

The associated MPI datatype
source§

impl<'d, 'b, D, B> Collection for MutView<'d, 'b, D, B>
where D: 'd + Datatype, B: 'b + PointerMut + ?Sized,

source§

fn count(&self) -> Count

How many things are in this collection.
source§

impl<'d, 'b, D, B> PointerMut for MutView<'d, 'b, D, B>
where D: 'd + Datatype, B: 'b + PointerMut + ?Sized,

source§

fn pointer_mut(&mut self) -> *mut c_void

A mutable pointer to the starting address in memory
source§

impl<'d, 'b, D, B> BufferMut for MutView<'d, 'b, D, B>
where D: 'd + Datatype, B: 'b + PointerMut + ?Sized,

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>
where D: Sync, B: Send + ?Sized,

§

impl<'d, 'b, D, B> Sync for MutView<'d, 'b, D, B>
where D: Sync, B: Sync + ?Sized,

§

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<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<Src, Scheme> ApproxFrom<Src, Scheme> for Src
where Scheme: ApproxScheme,

§

type Err = NoError

The error type produced by a failed conversion.
source§

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 Src
where Dst: ApproxFrom<Src, Scheme>, Scheme: ApproxScheme,

§

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>

Convert the subject into an approximately equivalent representation.
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T, Dst> ConvAsUtil<Dst> for T

source§

fn approx(self) -> Result<Dst, Self::Err>
where Self: Sized + ApproxInto<Dst>,

Approximate the subject with the default scheme.
source§

fn approx_by<Scheme>(self) -> Result<Dst, Self::Err>
where Self: Sized + ApproxInto<Dst, Scheme>, Scheme: ApproxScheme,

Approximate the subject with a specific scheme.
source§

impl<T> ConvUtil for T

source§

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>
where Self: Sized + ApproxInto<Dst, Scheme>, Scheme: ApproxScheme,

Approximate the subject to a given type with a specific scheme.
source§

fn into_as<Dst>(self) -> Dst
where Self: Sized + Into<Dst>,

Convert the subject to a given type.
source§

fn try_as<Dst>(self) -> Result<Dst, Self::Err>
where Self: Sized + TryInto<Dst>,

Attempt to convert the subject to a given type.
source§

fn value_as<Dst>(self) -> Result<Dst, Self::Err>
where Self: Sized + ValueInto<Dst>,

Attempt a value conversion of the subject to a given type.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<Src> TryFrom<Src> for Src

§

type Err = NoError

The error type produced by a failed conversion.
source§

fn try_from(src: Src) -> Result<Src, <Src as TryFrom<Src>>::Err>

Convert the given value into the subject type.
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<Src, Dst> TryInto<Dst> for Src
where Dst: TryFrom<Src>,

§

type Err = <Dst as TryFrom<Src>>::Err

The error type produced by a failed conversion.
source§

fn try_into(self) -> Result<Dst, <Src as TryInto<Dst>>::Err>

Convert the subject into the destination type.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<Src> ValueFrom<Src> for Src

§

type Err = NoError

The error type produced by a failed conversion.
source§

fn value_from(src: Src) -> Result<Src, <Src as ValueFrom<Src>>::Err>

Convert the given value into an exactly equivalent representation.
source§

impl<Src, Dst> ValueInto<Dst> for Src
where Dst: ValueFrom<Src>,

§

type Err = <Dst as ValueFrom<Src>>::Err

The error type produced by a failed conversion.
source§

fn value_into(self) -> Result<Dst, <Src as ValueInto<Dst>>::Err>

Convert the subject into an exactly equivalent representation.