use std::cmp::Ordering;
use std::marker::PhantomData;
use crate::engine::generalized::PassId;
use crate::engine::{KvEvent, LifecycleEvent};
use super::core::{EngineEventBatch, EngineProgress};
use crate::engine::HandoffId;
use crate::replay::protocol::{ForwardPassSnapshot, OutputSignal};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum SimulationWorkerStage {
Aggregated,
Prefill,
Decode,
}
impl From<SimulationWorkerStage> for crate::replay::WorkerStage {
fn from(stage: SimulationWorkerStage) -> Self {
match stage {
SimulationWorkerStage::Aggregated => Self::Aggregated,
SimulationWorkerStage::Prefill => Self::Prefill,
SimulationWorkerStage::Decode => Self::Decode,
}
}
}
#[derive(Debug)]
pub(crate) struct WorkerCompletionPayload<Events: EngineEventBatch = ()> {
pub(crate) stage: SimulationWorkerStage,
pub(crate) worker_idx: usize,
pub(crate) completed_requests: usize,
pub(crate) output_signals: Vec<OutputSignal>,
pub(crate) lifecycle_events: Vec<LifecycleEvent>,
pub(crate) engine_events: Events,
pub(crate) pass_started_at_ms: f64,
pub(crate) artifact_pass_end_kv_events: Option<Box<[KvEvent]>>,
pub(crate) progress: EngineProgress,
pub(crate) fpm: Option<ForwardPassSnapshot>,
pub(crate) accept_length_output_tokens: usize,
pub(crate) accept_length_decode_forwards: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct EnginePassCompletion<Events: EngineEventBatch = ()> {
pub(crate) stage: SimulationWorkerStage,
pub(crate) worker_id: usize,
pub(crate) pass_id: PassId,
events: PhantomData<fn() -> Events>,
}
impl<Events: EngineEventBatch> EnginePassCompletion<Events> {
pub(crate) fn new(stage: SimulationWorkerStage, worker_id: usize, pass_id: PassId) -> Self {
Self {
stage,
worker_id,
pass_id,
events: PhantomData,
}
}
}
#[derive(Debug)]
pub(crate) enum SimulationEventKind<Events: EngineEventBatch = ()> {
EnginePassCompletion(EnginePassCompletion<Events>),
TransferComplete {
handoff_id: HandoffId,
},
WorkerReady {
stage: SimulationWorkerStage,
worker_id: usize,
},
ScalingTick,
TelemetryTick,
}
impl<Events: EngineEventBatch> SimulationEventKind<Events> {
fn ordering_rank(&self) -> u8 {
match self {
SimulationEventKind::TelemetryTick => 1,
SimulationEventKind::ScalingTick => 2,
_ => 0,
}
}
}
#[derive(Debug)]
pub(crate) struct SimulationEvent<Events: EngineEventBatch = ()> {
pub(crate) at_ms: f64,
pub(crate) seq_no: u64,
pub(crate) kind: SimulationEventKind<Events>,
}
impl<Events: EngineEventBatch> PartialEq for SimulationEvent<Events> {
fn eq(&self, other: &Self) -> bool {
self.at_ms.to_bits() == other.at_ms.to_bits() && self.seq_no == other.seq_no
}
}
impl<Events: EngineEventBatch> Eq for SimulationEvent<Events> {}
impl<Events: EngineEventBatch> PartialOrd for SimulationEvent<Events> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<Events: EngineEventBatch> Ord for SimulationEvent<Events> {
fn cmp(&self, other: &Self) -> Ordering {
other
.at_ms
.partial_cmp(&self.at_ms)
.unwrap_or(Ordering::Equal)
.then_with(|| other.kind.ordering_rank().cmp(&self.kind.ordering_rank()))
.then_with(|| other.seq_no.cmp(&self.seq_no))
}
}