use std::net::SocketAddr;
use fandhe_ai_autodiff::distributed as inner;
use super::config::DistributedConfig;
use super::error::DistributedError;
#[derive(Debug)]
pub struct Rendezvous {
inner: inner::Rendezvous,
collective: inner::CollectiveOptions,
}
impl Rendezvous {
pub fn bind(config: &DistributedConfig) -> Result<Rendezvous, DistributedError> {
let inner = inner::Rendezvous::bind(config.rendezvous.clone())
.map_err(DistributedError::from_inner)?;
Ok(Rendezvous {
inner,
collective: config.collective,
})
}
pub fn local_addr(&self) -> Option<SocketAddr> {
self.inner.rendezvous_local_addr()
}
pub fn establish(self) -> Result<Communicator, DistributedError> {
let links = self
.inner
.establish()
.map_err(DistributedError::from_inner)?;
let ring = inner::RingCommunicator::new(links, self.collective)
.map_err(DistributedError::from_inner)?;
Ok(Communicator { inner: ring })
}
}
#[derive(Debug)]
pub struct Communicator {
pub(crate) inner: inner::RingCommunicator,
}
impl Communicator {
pub fn init(config: &DistributedConfig) -> Result<Communicator, DistributedError> {
if config.world_size() >= 2 && config.rank() == 0 && config.rendezvous_addr().port() == 0 {
return Err(DistributedError::InvalidConfig {
reason: "rank 0 with world_size >= 2 needs a concrete rendezvous port (use Rendezvous for port 0)",
});
}
Rendezvous::bind(config)?.establish()
}
pub fn rank(&self) -> usize {
self.inner.rank()
}
pub fn world_size(&self) -> usize {
self.inner.world_size()
}
pub fn is_poisoned(&self) -> bool {
self.inner.is_poisoned()
}
}