pub struct OneSidedMemoryRegion<T: Dist> { /* private fields */ }
Expand description

A OneSided Memory Region is a RemoteMemoryRegion that has only been allocated on a single PE.

The memory region provides RDMA access to any PE which has a handle to the region.

OneSidedMemoryRegions implement distributed reference counting, so their handles can be sent along in active messages to other Remote PE’s, and it is gauranteed that the memory region will remain valid as long as a single reference exists on any PE anywhere in the distributed system (even if the original allocating PE drops all local references to the memory region)

OneSidedMemoryRegions are constructed using either the LamellarWorld instance or a LamellarTeam instance.

Memory Regions are low-level unsafe abstraction not really intended for use in higher-level applications

§Warning

Unless you are very confident in low level distributed memory access or you explicitly need a one sided memory region it is highly recommended you utilize the LamellarArray interface to construct and interact with distributed memory.

§Examples

 use lamellar::memregion::prelude::*;

 let world = LamellarWorldBuilder::new().build();
 let world_mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region::<usize>(1000);

Implementations§

source§

impl<T: Dist> OneSidedMemoryRegion<T>

source

pub unsafe fn put<U: Into<LamellarMemoryRegion<T>>>( &self, index: usize, data: U )

“Puts” (copies) data from a local memory location data into this memory region

The data buffer may not be safe to use upon return from this call, currently the user is responsible for completion detection, or you may use the similar blocking_put call (with a potential performance penalty);

§Safety

This call is always unsafe as mutual exclusitivity is not enforced, i.e. many other reader/writers can exist simultaneously. Additionally, when this call returns the underlying fabric provider may or may not have already copied the data buffer

§One-sided Operation

the calling PE initaites the remote transfer

§Panics

Panics if “data” does not have any local data on this PE Panics if index is out of bounds Panics if PE is out of bounds

§Examples
 use lamellar::active_messaging::prelude::*;
 use lamellar::memregion::prelude::*;

 #[AmData]
 struct MemRegionAm{
     mem_region: OneSidedMemoryRegion<usize>,
 }

 #[am]
 impl LamellarAm for MemRegionAm{
     async fn exec(self){
         let temp_buffer: OneSidedMemoryRegion<usize> = lamellar::world.alloc_one_sided_mem_region(10);
         unsafe{ for elem in temp_buffer.as_mut_slice().expect("PE just created memregion"){ *elem = lamellar::current_pe}}
         unsafe{ self.mem_region.put(lamellar::current_pe*temp_buffer.len(),temp_buffer)};
     }
 }

 let world = LamellarWorldBuilder::new().build();
 let my_pe = world.my_pe();
 let num_pes = world.num_pes();

 let mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region(num_pes*10);
 unsafe{ for elem in mem_region.as_mut_slice().expect("PE just created the memregion"){*elem = num_pes};}

 world.exec_am_all(MemRegionAm{mem_region: mem_region.clone()});

 unsafe {
     for (i,elem) in mem_region.iter().enumerate(){
         let pe = i / 10;
         while *elem == num_pes{
             std::thread::yield_now();
         }
         assert_eq!(pe,*elem);
     }      
 }
source

pub unsafe fn blocking_put<U: Into<LamellarMemoryRegion<T>>>( &self, index: usize, data: U )

Blocking “Puts” (copies) data from a local memory location into a remote memory location on the specified PE.

This function blocks until the data in the data buffer has been transfered out of this PE, this does not imply that it has arrived at the remote destination though

§Arguments

the data buffer is free to be reused upon return of this function.

§Safety

This call is always unsafe as mutual exclusitivity is not enforced, i.e. many other reader/writers can exist simultaneously.

§One-sided Operation

the calling PE initaites the remote transfer

§Panics

Panics if “data” does not have any local data on this PE Panics if index is out of bounds Panics if PE is out of bounds

§Examples
 use lamellar::active_messaging::prelude::*;
 use lamellar::memregion::prelude::*;

 #[AmData]
 struct MemRegionAm{
     mem_region: OneSidedMemoryRegion<usize>,
 }

 #[am]
 impl LamellarAm for MemRegionAm{
     async fn exec(self){
         let temp_buffer: OneSidedMemoryRegion<usize> = lamellar::world.alloc_one_sided_mem_region(10);
         unsafe{ for elem in temp_buffer.as_mut_slice().expect("PE just created memregion"){ *elem = lamellar::current_pe}}
         unsafe{ self.mem_region.blocking_put(lamellar::current_pe*temp_buffer.len(),temp_buffer)};
     }
 }

 let world = LamellarWorldBuilder::new().build();
 let my_pe = world.my_pe();
 let num_pes = world.num_pes();

 let mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region(num_pes*10);
 unsafe{ for elem in mem_region.as_mut_slice().expect("PE just created the memregion "){*elem = num_pes};}

 world.exec_am_all(MemRegionAm{mem_region: mem_region.clone()});

 unsafe {
     for (i,elem) in mem_region.iter().enumerate(){
         let pe = i / 10;
         while *elem == num_pes{
             std::thread::yield_now();
         }
         assert_eq!(pe,*elem);
     }      
 }
source

pub unsafe fn get_unchecked<U: Into<LamellarMemoryRegion<T>>>( &self, index: usize, data: U )

“Gets” (copies) data from (this) memory region into the provided data buffer. After calling this function, the data may or may not have actually arrived into the data buffer. The user is responsible for transmission termination detection

§Safety

This call is always unsafe as mutual exclusitivity is not enforced, i.e. many other reader/writers can exist simultaneously. Additionally, when this call returns the underlying fabric provider may or may not have already copied data into the data buffer.

§One-sided Operation

the calling PE initaites the remote transfer

§Panics

Panics if “data” does not have any local data on this PE Panics if index is out of bounds Panics if PE is out of bounds

§Examples
 use lamellar::active_messaging::prelude::*;
 use lamellar::memregion::prelude::*;
 use std::time::{Duration, Instant};

 #[AmData]
 struct MemRegionAm{
     mem_region: OneSidedMemoryRegion<usize>,
 }

 #[am]
 impl LamellarAm for MemRegionAm{
     async fn exec(self){
         let temp_buffer = OneSidedMemoryRegion<usize> = lamellar::world.alloc_one_sided_mem_region(mem_region.len());
         unsafe{ for elem in temp_buffer.as_mut_slice().expect("PE just created memregion"){ *elem = lamellar::current_pe}}
         unsafe{ self.mem_region.get_unchecked(lamellar::current_pe*temp_buffer.len(),temp_buffer)};
         unsafe {
             for elem in temp_buffer.iter(){
                 while *elem == lamellar::current_pe{
                     async_std::task::sleep(Duration::from_secs(self.secs)).await;
                 }
                 assert_eq!(lamellar::num_pes,*elem);
             }
         }
     }
 }

 let world = LamellarWorldBuilder::new().build();
 let my_pe = world.my_pe();
 let num_pes = world.num_pes();

 let mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region(num_pes*10);
 unsafe{ for elem in mem_region.as_mut_slice().expect("PE just created the memregion"){*elem = num_pes};}

 world.exec_am_all(MemRegionAm{mem_region: mem_region.clone()});
source

pub unsafe fn blocking_get<U: Into<LamellarMemoryRegion<T>>>( &self, index: usize, data: U )

Blocking “Gets” (copies) data from (this) memory region into the provided data buffer. After calling this function, the data is guaranteed to be placed in the data buffer

§Safety

This call is always unsafe as mutual exclusitivity is not enforced, i.e. many other reader/writers can exist simultaneously.

§One-sided Operation

the calling PE initaites the remote transfer

§Panics

Panics if “data” does not have any local data on this PE Panics if index is out of bounds Panics if PE is out of bounds

§Examples
 use lamellar::active_messaging::prelude::*;
 use lamellar::memregion::prelude::*;
 use std::time::{Duration, Instant};

 #[AmData]
 struct MemRegionAm{
     mem_region: OneSidedMemoryRegion<usize>,
 }

 #[am]
 impl LamellarAm for MemRegionAm{
     async fn exec(self){
         let temp_buffer = OneSidedMemoryRegion<usize> = lamellar::world.alloc_one_sided_mem_region(mem_region.len());
         unsafe{ for elem in temp_buffer.as_mut_slice().expect("PE just created memregion"){ *elem = lamellar::current_pe}}
         unsafe{ self.mem_region.get_unchecked(lamellar::current_pe*temp_buffer.len(),temp_buffer)};
         unsafe {
             for elem in temp_buffer.iter(){
                 while *elem == lamellar::current_pe{
                     async_std::task::sleep(Duration::from_secs(self.secs)).await;
                 }
                 assert_eq!(lamellar::num_pes,*elem);
             }
         }
     }
 }

 let world = LamellarWorldBuilder::new().build();
 let my_pe = world.my_pe();
 let num_pes = world.num_pes();

 let mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region(num_pes*10);
 unsafe{ for elem in mem_region.as_mut_slice().expect("PE just created the memregion"){*elem = num_pes};}

 world.exec_am_all(MemRegionAm{mem_region: mem_region.clone()});
source

pub unsafe fn iter(&self) -> Iter<'_, T>

An iterator to data local to this PE

§One-sided Operation

the calling PE initaites the remote transfer

§Panics

Panics if the calling PE does not contain any local data

§Examples
 use lamellar::memregion::prelude::*;

 let world = LamellarWorldBuilder::new().build();
 let num_pes = world.num_pes();
 let mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region(num_pes*10);

 for elem in unsafe {mem_region.iter()}{
     println!("elem {}",*elem);
 }
source

pub fn data_local(&self) -> bool

Checks for if the calling PE contains any local data

Returns true if the PE does contain data, false otherwise

§One-sided Operation

the calling PE initaites the remote transfer

§Examples
 use lamellar::active_messaging::prelude::*;
 use lamellar::memregion::prelude::*;

 #[AmData]
 struct MemRegionAm{
     mem_region: OneSidedMemoryRegion<usize>,
 }

 #[am]
 impl LamellarAm for MemRegionAm{
     async fn exec(self){
         println!("PE{}, memregion is local {}",lamellar::num_pes,self.mem_region.data_local());
     }
 }

 let world = LamellarWorldBuilder::new().build();
 let my_pe = world.my_pe();
 let num_pes = world.num_pes();

 let mem_region: OneSidedMemoryRegion<usize> = world.alloc_one_sided_mem_region(num_pes*10);
 unsafe{ for elem in mem_region.as_mut_slice().expect("PE just created the memregion"){*elem = num_pes};}

 world.exec_am_all(MemRegionAm{mem_region: mem_region.clone()});

Trait Implementations§

source§

impl<T: Clone + Dist> Clone for OneSidedMemoryRegion<T>

source§

fn clone(&self) -> OneSidedMemoryRegion<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Dist> Debug for OneSidedMemoryRegion<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, T: Dist> Deserialize<'de> for OneSidedMemoryRegion<T>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: Dist> From<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>

source§

fn from(smr: &OneSidedMemoryRegion<T>) -> Self

Converts to this type from the input type.
source§

impl<T: Dist> From<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>

source§

fn from(smr: &OneSidedMemoryRegion<T>) -> Self

Converts to this type from the input type.
source§

impl<T: Dist> LamellarEnv for OneSidedMemoryRegion<T>

source§

fn my_pe(&self) -> usize

Return the PE id of the calling PE, if called on a team instance, the PE id will be with respect to the team (not to the world)
source§

fn num_pes(&self) -> usize

Return the number of PEs in the execution
source§

fn num_threads_per_pe(&self) -> usize

Return the number of threads per PE
source§

fn world(&self) -> Arc<LamellarTeam>

Return a pointer the world team
source§

fn team(&self) -> Arc<LamellarTeam>

Return a pointer to the LamellarTeam
source§

impl<T: Dist> MemoryRegionRDMA<T> for OneSidedMemoryRegion<T>

source§

unsafe fn put<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )

“Puts” (copies) data from a local memory location into a remote memory location on the specified PE Read more
source§

unsafe fn blocking_put<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )

Blocking “Puts” (copies) data from a local memory location into a remote memory location on the specified PE. Read more
source§

unsafe fn put_all<U: Into<LamellarMemoryRegion<T>>>( &self, index: usize, data: U )

“Puts” (copies) data from a local memory location into a remote memory location on all PEs containing the memory region Read more
source§

unsafe fn get_unchecked<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )

“Gets” (copies) data from remote memory location on the specified PE into the provided data buffer. After calling this function, the data may or may not have actually arrived into the data buffer. The user is responsible for transmission termination detection Read more
source§

unsafe fn blocking_get<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )

Blocking “Gets” (copies) data from remote memory location on the specified PE into the provided data buffer. After calling this function, the data is guaranteed to be placed in the data buffer Read more
source§

impl<T: Dist> RegisteredMemoryRegion<T> for OneSidedMemoryRegion<T>

source§

fn len(&self) -> usize

The length (in number of elements of T) of the local segment of the memory region (i.e. not the global length of the memory region) Read more
source§

unsafe fn at(&self, index: usize) -> MemResult<&T>

Return a reference to the local (to the calling PE) element located by the provided index Read more
source§

unsafe fn as_slice(&self) -> MemResult<&[T]>

Return a slice of the local (to the calling PE) data of the memory region Read more
source§

unsafe fn as_mut_slice(&self) -> MemResult<&mut [T]>

Return a mutable slice of the local (to the calling PE) data of the memory region Read more
source§

unsafe fn as_ptr(&self) -> MemResult<*const T>

Return a ptr to the local (to the calling PE) data of the memory region Read more
source§

unsafe fn as_mut_ptr(&self) -> MemResult<*mut T>

Return a mutable ptr to the local (to the calling PE) data of the memory region Read more
source§

impl<T: Dist> Serialize for OneSidedMemoryRegion<T>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<T: Dist> TeamFrom<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>

source§

fn team_from( smr: &OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Self

Converts to this type from the input type
source§

impl<T: Dist> TeamFrom<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>

source§

fn team_from( smr: &OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Self

Converts to this type from the input type
source§

impl<T: Dist> TeamFrom<OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>

source§

fn team_from( smr: OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Self

Converts to this type from the input type
source§

impl<T: Dist> TeamFrom<OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>

source§

fn team_from( smr: OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Self

Converts to this type from the input type
source§

impl<T: Dist> TeamTryFrom<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>

source§

fn team_try_from( smr: &OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Result<Self, Error>

Trys to convert to this type from the input type
source§

impl<T: Dist> TeamTryFrom<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>

source§

fn team_try_from( smr: &OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Result<Self, Error>

Trys to convert to this type from the input type
source§

impl<T: Dist> TeamTryFrom<OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>

source§

fn team_try_from( smr: OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Result<Self, Error>

Trys to convert to this type from the input type
source§

impl<T: Dist> TeamTryFrom<OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>

source§

fn team_try_from( smr: OneSidedMemoryRegion<T>, _team: &Pin<Arc<LamellarTeamRT>> ) -> Result<Self, Error>

Trys to convert to this type from the input type

Auto Trait Implementations§

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<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> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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.

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T, U> TeamInto<U> for T
where U: TeamFrom<T>,

source§

fn team_into(self, team: &Pin<Arc<LamellarTeamRT>>) -> U

converts this type into the (usually inferred) input type
source§

impl<T, U> TeamTryInto<U> for T
where U: TeamTryFrom<T>,

source§

fn team_try_into(self, team: &Pin<Arc<LamellarTeamRT>>) -> Result<U, Error>

Trys to convert this type into the (usually inferred) input type
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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<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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
source§

impl<T> AmDist for T
where T: Serialize + DeserializeOwned + SyncSend + 'static,

source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

source§

impl<T> SyncSend for T
where T: Sync + Send,