#[cfg(test)]
mod live_tests;
pub mod pool;
pub mod receiver;
pub mod sender;
use bytes::Bytes;
use crate::{net::ascii, status::TransferPoll, wire::WireError};
const REGISTER_ROOM: &[u8] = b"None";
pub fn shard_rows(span: i64, rank: i64, size: i64) -> (i64, i64) {
let (base, rem) = (span / size, span % size);
let start = rank * base + rank.min(rem);
let count = base + i64::from(rank < rem);
(start, count)
}
fn pointer(value: u64) -> Bytes {
Bytes::copy_from_slice(&value.to_ne_bytes())
}
pub fn registration_frames(
endpoint: &str,
port: u16,
session_id: &str,
embedding_base: u64,
deepstack_base: u64,
) -> Vec<Bytes> {
vec![
Bytes::from_static(REGISTER_ROOM),
ascii(endpoint),
ascii(port),
ascii(session_id),
pointer(embedding_base),
pointer(deepstack_base),
]
}
pub fn is_registration(frames: &[Bytes]) -> bool {
frames
.first()
.is_some_and(|room| room.as_ref() == REGISTER_ROOM)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TransferInfo {
pub room: u64,
pub endpoint: String,
pub port: u16,
pub session_id: String,
pub embedding_ptr: u64,
pub deepstack_ptr: u64,
pub rows: i64,
pub hidden: i64,
pub dtype: String,
pub has_deepstack: bool,
pub fanout: i64,
pub row_start: i64,
pub span: i64,
}
impl TransferInfo {
pub fn to_frames(&self) -> Vec<Bytes> {
vec![
ascii(self.room),
ascii(&self.endpoint),
ascii(self.port),
ascii(&self.session_id),
pointer(self.embedding_ptr),
pointer(self.deepstack_ptr),
ascii(self.rows),
ascii(self.hidden),
ascii(&self.dtype),
Bytes::from_static(if self.has_deepstack { b"1" } else { b"0" }),
ascii(self.fanout),
ascii(self.row_start),
ascii(self.span),
]
}
pub fn from_frames(frames: &[Bytes]) -> Result<Self, WireError> {
if frames.len() < 13 {
return Err(WireError(format!(
"malformed EmbeddingTransferInfo frame: {} parts < 13",
frames.len()
)));
}
let text = |index: usize, name: &str| {
std::str::from_utf8(&frames[index])
.ok()
.filter(|text| text.is_ascii())
.map(str::to_owned)
.ok_or_else(|| WireError(format!("{name} must be ASCII")))
};
let int = |index: usize, name: &str| -> Result<i64, WireError> {
text(index, name)?
.parse()
.map_err(|_| WireError(format!("{name} is not an integer")))
};
let ptr = |index: usize, name: &str| -> Result<u64, WireError> {
let bytes: [u8; 8] = frames[index]
.as_ref()
.try_into()
.map_err(|_| WireError(format!("{name} must be 8 bytes")))?;
Ok(u64::from_ne_bytes(bytes))
};
Ok(Self {
room: u64::try_from(int(0, "room")?)
.map_err(|_| WireError("negative room".to_owned()))?,
endpoint: text(1, "endpoint")?,
port: u16::try_from(int(2, "port")?)
.map_err(|_| WireError("invalid port".to_owned()))?,
session_id: text(3, "session")?,
embedding_ptr: ptr(4, "embedding pointer")?,
deepstack_ptr: ptr(5, "deepstack pointer")?,
rows: int(6, "rows")?,
hidden: int(7, "hidden")?,
dtype: text(8, "dtype")?,
has_deepstack: frames[9].as_ref() == b"1",
fanout: int(10, "fanout")?,
row_start: int(11, "row_start")?,
span: int(12, "span")?,
})
}
}
pub fn status_frames(room: u64, status: TransferPoll, rank: i64) -> Vec<Bytes> {
vec![ascii(room), ascii(status as i64), ascii(rank)]
}
pub fn parse_status(frames: &[Bytes]) -> Result<(u64, TransferPoll, i64), WireError> {
let [room, status, rank, ..] = frames else {
return Err(WireError("an EPD status has 3 frames".to_owned()));
};
let int = |frame: &Bytes, name: &str| -> Result<i64, WireError> {
std::str::from_utf8(frame)
.ok()
.and_then(|text| text.parse().ok())
.ok_or_else(|| WireError(format!("{name} is not an integer")))
};
let room =
u64::try_from(int(room, "room")?).map_err(|_| WireError("negative room".to_owned()))?;
let status = TransferPoll::from_wire(int(status, "status")?)
.ok_or_else(|| WireError("unknown status".to_owned()))?;
Ok((room, status, int(rank, "rank")?))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn shards_tile_the_span_in_rank_order() {
for (span, size) in [(10, 3), (2, 4), (0, 2), (7, 1), (16, 4)] {
let mut next = 0;
for rank in 0..size {
let (start, count) = shard_rows(span, rank, size);
assert_eq!(start, next, "span {span} size {size} rank {rank}");
next += count;
}
assert_eq!(next, span);
}
assert_eq!(shard_rows(10, 0, 3), (0, 4));
assert_eq!(shard_rows(10, 2, 3), (7, 3));
assert_eq!(shard_rows(2, 3, 4), (2, 0));
}
#[test]
fn a_transfer_request_round_trips() {
let info = TransferInfo {
room: 42,
endpoint: "10.0.0.2".to_owned(),
port: 7001,
session_id: "10.0.0.2:15000".to_owned(),
embedding_ptr: 0x7f00_0000_1000,
deepstack_ptr: 0,
rows: 3,
hidden: 1024,
dtype: "torch.bfloat16".to_owned(),
has_deepstack: false,
fanout: 2,
row_start: 4,
span: 7,
};
let frames = info.to_frames();
assert_eq!(frames.len(), 13);
assert!(!is_registration(&frames));
assert_eq!(TransferInfo::from_frames(&frames), Ok(info));
assert!(TransferInfo::from_frames(&frames[..12]).is_err());
let registration = registration_frames("10.0.0.2", 7001, "s", 0, 0);
assert!(is_registration(®istration));
assert_eq!(registration.len(), 6);
let status = status_frames(42, TransferPoll::Success, 1);
assert_eq!(parse_status(&status), Ok((42, TransferPoll::Success, 1)));
}
}