Skip to main content

Window

Struct Window 

Source
pub struct Window<T: RmaElement> { /* private fields */ }
Expand description

MPI-allocated homogeneous memory exposed to the communicator.

Send + Sync once constructed. Construction requires MPI_THREAD_MULTIPLE; the access epoch is entered inside allocate and left in close or Drop, and no public API exposes epoch transitions. All reads and writes are issued through the put/get/fetch_add family, each completed at the target before returning; no Rust reference into remotely mutable storage is ever exposed.

Implementations§

Source§

impl<T: RmaElement> Window<T>

Source

pub fn len(&self) -> usize

Number of locally allocated elements.

Examples found in repository?
examples/test_window.rs (line 46)
11fn main() {
12    let (universe, provided) =
13        mpi::initialize_with_threading(Threading::Multiple).expect("MPI must initialize once");
14    assert_eq!(provided, Threading::Multiple);
15    let world = universe.world();
16    let rank = world.rank();
17    let size = world.size();
18    assert_eq!(size, 2);
19    let next = (rank + 1) % size;
20    let prev = (rank + size - 1) % size;
21
22    // Element type must agree across ranks.
23    if rank == 0 {
24        assert!(matches!(
25            world.allocate_window::<u8>(1),
26            Err(Error::Window("element type differs between ranks"))
27        ));
28    } else {
29        assert!(matches!(
30            world.allocate_window::<u64>(2),
31            Err(Error::Window("element type differs between ranks"))
32        ));
33    }
34
35    // Self put/get, bounds, fetch_add; relies on Drop for shutdown.
36    {
37        let win = world.allocate_window::<u64>(8).unwrap();
38        win.put(rank, 0, &[rank as u64 + 10, rank as u64 + 20])
39            .unwrap();
40        let mut got = [0; 8];
41        win.get(rank, 0, &mut got).unwrap();
42        assert_eq!(got[0], rank as u64 + 10);
43        assert_eq!(got[1], rank as u64 + 20);
44
45        assert!(matches!(
46            win.put(rank, win.len(), &[1]),
47            Err(Error::Range { .. })
48        ));
49        assert!(matches!(win.put(-1, 0, &[1]), Err(Error::Rank(-1))));
50        assert!(matches!(win.put(size, 0, &[1]), Err(Error::Rank(_))));
51        assert!(matches!(
52            win.get(rank, win.len(), &mut [0]),
53            Err(Error::Range { .. })
54        ));
55
56        assert_eq!(win.fetch_add(rank, 7, rank as u64 + 1).unwrap(), 0);
57        assert_eq!(win.fetch_add(rank, 7, 0).unwrap(), rank as u64 + 1);
58        world.barrier();
59    }
60
61    // Cross-rank exchange.
62    {
63        let win = world.allocate_window::<u64>(8).unwrap();
64        win.put(next, 0, &[rank as u64 + 100]).unwrap();
65        world.barrier();
66        let mut got = [0u64; 1];
67        win.get(rank, 0, &mut got).unwrap();
68        assert_eq!(got[0], prev as u64 + 100);
69        world.barrier();
70        win.close().unwrap();
71    }
72
73    if rank == 0 {
74        println!("test_window: ok");
75    }
76}
Source

pub fn is_empty(&self) -> bool

Whether this rank allocated an empty window.

Source

pub fn memory_model(&self) -> MemoryModel

Memory model reported by MPI_WIN_MODEL.

Source

pub fn sync(&self) -> Result<(), Error>

Make remote updates visible to local memory accesses.

Required after a remote put on a separate-model window before any local read can observe the new contents.

Source

pub fn read_local(&self, disp: usize, out: &mut [T]) -> Result<(), Error>

Copy a region from this rank’s local window storage.

Concurrent remote updates to the same region yield undefined contents; the caller is responsible for the ordering. Volatile reads of single scalars are provided by read_local_volatile.

Source

pub fn read_local_volatile( &self, disp: usize, out: &mut [T], ) -> Result<(), Error>

Volatile local copy for scalars concurrently mutated by an RMA operation.

Source

pub fn put(&self, dest: Rank, disp: usize, data: &[T]) -> Result<(), Error>

Put a contiguous region and complete the transfer at the target before return.

The transfer reaches remote completion (target’s public window visible to subsequent get from any process) before this returns.

§Errors
Examples found in repository?
examples/test_window.rs (line 38)
11fn main() {
12    let (universe, provided) =
13        mpi::initialize_with_threading(Threading::Multiple).expect("MPI must initialize once");
14    assert_eq!(provided, Threading::Multiple);
15    let world = universe.world();
16    let rank = world.rank();
17    let size = world.size();
18    assert_eq!(size, 2);
19    let next = (rank + 1) % size;
20    let prev = (rank + size - 1) % size;
21
22    // Element type must agree across ranks.
23    if rank == 0 {
24        assert!(matches!(
25            world.allocate_window::<u8>(1),
26            Err(Error::Window("element type differs between ranks"))
27        ));
28    } else {
29        assert!(matches!(
30            world.allocate_window::<u64>(2),
31            Err(Error::Window("element type differs between ranks"))
32        ));
33    }
34
35    // Self put/get, bounds, fetch_add; relies on Drop for shutdown.
36    {
37        let win = world.allocate_window::<u64>(8).unwrap();
38        win.put(rank, 0, &[rank as u64 + 10, rank as u64 + 20])
39            .unwrap();
40        let mut got = [0; 8];
41        win.get(rank, 0, &mut got).unwrap();
42        assert_eq!(got[0], rank as u64 + 10);
43        assert_eq!(got[1], rank as u64 + 20);
44
45        assert!(matches!(
46            win.put(rank, win.len(), &[1]),
47            Err(Error::Range { .. })
48        ));
49        assert!(matches!(win.put(-1, 0, &[1]), Err(Error::Rank(-1))));
50        assert!(matches!(win.put(size, 0, &[1]), Err(Error::Rank(_))));
51        assert!(matches!(
52            win.get(rank, win.len(), &mut [0]),
53            Err(Error::Range { .. })
54        ));
55
56        assert_eq!(win.fetch_add(rank, 7, rank as u64 + 1).unwrap(), 0);
57        assert_eq!(win.fetch_add(rank, 7, 0).unwrap(), rank as u64 + 1);
58        world.barrier();
59    }
60
61    // Cross-rank exchange.
62    {
63        let win = world.allocate_window::<u64>(8).unwrap();
64        win.put(next, 0, &[rank as u64 + 100]).unwrap();
65        world.barrier();
66        let mut got = [0u64; 1];
67        win.get(rank, 0, &mut got).unwrap();
68        assert_eq!(got[0], prev as u64 + 100);
69        world.barrier();
70        win.close().unwrap();
71    }
72
73    if rank == 0 {
74        println!("test_window: ok");
75    }
76}
Source

pub fn get(&self, source: Rank, disp: usize, out: &mut [T]) -> Result<(), Error>

Get a contiguous region and complete the transfer before return.

§Errors
Examples found in repository?
examples/test_window.rs (line 41)
11fn main() {
12    let (universe, provided) =
13        mpi::initialize_with_threading(Threading::Multiple).expect("MPI must initialize once");
14    assert_eq!(provided, Threading::Multiple);
15    let world = universe.world();
16    let rank = world.rank();
17    let size = world.size();
18    assert_eq!(size, 2);
19    let next = (rank + 1) % size;
20    let prev = (rank + size - 1) % size;
21
22    // Element type must agree across ranks.
23    if rank == 0 {
24        assert!(matches!(
25            world.allocate_window::<u8>(1),
26            Err(Error::Window("element type differs between ranks"))
27        ));
28    } else {
29        assert!(matches!(
30            world.allocate_window::<u64>(2),
31            Err(Error::Window("element type differs between ranks"))
32        ));
33    }
34
35    // Self put/get, bounds, fetch_add; relies on Drop for shutdown.
36    {
37        let win = world.allocate_window::<u64>(8).unwrap();
38        win.put(rank, 0, &[rank as u64 + 10, rank as u64 + 20])
39            .unwrap();
40        let mut got = [0; 8];
41        win.get(rank, 0, &mut got).unwrap();
42        assert_eq!(got[0], rank as u64 + 10);
43        assert_eq!(got[1], rank as u64 + 20);
44
45        assert!(matches!(
46            win.put(rank, win.len(), &[1]),
47            Err(Error::Range { .. })
48        ));
49        assert!(matches!(win.put(-1, 0, &[1]), Err(Error::Rank(-1))));
50        assert!(matches!(win.put(size, 0, &[1]), Err(Error::Rank(_))));
51        assert!(matches!(
52            win.get(rank, win.len(), &mut [0]),
53            Err(Error::Range { .. })
54        ));
55
56        assert_eq!(win.fetch_add(rank, 7, rank as u64 + 1).unwrap(), 0);
57        assert_eq!(win.fetch_add(rank, 7, 0).unwrap(), rank as u64 + 1);
58        world.barrier();
59    }
60
61    // Cross-rank exchange.
62    {
63        let win = world.allocate_window::<u64>(8).unwrap();
64        win.put(next, 0, &[rank as u64 + 100]).unwrap();
65        world.barrier();
66        let mut got = [0u64; 1];
67        win.get(rank, 0, &mut got).unwrap();
68        assert_eq!(got[0], prev as u64 + 100);
69        world.barrier();
70        win.close().unwrap();
71    }
72
73    if rank == 0 {
74        println!("test_window: ok");
75    }
76}
Source

pub fn fetch_add(&self, dest: Rank, disp: usize, value: T) -> Result<T, Error>

Atomically add value at the target and return the previous value.

§Errors
Examples found in repository?
examples/test_window.rs (line 56)
11fn main() {
12    let (universe, provided) =
13        mpi::initialize_with_threading(Threading::Multiple).expect("MPI must initialize once");
14    assert_eq!(provided, Threading::Multiple);
15    let world = universe.world();
16    let rank = world.rank();
17    let size = world.size();
18    assert_eq!(size, 2);
19    let next = (rank + 1) % size;
20    let prev = (rank + size - 1) % size;
21
22    // Element type must agree across ranks.
23    if rank == 0 {
24        assert!(matches!(
25            world.allocate_window::<u8>(1),
26            Err(Error::Window("element type differs between ranks"))
27        ));
28    } else {
29        assert!(matches!(
30            world.allocate_window::<u64>(2),
31            Err(Error::Window("element type differs between ranks"))
32        ));
33    }
34
35    // Self put/get, bounds, fetch_add; relies on Drop for shutdown.
36    {
37        let win = world.allocate_window::<u64>(8).unwrap();
38        win.put(rank, 0, &[rank as u64 + 10, rank as u64 + 20])
39            .unwrap();
40        let mut got = [0; 8];
41        win.get(rank, 0, &mut got).unwrap();
42        assert_eq!(got[0], rank as u64 + 10);
43        assert_eq!(got[1], rank as u64 + 20);
44
45        assert!(matches!(
46            win.put(rank, win.len(), &[1]),
47            Err(Error::Range { .. })
48        ));
49        assert!(matches!(win.put(-1, 0, &[1]), Err(Error::Rank(-1))));
50        assert!(matches!(win.put(size, 0, &[1]), Err(Error::Rank(_))));
51        assert!(matches!(
52            win.get(rank, win.len(), &mut [0]),
53            Err(Error::Range { .. })
54        ));
55
56        assert_eq!(win.fetch_add(rank, 7, rank as u64 + 1).unwrap(), 0);
57        assert_eq!(win.fetch_add(rank, 7, 0).unwrap(), rank as u64 + 1);
58        world.barrier();
59    }
60
61    // Cross-rank exchange.
62    {
63        let win = world.allocate_window::<u64>(8).unwrap();
64        win.put(next, 0, &[rank as u64 + 100]).unwrap();
65        world.barrier();
66        let mut got = [0u64; 1];
67        win.get(rank, 0, &mut got).unwrap();
68        assert_eq!(got[0], prev as u64 + 100);
69        world.barrier();
70        win.close().unwrap();
71    }
72
73    if rank == 0 {
74        println!("test_window: ok");
75    }
76}
Source

pub fn close(self) -> Result<(), Error>

Close the window. Collective over the window group.

Prefer this over relying on Drop: the destructor’s shutdown runs the same steps but the collective boundary is implicit.

Examples found in repository?
examples/test_window.rs (line 70)
11fn main() {
12    let (universe, provided) =
13        mpi::initialize_with_threading(Threading::Multiple).expect("MPI must initialize once");
14    assert_eq!(provided, Threading::Multiple);
15    let world = universe.world();
16    let rank = world.rank();
17    let size = world.size();
18    assert_eq!(size, 2);
19    let next = (rank + 1) % size;
20    let prev = (rank + size - 1) % size;
21
22    // Element type must agree across ranks.
23    if rank == 0 {
24        assert!(matches!(
25            world.allocate_window::<u8>(1),
26            Err(Error::Window("element type differs between ranks"))
27        ));
28    } else {
29        assert!(matches!(
30            world.allocate_window::<u64>(2),
31            Err(Error::Window("element type differs between ranks"))
32        ));
33    }
34
35    // Self put/get, bounds, fetch_add; relies on Drop for shutdown.
36    {
37        let win = world.allocate_window::<u64>(8).unwrap();
38        win.put(rank, 0, &[rank as u64 + 10, rank as u64 + 20])
39            .unwrap();
40        let mut got = [0; 8];
41        win.get(rank, 0, &mut got).unwrap();
42        assert_eq!(got[0], rank as u64 + 10);
43        assert_eq!(got[1], rank as u64 + 20);
44
45        assert!(matches!(
46            win.put(rank, win.len(), &[1]),
47            Err(Error::Range { .. })
48        ));
49        assert!(matches!(win.put(-1, 0, &[1]), Err(Error::Rank(-1))));
50        assert!(matches!(win.put(size, 0, &[1]), Err(Error::Rank(_))));
51        assert!(matches!(
52            win.get(rank, win.len(), &mut [0]),
53            Err(Error::Range { .. })
54        ));
55
56        assert_eq!(win.fetch_add(rank, 7, rank as u64 + 1).unwrap(), 0);
57        assert_eq!(win.fetch_add(rank, 7, 0).unwrap(), rank as u64 + 1);
58        world.barrier();
59    }
60
61    // Cross-rank exchange.
62    {
63        let win = world.allocate_window::<u64>(8).unwrap();
64        win.put(next, 0, &[rank as u64 + 100]).unwrap();
65        world.barrier();
66        let mut got = [0u64; 1];
67        win.get(rank, 0, &mut got).unwrap();
68        assert_eq!(got[0], prev as u64 + 100);
69        world.barrier();
70        win.close().unwrap();
71    }
72
73    if rank == 0 {
74        println!("test_window: ok");
75    }
76}

Trait Implementations§

Source§

impl<T: RmaElement> Drop for Window<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<T: RmaElement> Send for Window<T>

Source§

impl<T: RmaElement> Sync for Window<T>

Auto Trait Implementations§

§

impl<T> Freeze for Window<T>

§

impl<T> RefUnwindSafe for Window<T>
where T: RefUnwindSafe,

§

impl<T> Unpin for Window<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Window<T>

§

impl<T> UnwindSafe for Window<T>

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,

Source§

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,

Source§

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

Source§

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>,

Source§

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>,

Source§

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>,

Source§

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

Source§

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>,

Source§

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.