pub struct Rdma { /* private fields */ }
Expand description

Rdma handler, the only interface that the users deal with rdma

Implementations

Listen for new connections using the same mr_allocator and event_listener as parent Rdma

Used with connect and new_connect

Examples
use async_rdma::RdmaBuilder;
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().connect(addr).await?;
    for _ in 0..3 {
        let _new_rdma = rdma.new_connect(addr).await?;
    }
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().listen(addr).await?;
    for _ in 0..3 {
        let _new_rdma = rdma.listen().await?;
    }
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Establish new connections with RDMA server using the same mr_allocator and event_listener as parent Rdma

Used with listen

Examples
use async_rdma::RdmaBuilder;
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().connect(addr).await?;
    for _ in 0..3 {
        let _new_rdma = rdma.new_connect(addr).await?;
    }
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().listen(addr).await?;
    for _ in 0..3 {
        let _new_rdma = rdma.listen().await?;
    }
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send the content in the lm

Used with receive. Application scenario such as: client put data into a local mr and send to server. Server receive the mr sent by client and process data in it.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // read data from mr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(*lmr.as_ptr() as *const Data)).0
        )
    };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send the content in the lm with immediate date.

Used with receive_with_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);
static IMM_NUM: u32 = 123;
static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { std::ptr::write(*lmr.as_mut_ptr() as *mut Data, Data(MSG.to_string())) };
    // send the content of lmr and imm data to server
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send(&lmr).await?;
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data and imm sent by the client
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, Some(IMM_NUM));
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // receive the data in mr while avoiding the immediate data is ok.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // `receive_with_imm` works well even if the client didn't send any immediate data.
    // the imm received will be a `None`.
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, None);
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // compared to the above, using `receive` is a better choice.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Receive the content and stored in the returned memory region

Used with send. Application scenario such as: client put data into a local mr and send to server. Server receive the mr sent by client and process data in it.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // read data from mr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(*lmr.as_ptr() as *const Data)).0
        )
    };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Receive the content and stored in the returned memory region.

Used with send_with_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);
static IMM_NUM: u32 = 123;
static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { std::ptr::write(*lmr.as_mut_ptr() as *mut Data, Data(MSG.to_string())) };
    // send the content of lmr and imm data to server
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send_with_imm(&lmr, IMM_NUM).await?;
    rdma.send(&lmr).await?;
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data and imm sent by the client
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, Some(IMM_NUM));
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // receive the data in mr while avoiding the immediate data is ok.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // `receive_with_imm` works well even if the client didn't send any immediate data.
    // the imm received will be a `None`.
    let (lmr, imm) = rdma.receive_with_imm().await?;
    assert_eq!(imm, None);
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // compared to the above, using `receive` is a better choice.
    let lmr = rdma.receive().await?;
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Receive the immediate data sent by write_with_imm.

Used with write_with_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

static IMM_NUM: u32 = 123;
struct Data(String);

static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    let data = Data(MSG.to_string());
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = data };
    // write the content of lmr to remote mr with immediate data.
    rdma.write_with_imm(&lmr, &mut rmr, IMM_NUM).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the immediate data sent by `write_with_imm`
    let imm = rdma.receive_write_imm().await?;
    assert_eq!(imm, IMM_NUM);
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Read content in the rm and store the content in the lm

Application scenario such as: client put data into a local mr and send_mr to server. Server get a remote mr by receive_remote_mr, and then get data from this rmr by rdma read.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr(lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // receive the metadata of rmr sent by client
    let rmr = rdma.receive_remote_mr().await?;
    // `read` data from rmr to lmr
    rdma.read(&mut lmr, &rmr).await?;
    // assert the content of lmr, which was get from rmr by rdma `read`
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(*lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Write content in the lm to rm

Application scenario such as: client request a remote mr through request_remote_mr, and then put data into this rmr by rdma write. After all client send_mr to make server aware of this mr. After client send_mr, server receive_local_mr, and then get data from this mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // write the content of local mr into remote mr
    rdma.write(&lmr, &mut rmr).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(*lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Write content in the lm to rm and send a immediate data which will consume a rdma receive work request in the receiver’s receive queue. The receiver can receive this immediate data by using receive_write_imm.

Used with receive_write_imm.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

static IMM_NUM: u32 = 123;
struct Data(String);

static MSG: &str = "hello world";

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    let data = Data(MSG.to_string());
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = data };
    // write the content of lmr to server with immediate data.
    rdma.write_with_imm(&lmr, &mut rmr, IMM_NUM).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the immediate data sent by `write_with_imm`
    let imm = rdma.receive_write_imm().await?;
    assert_eq!(imm, IMM_NUM);
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe { assert_eq!(MSG.to_string(), *(*(*lmr.as_ptr() as *const Data)).0) };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    let server_handle = std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
    server_handle.join().unwrap().unwrap();
}

Connect the remote endpoint and build rmda queue pair by TCP connection

gid_index: 0:ipv6, 1:ipv4 max_message_length: max length of msg used in send&receive.

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let _rdma = Rdma::connect(addr, 1, 1, 512).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let _rdma = rdma_listener.accept(1, 1, 512).await?;
    // run here after client connect
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Allocate a local memory region

You can use local mr to send&receive or read&write with a remote mr. The parameter layout can be obtained by Layout::new::<Data>(). You can learn the way to write or read data in mr in the following example.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // assert data in the lmr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(*lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Allocate a local memory region that has not been initialized

You can use local mr to send&receive or read&write with a remote mr. The parameter layout can be obtained by Layout::new::<Data>(). You can learn the way to write or read data in mr in the following example.

Safety

The newly allocated memory in this LocalMr is uninitialized. Initialize it before using to make it safe.

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = unsafe { rdma.alloc_local_mr_uninit(Layout::new::<Data>())? };
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // send the content of lmr to server
    rdma.send(&lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the data sent by client and put it into an mr
    let lmr = rdma.receive().await?;
    // assert data in the lmr
    unsafe {
        assert_eq!(
            "hello world".to_string(),
            *(*(*lmr.as_ptr() as *const Data)).0
        )
    };
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Allocate a local memory region with specified access

Use alloc_local_mr if you want to alloc memory region with default access.

If you want more information, please check the documentation and examples of alloc_local_mr.

Example
use async_rdma::{AccessFlag, MrAccess, RdmaBuilder};
use std::alloc::Layout;

#[tokio::main]
async fn main() {
    let rdma = RdmaBuilder::default().build().unwrap();
    let layout = Layout::new::<[u8; 4096]>();
    let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
    let mr = rdma.alloc_local_mr_with_access(layout, access).unwrap();
    assert_eq!(mr.access(), access);
}

Allocate a local memory region with specified access that has not been initialized

Use alloc_local_mr_uninit if you want to alloc memory region with default access.

If you want more information, please check the documentation and examples of alloc_local_mr_uninit.

Safety

The newly allocated memory in this LocalMr is uninitialized. Initialize it before using to make it safe.

Example
use async_rdma::{AccessFlag, MrAccess, RdmaBuilder};
use std::alloc::Layout;

#[tokio::main]
async fn main() {
    let rdma = RdmaBuilder::default().build().unwrap();
    let layout = Layout::new::<[u8; 4096]>();
    let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
    let mr = unsafe {
        rdma.alloc_local_mr_uninit_with_access(layout, access)
            .unwrap()
    };
    assert_eq!(mr.access(), access);
}

Request a remote memory region with default timeout value.

Note: The operation of this memory region will fail after timeout.

Used with send_mr, receive_local_mr, read and write. Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // do something with rmr like `write` data into it.
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let _lmr = rdma.receive_local_mr().await?;
    // do something with lmr like getting data from it.
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Request a remote memory region with customized timeout value. The rest is consistent with request_remote_mr.

Note: The operation of this memory region will fail after timeout.

Used with send_mr, receive_local_mr, read and write. Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Examples
use async_rdma::{Rdma, RdmaListener, RemoteMrReadAccess};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let rmr = rdma
        .request_remote_mr_with_timeout(Layout::new::<Data>(), Duration::from_secs(10))
        .await?;
    assert!(!rmr.timeout_check());
    // do something with rmr like `write` data into it.
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let _lmr = rdma.receive_local_mr().await?;
    // do something with lmr like getting data from it.
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send a local memory region metadata to remote with default timeout value

Note: The operation of this memory region will fail after timeout.

Used with receive_remote_mr

Application scenario such as: client uses alloc_local_mr to alloc a local mr, and makes server aware of this mr by send_local_mr to server. For server, this mr is a remote mr, which can be received through receive_remote_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // do something with rmr like `write` data into it.
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr(lmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of rmr sent by client
    let _rmr = rdma.receive_remote_mr().await?;
    // do something with lmr like getting data from it.
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send a local memory region metadata with timeout to remote with customized timeout value.

Note: The operation of this memory region will fail after timeout.

Used with receive_remote_mr

Application scenario such as: client uses alloc_local_mr to alloc a local mr, and makes server aware of this mr by send_local_mr to server. For server, this mr is a remote mr, which can be received through receive_remote_mr.

Examples
use async_rdma::{Rdma, RdmaListener, RemoteMrReadAccess};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // do something with rmr like `write` data into it.
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr_with_timeout(lmr, Duration::from_secs(1))
        .await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of rmr sent by client
    let rmr = rdma.receive_remote_mr().await?;
    assert!(!rmr.timeout_check());
    // do something with lmr like getting data from it.
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Send a remote memory region metadata to remote

Used with receive_local_mr.

Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_remote_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // request a mr located in server.
    let rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // do something with rmr like `write` data into it.
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let _lmr = rdma.receive_local_mr().await?;
    // do something with lmr like getting data from it.
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Receive a local memory region

Used with send_mr. Application scenario such as: client uses request_remote_mr to apply for a remote mr from server, and makes server aware of this mr by send_mr to server. For server, this mr is a local mr, which can be received through receive_local_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples

Application scenario such as: client request a remote mr through request_remote_mr, and then put data into this rmr by rdma write. After all client send_mr to make server aware of this mr. After client send_mr, server receive_local_mr, and then get data from this mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{LocalMrReadAccess, LocalMrWriteAccess, Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    let mut lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    let mut rmr = rdma.request_remote_mr(Layout::new::<Data>()).await?;
    // put data into lmr
    unsafe { *(*lmr.as_mut_ptr() as *mut Data) = Data("hello world".to_string()) };
    // write the content of local mr into remote mr
    rdma.write(&lmr, &mut rmr).await?;
    // then send the metadata of rmr to server to make server aware of this mr.
    rdma.send_remote_mr(rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    // receive the metadata of the lmr that had been requested by client
    let lmr = rdma.receive_local_mr().await?;
    // assert the content of lmr, which was `write` by client
    unsafe {
        assert_eq!(
        "hello world".to_string(),
        *(*(*lmr.as_ptr() as *const Data)).0
    )
    };
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Receive a remote memory region

Used with send_mr. Application scenario such as: server alloc a local mr and put data into it and let client know about this mr through send_mr. For client, this is a remote mr located in server.Client receive the metadata of this mr by receive_remote_mr.

Application scenario can be seen in [/example/rpc.rs]

Examples
use async_rdma::{Rdma, RdmaListener};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

struct Data(String);

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = Rdma::connect(addr, 1, 1, 512).await?;
    // receive the metadata of rmr sent by client
    let _rmr = rdma.receive_remote_mr().await?;
    // do something with rmr like `read` data from it.
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma_listener = RdmaListener::bind(addr).await?;
    let rdma = rdma_listener.accept(1, 1, 512).await?;
    let lmr = rdma.alloc_local_mr(Layout::new::<Data>())?;
    // do something with lmr like put data into it.
    // then send the metadata of this lmr to server to make server aware of this mr.
    rdma.send_local_mr(lmr).await?;
    Ok(())
}
#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Set qp access for new Rdma that created by clone

Used with listen, new_connect

Examples
use async_rdma::{AccessFlag, RdmaBuilder};
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().connect(addr).await?;
    let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
    let rdma = rdma.set_new_qp_access(access);
    let _new_rdma = rdma.new_connect(addr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().listen(addr).await?;
        let _new_rdma = rdma.listen().await?;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Set max access permission for remote mr requests for new Rdma that created by clone

Used with listen, new_connect

Examples
use async_rdma::{AccessFlag, RdmaBuilder, MrAccess};
use portpicker::pick_unused_port;
use std::{
    alloc::Layout,
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().connect(addr).await?;
    let rmr = rdma.request_remote_mr(Layout::new::<char>()).await?;
    let new_rdma = rdma.new_connect(addr).await?;
    let new_rmr = new_rdma.request_remote_mr(Layout::new::<char>()).await?;
    let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
    assert_eq!(new_rmr.access(), access);
    assert_ne!(rmr.access(), new_rmr.access());
    new_rdma.send_remote_mr(new_rmr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().listen(addr).await?;
    let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
    let rdma = rdma.set_new_max_rmr_access(access);
    let new_rdma = rdma.listen().await?;
    // receive the metadata of the lmr that had been requested by client
    let _lmr = new_rdma.receive_local_mr().await?;
    // wait for the agent thread to send all reponses to the remote.
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Set qp access for new Rdma that created by clone

Used with listen, new_connect

Examples
use async_rdma::RdmaBuilder;
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().connect(addr).await?;
    let rdma = rdma.set_new_port_num(1_u8);
    let _new_rdma = rdma.new_connect(addr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().listen(addr).await?;
    let _new_rdma = rdma.listen().await?;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Set new ProtectionDomain for new Rdma that created by clone to provide isolation.

Used with listen, new_connect

Examples
use async_rdma::RdmaBuilder;
use portpicker::pick_unused_port;
use std::{
    io,
    net::{Ipv4Addr, SocketAddrV4},
    time::Duration,
};

async fn client(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().connect(addr).await?;
    let rdma = rdma.set_new_pd()?;
    // then the `Rdma`s created by `new_connect` will have a new `ProtectionDomain`
    let _new_rdma = rdma.new_connect(addr).await?;
    Ok(())
}

#[tokio::main]
async fn server(addr: SocketAddrV4) -> io::Result<()> {
    let rdma = RdmaBuilder::default().listen(addr).await?;
    let _new_rdma = rdma.listen().await?;
    Ok(())
}

#[tokio::main]
async fn main() {
    let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), pick_unused_port().unwrap());
    std::thread::spawn(move || server(addr));
    tokio::time::sleep(Duration::from_secs(3)).await;
    client(addr)
        .await
        .map_err(|err| println!("{}", err))
        .unwrap();
}

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Returns the argument unchanged.

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

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

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

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

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

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