pub mod comm;
use std::sync::Arc;
pub use comm::{RankComm, SerialComm};
#[cfg(feature = "distributed-mpi")]
pub use comm::MpiComm;
pub const MIN_LOCAL_QUBITS_DEFAULT: usize = 10;
pub fn min_local_qubits() -> usize {
use std::sync::OnceLock;
static CACHED: OnceLock<usize> = OnceLock::new();
*CACHED.get_or_init(|| env_usize_or("PRISM_DIST_MIN_LOCAL_QUBITS", MIN_LOCAL_QUBITS_DEFAULT, 1))
}
pub const EXCHANGE_CHUNK_DEFAULT: usize = usize::MAX;
pub fn exchange_chunk() -> usize {
use std::sync::OnceLock;
static CACHED: OnceLock<usize> = OnceLock::new();
*CACHED.get_or_init(|| env_usize_or("PRISM_DIST_EXCHANGE_CHUNK", EXCHANGE_CHUNK_DEFAULT, 1))
}
pub fn relabel_enabled() -> bool {
use std::sync::OnceLock;
static CACHED: OnceLock<bool> = OnceLock::new();
*CACHED.get_or_init(|| {
std::env::var("PRISM_DIST_RELABEL")
.map(|v| v != "0" && !v.eq_ignore_ascii_case("false"))
.unwrap_or(true)
})
}
#[inline]
fn env_usize_or(var: &str, default: usize, min: usize) -> usize {
std::env::var(var)
.ok()
.and_then(|v| v.parse::<usize>().ok())
.map(|n| n.max(min))
.unwrap_or(default)
}
pub struct DistributedContext {
comm: Arc<dyn RankComm>,
}
impl std::fmt::Debug for DistributedContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DistributedContext")
.field("rank", &self.rank())
.field("size", &self.size())
.finish()
}
}
impl DistributedContext {
pub fn from_comm(comm: Arc<dyn RankComm>) -> Arc<Self> {
Arc::new(Self { comm })
}
pub fn serial() -> Arc<Self> {
Self::from_comm(Arc::new(SerialComm))
}
#[cfg(feature = "distributed-mpi")]
pub fn world() -> Option<Arc<Self>> {
MpiComm::world().map(|c| Self::from_comm(Arc::new(c)))
}
pub fn rank(&self) -> usize {
self.comm.rank()
}
pub fn size(&self) -> usize {
self.comm.size()
}
pub(crate) fn comm(&self) -> &Arc<dyn RankComm> {
&self.comm
}
}