use crate::topology::SystemCommunicator;
use crate::transport;
use crate::MpiError;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Threading {
Single,
Funneled,
Serialized,
Multiple,
}
impl Threading {
pub const fn max() -> Threading {
Threading::Multiple
}
}
pub struct Universe {
threading: Threading,
}
impl Universe {
pub fn world(&self) -> SystemCommunicator {
SystemCommunicator::world()
}
pub fn threading_support(&self) -> Threading {
self.threading
}
pub fn size(&self) -> Option<usize> {
Some(transport::runtime().size as usize)
}
pub fn buffer_attach(&self, size: usize) {
transport::runtime().buffer_attach(size);
}
pub fn buffer_size(&self) -> usize {
transport::runtime().buffer_size()
}
pub fn set_buffer_size(&mut self, size: usize) {
transport::runtime().set_buffer_size(size);
}
pub fn detach_buffer(&self) -> usize {
transport::runtime().buffer_detach()
}
}
impl Drop for Universe {
fn drop(&mut self) {
use crate::collective::CommunicatorCollectives;
use crate::topology::Communicator;
let world = SystemCommunicator::world();
if world.size() > 1 {
world.barrier();
}
}
}
pub fn time() -> f64 {
static START: std::sync::OnceLock<std::time::Instant> = std::sync::OnceLock::new();
START
.get_or_init(std::time::Instant::now)
.elapsed()
.as_secs_f64()
}
pub fn time_resolution() -> f64 {
1e-9
}
pub fn threading_support() -> Threading {
transport::runtime().threading
}
pub fn processor_name() -> Result<String, MpiError> {
let host = std::env::var("HOSTNAME")
.ok()
.or_else(|| std::env::var("HOST").ok())
.unwrap_or_else(|| "localhost".to_string());
Ok(host.to_string())
}
pub fn library_version() -> Result<String, MpiError> {
Ok(format!(
"pure-rust-mpi {} (rsmpi-compatible, no C library)",
env!("CARGO_PKG_VERSION")
))
}
pub fn version() -> (i32, i32) {
(3, 1)
}
pub fn initialize() -> Option<Universe> {
initialize_with_threading(Threading::Multiple).map(|(u, _)| u)
}
pub fn initialize_with_threading(requested: Threading) -> Option<(Universe, Threading)> {
match transport::init(requested) {
Ok(()) => {
let provided = transport::runtime().threading;
Some((
Universe {
threading: provided,
},
provided,
))
}
Err(MpiError::AlreadyInitialized) => None,
Err(e) => {
panic!("mpi::initialize failed: {e}");
}
}
}