use std::collections::HashMap;
use std::sync::Mutex;
use crate::topology::Communicator;
pub mod class {
pub const SUCCESS: i32 = 0;
pub const BUFFER: i32 = 1;
pub const COUNT: i32 = 2;
pub const TYPE: i32 = 3;
pub const TAG: i32 = 4;
pub const COMM: i32 = 5;
pub const RANK: i32 = 6;
pub const REQUEST: i32 = 7;
pub const ROOT: i32 = 8;
pub const GROUP: i32 = 9;
pub const OP: i32 = 10;
pub const TOPOLOGY: i32 = 11;
pub const DIMS: i32 = 12;
pub const ARG: i32 = 13;
pub const UNKNOWN: i32 = 14;
pub const TRUNCATE: i32 = 15;
pub const OTHER: i32 = 16;
pub const INTERN: i32 = 17;
pub const PENDING: i32 = 18;
pub const IO: i32 = 32;
pub const LASTCODE: i32 = 64;
}
pub fn error_string(code: i32) -> String {
let s = match code {
class::SUCCESS => "no error",
class::BUFFER => "invalid buffer pointer",
class::COUNT => "invalid count argument",
class::TYPE => "invalid datatype argument",
class::TAG => "invalid tag argument",
class::COMM => "invalid communicator",
class::RANK => "invalid rank",
class::REQUEST => "invalid request",
class::ROOT => "invalid root",
class::GROUP => "invalid group",
class::OP => "invalid operation",
class::TOPOLOGY => "invalid topology",
class::DIMS => "invalid dimension argument",
class::ARG => "invalid argument",
class::TRUNCATE => "message truncated on receive",
class::OTHER => "known error not in this list",
class::INTERN => "internal MPI error",
class::PENDING => "pending request",
class::IO => "I/O error",
_ => "unknown error",
};
s.to_string()
}
pub fn error_class(code: i32) -> i32 {
code
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ErrorHandler {
Fatal,
Return,
}
static HANDLERS: Mutex<Option<HashMap<u32, ErrorHandler>>> = Mutex::new(None);
fn with_handlers<R>(f: impl FnOnce(&mut HashMap<u32, ErrorHandler>) -> R) -> R {
let mut guard = HANDLERS.lock().unwrap();
f(guard.get_or_insert_with(HashMap::new))
}
pub trait CommunicatorErrorHandler: Communicator {
fn set_error_handler(&self, handler: ErrorHandler) {
let ctx = self.comm_data().context;
with_handlers(|h| {
h.insert(ctx, handler);
});
}
fn error_handler(&self) -> ErrorHandler {
let ctx = self.comm_data().context;
with_handlers(|h| *h.get(&ctx).unwrap_or(&ErrorHandler::Fatal))
}
}
impl<C: Communicator + ?Sized> CommunicatorErrorHandler for C {}
pub mod traits {
pub use super::CommunicatorErrorHandler;
}