use nexus_core::topology::{CpuGeneration, TopologyReport};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuntimeProfile {
Auto,
Epyc,
Dev,
}
impl RuntimeProfile {
pub fn from_str(value: &str) -> anyhow::Result<Self> {
match value {
"auto" => Ok(Self::Auto),
"epyc" => Ok(Self::Epyc),
"dev" => Ok(Self::Dev),
other => anyhow::bail!("unsupported runtime profile: {other}"),
}
}
pub fn resolve(self) -> Self {
match self {
Self::Auto => {
if cfg!(target_arch = "aarch64") {
Self::Dev
} else {
Self::Epyc
}
}
other => other,
}
}
pub fn as_str(self) -> &'static str {
match self {
Self::Auto => "auto",
Self::Epyc => "epyc",
Self::Dev => "dev",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AtcForceMode {
Auto,
Hypervisor,
Posix,
}
impl AtcForceMode {
pub fn from_str(value: &str) -> anyhow::Result<Self> {
match value {
"auto" => Ok(Self::Auto),
"hypervisor" => Ok(Self::Hypervisor),
"posix" => Ok(Self::Posix),
other => anyhow::bail!("unsupported ATC force mode: {other}"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AtcMode {
Hypervisor,
Posix,
}
impl AtcMode {
pub fn as_str(self) -> &'static str {
match self {
Self::Hypervisor => "hypervisor",
Self::Posix => "posix",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WorkerModel {
PinnedLocalset,
TokioWorkStealing,
}
impl WorkerModel {
pub fn as_str(self) -> &'static str {
match self {
Self::PinnedLocalset => "pinned-localset",
Self::TokioWorkStealing => "tokio-workstealing",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IoModel {
DirectSync,
Buffered,
}
impl IoModel {
pub fn as_str(self) -> &'static str {
match self {
Self::DirectSync => "direct-sync",
Self::Buffered => "buffered",
}
}
}
#[derive(Debug, Clone)]
pub struct AtcDecision {
pub mode: AtcMode,
pub runtime_profile: RuntimeProfile,
pub device_count: usize,
pub cpu_generation: CpuGeneration,
pub numa_nodes: usize,
pub worker_model: WorkerModel,
pub io_model: IoModel,
pub reason: String,
}
impl AtcDecision {
pub fn to_json(&self) -> String {
format!(
"{{\"mode\":\"{}\",\"runtime_profile\":\"{}\",\"device_count\":{},\"cpu_generation\":\"{}\",\"numa_nodes\":{},\"worker_model\":\"{}\",\"io_model\":\"{}\",\"reason\":\"{}\"}}",
self.mode.as_str(),
self.runtime_profile.as_str(),
self.device_count,
cpu_generation_label(self.cpu_generation),
self.numa_nodes,
self.worker_model.as_str(),
self.io_model.as_str(),
json_escape(self.reason.as_str()),
)
}
}
#[derive(Debug)]
pub struct AtcInput<'a> {
pub runtime_profile: RuntimeProfile,
pub force_mode: AtcForceMode,
pub device_count: usize,
pub single_device_threshold: usize,
pub topology: &'a TopologyReport,
}
pub fn decide(input: AtcInput<'_>) -> AtcDecision {
let runtime_profile = input.runtime_profile.resolve();
let single_threshold = input.single_device_threshold.max(1);
let device_count = input.device_count.max(1);
let is_single_device = device_count <= single_threshold;
let is_amd_zen = input.topology.cpu_vendor == "AuthenticAMD"
&& matches!(
input.topology.cpu_generation,
CpuGeneration::Zen2 | CpuGeneration::Zen3
);
let has_numa_or_ccx =
input.topology.numa_nodes.len() > 1 || !input.topology.ccx_groups.is_empty();
let (mode, reason) = match input.force_mode {
AtcForceMode::Hypervisor => (
AtcMode::Hypervisor,
"forced ATC mode hypervisor via --atc-force-mode".to_string(),
),
AtcForceMode::Posix => (
AtcMode::Posix,
"forced ATC mode posix via --atc-force-mode".to_string(),
),
AtcForceMode::Auto => {
if runtime_profile == RuntimeProfile::Dev {
(
AtcMode::Posix,
"runtime profile resolved to dev".to_string(),
)
} else if is_single_device {
(
AtcMode::Posix,
format!(
"device_count={} <= atc_single_device_threshold={}",
device_count, single_threshold
),
)
} else if is_amd_zen && has_numa_or_ccx {
(
AtcMode::Hypervisor,
"multi-device EPYC/Zen topology detected".to_string(),
)
} else {
(
AtcMode::Posix,
"topology not classified as EPYC/NUMA multi-device target".to_string(),
)
}
}
};
let (worker_model, io_model) = match mode {
AtcMode::Hypervisor => (WorkerModel::PinnedLocalset, IoModel::DirectSync),
AtcMode::Posix => (WorkerModel::TokioWorkStealing, IoModel::Buffered),
};
AtcDecision {
mode,
runtime_profile,
device_count,
cpu_generation: input.topology.cpu_generation,
numa_nodes: input.topology.numa_nodes.len(),
worker_model,
io_model,
reason,
}
}
fn cpu_generation_label(value: CpuGeneration) -> &'static str {
match value {
CpuGeneration::Zen2 => "Zen2",
CpuGeneration::Zen3 => "Zen3",
CpuGeneration::Unknown => "Unknown",
}
}
fn json_escape(value: &str) -> String {
value
.chars()
.flat_map(|ch| match ch {
'\\' => "\\\\".chars().collect::<Vec<_>>(),
'"' => "\\\"".chars().collect::<Vec<_>>(),
'\n' => "\\n".chars().collect::<Vec<_>>(),
'\r' => "\\r".chars().collect::<Vec<_>>(),
'\t' => "\\t".chars().collect::<Vec<_>>(),
other => vec![other],
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use nexus_core::topology::RssIrqAffinity;
fn topology(cpu_generation: CpuGeneration, cpu_vendor: &str, numa_nodes: usize) -> TopologyReport {
TopologyReport {
cpu_vendor: cpu_vendor.to_string(),
family_model: "0x19:0x1".to_string(),
cpu_generation,
numa_nodes: (0..numa_nodes).map(|_| vec![0, 1]).collect(),
ccx_groups: vec![vec![0, 1, 2, 3]],
rss_irq_map: vec![RssIrqAffinity {
irq: 1,
cpus: vec![0, 1],
}],
selected_cores: vec![0, 1, 2, 3],
}
}
#[test]
fn auto_chooses_posix_for_single_device() {
let t = topology(CpuGeneration::Zen3, "AuthenticAMD", 2);
let decision = decide(AtcInput {
runtime_profile: RuntimeProfile::Auto,
force_mode: AtcForceMode::Auto,
device_count: 1,
single_device_threshold: 1,
topology: &t,
});
assert_eq!(decision.mode, AtcMode::Posix);
assert_eq!(decision.io_model, IoModel::Buffered);
}
#[test]
fn auto_chooses_hypervisor_for_multi_device_epyc() {
let t = topology(CpuGeneration::Zen3, "AuthenticAMD", 2);
let decision = decide(AtcInput {
runtime_profile: RuntimeProfile::Epyc,
force_mode: AtcForceMode::Auto,
device_count: 5,
single_device_threshold: 1,
topology: &t,
});
assert_eq!(decision.mode, AtcMode::Hypervisor);
assert_eq!(decision.worker_model, WorkerModel::PinnedLocalset);
}
#[test]
fn force_mode_overrides_auto_logic() {
let t = topology(CpuGeneration::Unknown, "GenuineIntel", 1);
let decision = decide(AtcInput {
runtime_profile: RuntimeProfile::Auto,
force_mode: AtcForceMode::Hypervisor,
device_count: 1,
single_device_threshold: 1,
topology: &t,
});
assert_eq!(decision.mode, AtcMode::Hypervisor);
assert_eq!(decision.io_model, IoModel::DirectSync);
}
}