use serde::Deserialize;
use std::sync::OnceLock;
fn default_deadlock_warning_timeout() -> f64 {
600.0
}
fn default_am_group_batch_size() -> usize {
10000
}
fn default_dissemination_factor() -> usize {
2
}
fn default_backend() -> String {
if cfg!(feature = "enable-rofi-c") {
return "rofi_c".to_owned();
} else if cfg!(feature = "enable-libfabric-sys") {
return "libfabric-sys".to_owned();
} else if cfg!(feature = "enable-libfabric") {
return "libfabric".to_owned();
} else if cfg!(feature = "enable-libfabric-async") {
return "libfabric-async".to_owned();
} else if cfg!(feature = "enable-ucx") {
return "ucx".to_owned();
} else {
return "local".to_owned();
}
}
pub fn compiled_default_backend() -> String {
default_backend()
}
pub fn available_backends() -> Vec<&'static str> {
let mut backends = Vec::new();
if cfg!(feature = "enable-rofi-c") {
backends.push("rofi_c");
}
if cfg!(feature = "enable-libfabric-sys") {
backends.push("libfabric-sys");
}
if cfg!(feature = "enable-libfabric") {
backends.push("libfabric");
}
if cfg!(feature = "enable-libfabric-async") {
backends.push("libfabric-async");
}
if cfg!(feature = "enable-ucx") {
backends.push("ucx");
}
backends.push("shmem");
backends.push("local");
backends
}
fn default_executor() -> String {
#[cfg(feature = "tokio-executor")]
return "tokio".to_owned();
#[cfg(not(feature = "tokio-executor"))]
return "lamellar".to_owned();
}
fn default_batcher() -> String {
"simple".to_owned()
}
fn default_threads() -> usize {
#[cfg(doctest)]
return 1;
match std::thread::available_parallelism() {
Ok(n) => n.into(),
Err(_) => 4,
}
}
#[doc(hidden)]
#[derive(Deserialize, Debug, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum HeapMode {
Static,
Dynamic,
}
fn default_heap_mode() -> HeapMode {
HeapMode::Dynamic
}
#[doc(hidden)]
#[derive(Deserialize, Debug, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Alloc {
Heap,
Lamellae,
}
fn default_alloc() -> Alloc {
Alloc::Heap
}
#[doc(hidden)]
#[derive(Deserialize, Debug, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum IndexType {
Static,
Dynamic,
}
fn default_array_dynamic_index() -> IndexType {
IndexType::Dynamic
}
#[doc(hidden)]
#[derive(Deserialize, Debug, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum CmdQueue {
Batched,
Get,
GetEager,
GetSlots,
Put,
PutSlots,
PutEager,
}
fn default_cmd_queue() -> CmdQueue {
CmdQueue::Get
}
fn default_cmd_buf_len() -> usize {
50000
}
fn default_cmd_buf_cnt() -> usize {
2
}
fn default_am_size_threshold() -> usize {
100000
}
fn default_rofi_provider() -> String {
"verbs".to_owned()
}
fn default_rofi_domain() -> String {
"".to_owned()
}
fn deserialize_bool_or_int_to_bool<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
if let Ok(int) = s.parse::<u8>() {
Ok(Some(int != 0))
} else if let Ok(bool) = s.parse::<bool>() {
Ok(Some(bool))
} else {
Err(serde::de::Error::custom(format!(
"invalid boolean value: {}",
s
)))
}
}
fn default_ucc_oob_init_buffer_size() -> usize {
16 * 1024
}
#[doc(hidden)]
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(default = "default_deadlock_warning_timeout")]
pub deadlock_warning_timeout: f64,
#[serde(default = "default_am_group_batch_size")]
pub am_group_batch_size: usize,
#[serde(default = "default_dissemination_factor")]
pub barrier_dissemination_factor: usize,
#[serde(deserialize_with = "deserialize_bool_or_int_to_bool", default)]
pub blocking_call_warning: Option<bool>,
#[serde(deserialize_with = "deserialize_bool_or_int_to_bool", default)]
pub dropped_unused_handle_warning: Option<bool>,
#[serde(deserialize_with = "deserialize_bool_or_int_to_bool", default)]
pub unspawned_task_warning: Option<bool>,
#[serde(default = "default_backend")]
pub backend: String,
#[serde(default = "default_executor")]
pub executor: String,
#[serde(default = "default_batcher")]
pub batcher: String,
#[serde(default = "default_threads")]
pub threads: usize,
pub batch_op_threads: Option<usize>, pub heap_size: Option<usize>,
#[serde(default = "default_heap_mode")]
pub heap_mode: HeapMode,
#[serde(default = "default_alloc")]
pub alloc: Alloc,
#[serde(default = "default_array_dynamic_index")]
pub array_index_size: IndexType,
#[serde(default = "default_cmd_buf_len")]
pub cmd_buf_len: usize,
#[serde(default = "default_cmd_buf_cnt")]
pub cmd_buf_cnt: usize,
#[serde(default = "default_cmd_queue")]
pub cmd_queue: CmdQueue,
#[serde(default = "default_am_size_threshold")]
pub am_size_threshold: usize, #[serde(default = "default_rofi_provider")]
pub rofi_provider: String,
#[serde(default = "default_rofi_domain")]
pub rofi_domain: String,
#[serde(deserialize_with = "deserialize_bool_or_int_to_bool", default)]
pub disable_on_node_shmem: Option<bool>,
#[serde(default = "default_ucc_oob_init_buffer_size")]
pub ucc_oob_init_buffer_size: usize,
}
#[doc(hidden)]
pub fn config() -> &'static Config {
static CONFIG: OnceLock<Config> = OnceLock::new();
CONFIG.get_or_init(|| match envy::prefixed("LAMELLAR_").from_env::<Config>() {
Ok(config) => config,
Err(error) => panic!("{}", error),
})
}