use std::env;
pub fn is_slurm_job() -> bool {
env::var("SLURM_JOB_ID").is_ok()
}
pub fn job_id() -> Option<String> {
env::var("SLURM_JOB_ID").ok()
}
pub fn local_rank() -> Option<i32> {
env::var("SLURM_LOCALID").ok().and_then(|s| s.parse().ok())
}
pub fn local_size() -> Option<i32> {
env::var("SLURM_NTASKS_PER_NODE")
.ok()
.and_then(|s| s.parse().ok())
.or_else(|| {
env::var("SLURM_TASKS_PER_NODE")
.ok()
.and_then(|s| s.split('(').next().and_then(|n| n.parse().ok()))
})
}
pub fn num_nodes() -> Option<i32> {
env::var("SLURM_NNODES").ok().and_then(|s| s.parse().ok())
}
pub fn cpus_per_task() -> Option<i32> {
env::var("SLURM_CPUS_PER_TASK")
.ok()
.and_then(|s| s.parse().ok())
}
pub fn node_name() -> Option<String> {
env::var("SLURM_NODENAME")
.or_else(|_| env::var("SLURMD_NODENAME"))
.ok()
}
pub fn node_list() -> Option<String> {
env::var("SLURM_NODELIST").ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn not_in_slurm_by_default() {
if std::env::var("SLURM_JOB_ID").is_err() {
assert!(!is_slurm_job());
assert!(job_id().is_none());
assert!(local_rank().is_none());
}
}
#[test]
fn slurm_env_var_parsing() {
unsafe {
std::env::set_var("SLURM_TASKS_PER_NODE", "4(x2)");
std::env::remove_var("SLURM_NTASKS_PER_NODE");
}
assert_eq!(local_size(), Some(4));
unsafe {
std::env::set_var("SLURM_NTASKS_PER_NODE", "8");
std::env::set_var("SLURM_TASKS_PER_NODE", "4(x2)");
}
assert_eq!(local_size(), Some(8));
unsafe {
std::env::remove_var("SLURM_NTASKS_PER_NODE");
std::env::remove_var("SLURM_TASKS_PER_NODE");
}
assert_eq!(local_size(), None);
unsafe {
std::env::set_var("SLURM_JOB_ID", "12345");
}
assert!(is_slurm_job());
assert_eq!(job_id(), Some("12345".to_string()));
unsafe {
std::env::remove_var("SLURM_JOB_ID");
}
unsafe {
std::env::set_var("SLURM_NNODES", "16");
}
assert_eq!(num_nodes(), Some(16));
unsafe {
std::env::remove_var("SLURM_NNODES");
}
unsafe {
std::env::set_var("SLURM_CPUS_PER_TASK", "4");
}
assert_eq!(cpus_per_task(), Some(4));
unsafe {
std::env::remove_var("SLURM_CPUS_PER_TASK");
}
unsafe {
std::env::remove_var("SLURM_NODENAME");
std::env::remove_var("SLURMD_NODENAME");
}
assert_eq!(node_name(), None);
unsafe {
std::env::set_var("SLURM_NODENAME", "node01");
}
assert_eq!(node_name(), Some("node01".to_string()));
unsafe {
std::env::remove_var("SLURM_NODENAME");
}
unsafe {
std::env::set_var("SLURMD_NODENAME", "node02");
}
assert_eq!(node_name(), Some("node02".to_string()));
unsafe {
std::env::remove_var("SLURMD_NODENAME");
}
unsafe {
std::env::remove_var("SLURM_NODELIST");
}
assert_eq!(node_list(), None);
unsafe {
std::env::set_var("SLURM_NODELIST", "node[001-004]");
}
assert_eq!(node_list(), Some("node[001-004]".to_string()));
unsafe {
std::env::remove_var("SLURM_NODELIST");
}
unsafe {
std::env::set_var("SLURM_LOCALID", "not_a_number");
}
assert_eq!(local_rank(), None);
unsafe {
std::env::set_var("SLURM_LOCALID", "3");
}
assert_eq!(local_rank(), Some(3));
unsafe {
std::env::remove_var("SLURM_LOCALID");
}
unsafe {
std::env::set_var("SLURM_NTASKS_PER_NODE", "garbage");
std::env::set_var("SLURM_TASKS_PER_NODE", "6(x3)");
}
assert_eq!(local_size(), Some(6));
unsafe {
std::env::remove_var("SLURM_NTASKS_PER_NODE");
std::env::remove_var("SLURM_TASKS_PER_NODE");
}
unsafe {
std::env::set_var("SLURM_NNODES", "not_a_number");
}
assert_eq!(num_nodes(), None);
unsafe {
std::env::remove_var("SLURM_NNODES");
}
unsafe {
std::env::set_var("SLURM_CPUS_PER_TASK", "abc");
}
assert_eq!(cpus_per_task(), None);
unsafe {
std::env::remove_var("SLURM_CPUS_PER_TASK");
}
}
}