use super::slot;
use rustc_hash::FxHashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RingStatus {
Empty,
Published,
Claimed,
Done,
WaitIo,
Yield,
Requeue,
Fault,
Unknown(u32),
}
impl RingStatus {
#[must_use]
pub(super) fn from_raw(raw: u32) -> Self {
match raw {
slot::EMPTY => Self::Empty,
slot::PUBLISHED => Self::Published,
slot::CLAIMED => Self::Claimed,
slot::DONE => Self::Done,
slot::WAIT_IO => Self::WaitIo,
slot::YIELD => Self::Yield,
slot::REQUEUE => Self::Requeue,
slot::FAULT => Self::Fault,
other => Self::Unknown(other),
}
}
#[must_use]
pub const fn raw(self) -> u32 {
match self {
Self::Empty => slot::EMPTY,
Self::Published => slot::PUBLISHED,
Self::Claimed => slot::CLAIMED,
Self::Done => slot::DONE,
Self::WaitIo => slot::WAIT_IO,
Self::Yield => slot::YIELD,
Self::Requeue => slot::REQUEUE,
Self::Fault => slot::FAULT,
Self::Unknown(raw) => raw,
}
}
#[must_use]
pub const fn is_active(self) -> bool {
matches!(
self,
Self::Published | Self::Claimed | Self::WaitIo | Self::Yield | Self::Requeue
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RingSlotSnapshot {
pub slot_idx: u32,
pub status: RingStatus,
pub tenant_id: u32,
pub opcode: u32,
pub args_prefix: [u32; 3],
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WindowTelemetry {
pub ticket: u32,
pub tenant_id: u32,
pub opcode: u32,
pub required_slots: u32,
pub lookahead_slots: u32,
pub published: u32,
pub claimed: u32,
pub done: u32,
pub wait_io: u32,
pub yield_count: u32,
pub requeue: u32,
pub fault: u32,
}
impl WindowTelemetry {
#[must_use]
pub const fn is_active(&self) -> bool {
self.published > 0
|| self.claimed > 0
|| self.wait_io > 0
|| self.yield_count > 0
|| self.requeue > 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct RingOccupancy {
pub empty: u32,
pub published: u32,
pub claimed: u32,
pub done: u32,
pub wait_io: u32,
pub yield_count: u32,
pub requeue: u32,
pub fault: u32,
pub unknown: u32,
}
impl RingOccupancy {
#[must_use]
pub fn total_slots(&self) -> u32 {
checked_status_sum(
[
self.empty,
self.published,
self.claimed,
self.done,
self.wait_io,
self.yield_count,
self.requeue,
self.fault,
self.unknown,
],
"total ring slots",
)
}
#[must_use]
pub fn queue_depth(&self) -> u32 {
checked_status_sum(
[
self.published,
self.claimed,
self.wait_io,
self.yield_count,
self.requeue,
self.fault,
self.unknown,
],
"ring queue depth",
)
}
}
fn checked_status_sum<const N: usize>(values: [u32; N], label: &'static str) -> u32 {
values
.into_iter()
.try_fold(0_u32, |acc, value| acc.checked_add(value))
.unwrap_or_else(|| {
panic!("megakernel telemetry {label} overflowed u32. Fix: shard the ring snapshot.")
})
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct ControlSnapshot {
pub shutdown: bool,
pub done_count: u32,
pub epoch: u32,
pub metrics: Vec<(u32, u32)>,
pub tenant_fairness: Vec<u32>,
pub priority_fairness: Vec<u32>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MegakernelRuntimeCounters {
pub total_slots: u32,
pub queue_depth: u32,
pub gpu_idle_slots: u32,
pub gpu_idle_ppm: u32,
pub frontier_density_bps: u16,
pub occupancy_proxy_bps: u16,
pub drained_slots: u32,
pub unreclaimed_done_slots: u32,
pub tenant_fairness_total: u64,
pub tenant_fairness_skew: u32,
pub priority_fairness_total: u64,
pub requeue_slots: u32,
pub fault_slots: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MegakernelWatchdogSnapshot {
pub done_delta: u32,
pub queue_depth: u32,
pub fault_slots: u32,
pub requeue_slots: u32,
pub gpu_idle_ppm: u32,
pub suspected_stall: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct RingTelemetry {
pub control: ControlSnapshot,
pub occupancy: RingOccupancy,
pub slots: Vec<RingSlotSnapshot>,
pub windows: Vec<WindowTelemetry>,
}
#[derive(Debug, Default)]
pub struct TelemetryDecodeScratch {
pub(super) window_opcodes: Vec<u32>,
pub(super) windows: FxHashMap<(u32, u32), WindowAccumulator>,
}
impl TelemetryDecodeScratch {
#[must_use]
pub fn new() -> Self {
Self {
window_opcodes: Vec::new(),
windows: FxHashMap::default(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub(super) struct WindowAccumulator {
pub(super) tenant_id: u32,
pub(super) opcode: u32,
pub(super) required_slots: u32,
pub(super) lookahead_slots: u32,
pub(super) published: u32,
pub(super) claimed: u32,
pub(super) done: u32,
pub(super) wait_io: u32,
pub(super) yield_count: u32,
pub(super) requeue: u32,
pub(super) fault: u32,
}