Struct lamellar::memregion::OneSidedMemoryRegion
source · 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>
impl<T: Dist> OneSidedMemoryRegion<T>
sourcepub unsafe fn put<U: Into<LamellarMemoryRegion<T>>>(
&self,
index: usize,
data: U
)
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);
}
}
sourcepub unsafe fn blocking_put<U: Into<LamellarMemoryRegion<T>>>(
&self,
index: usize,
data: U
)
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);
}
}
sourcepub unsafe fn get_unchecked<U: Into<LamellarMemoryRegion<T>>>(
&self,
index: usize,
data: U
)
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()});
sourcepub unsafe fn blocking_get<U: Into<LamellarMemoryRegion<T>>>(
&self,
index: usize,
data: U
)
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()});
sourcepub unsafe fn iter(&self) -> Iter<'_, T>
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);
}
sourcepub fn data_local(&self) -> bool
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>
impl<T: Clone + Dist> Clone for OneSidedMemoryRegion<T>
source§fn clone(&self) -> OneSidedMemoryRegion<T>
fn clone(&self) -> OneSidedMemoryRegion<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<T: Dist> Debug for OneSidedMemoryRegion<T>
impl<T: Dist> Debug for OneSidedMemoryRegion<T>
source§impl<'de, T: Dist> Deserialize<'de> for OneSidedMemoryRegion<T>
impl<'de, T: Dist> Deserialize<'de> for OneSidedMemoryRegion<T>
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl<T: Dist> From<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>
impl<T: Dist> From<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaInput<T>
source§fn from(smr: &OneSidedMemoryRegion<T>) -> Self
fn from(smr: &OneSidedMemoryRegion<T>) -> Self
source§impl<T: Dist> From<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>
impl<T: Dist> From<&OneSidedMemoryRegion<T>> for LamellarArrayRdmaOutput<T>
source§fn from(smr: &OneSidedMemoryRegion<T>) -> Self
fn from(smr: &OneSidedMemoryRegion<T>) -> Self
source§impl<T: Dist> LamellarEnv for OneSidedMemoryRegion<T>
impl<T: Dist> LamellarEnv for OneSidedMemoryRegion<T>
source§fn my_pe(&self) -> usize
fn my_pe(&self) -> usize
source§fn num_threads_per_pe(&self) -> usize
fn num_threads_per_pe(&self) -> usize
source§fn world(&self) -> Arc<LamellarTeam>
fn world(&self) -> Arc<LamellarTeam>
source§fn team(&self) -> Arc<LamellarTeam>
fn team(&self) -> Arc<LamellarTeam>
source§impl<T: Dist> MemoryRegionRDMA<T> for OneSidedMemoryRegion<T>
impl<T: Dist> MemoryRegionRDMA<T> for OneSidedMemoryRegion<T>
source§unsafe fn put<U: Into<LamellarMemoryRegion<T>>>(
&self,
pe: usize,
index: usize,
data: U
)
unsafe fn put<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )
source§unsafe fn blocking_put<U: Into<LamellarMemoryRegion<T>>>(
&self,
pe: usize,
index: usize,
data: U
)
unsafe fn blocking_put<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )
source§unsafe fn put_all<U: Into<LamellarMemoryRegion<T>>>(
&self,
index: usize,
data: U
)
unsafe fn put_all<U: Into<LamellarMemoryRegion<T>>>( &self, index: usize, data: U )
source§unsafe fn get_unchecked<U: Into<LamellarMemoryRegion<T>>>(
&self,
pe: usize,
index: usize,
data: U
)
unsafe fn get_unchecked<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )
source§unsafe fn blocking_get<U: Into<LamellarMemoryRegion<T>>>(
&self,
pe: usize,
index: usize,
data: U
)
unsafe fn blocking_get<U: Into<LamellarMemoryRegion<T>>>( &self, pe: usize, index: usize, data: U )
source§impl<T: Dist> RegisteredMemoryRegion<T> for OneSidedMemoryRegion<T>
impl<T: Dist> RegisteredMemoryRegion<T> for OneSidedMemoryRegion<T>
source§fn len(&self) -> usize
fn len(&self) -> usize
T
) of the local segment of the memory region (i.e. not the global length of the memory region) Read more