use std::num::NonZeroU32;
use anyhow::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EngineIdentity {
pub worker_id: u64,
}
impl EngineIdentity {
pub const fn new(worker_id: u64) -> Self {
Self { worker_id }
}
pub const fn rank(self, dp_rank: u32, dp_size: NonZeroU32) -> RankIdentity {
RankIdentity {
worker_id: self.worker_id,
dp_rank,
dp_size,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RankIdentity {
pub worker_id: u64,
pub dp_rank: u32,
pub dp_size: NonZeroU32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GeneralizedEngineConfig<C> {
pub dp_size: NonZeroU32,
pub rank: C,
}
impl<C> GeneralizedEngineConfig<C> {
pub const fn single_rank(rank: C) -> Self {
Self {
dp_size: NonZeroU32::MIN,
rank,
}
}
pub const fn attention_dp(dp_size: NonZeroU32, rank: C) -> Self {
Self { dp_size, rank }
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CommandContext {
pub now_ms: f64,
pub pass_in_flight: bool,
}
impl CommandContext {
pub const fn allow_immediate_admission(self) -> bool {
!self.pass_in_flight
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SchedulerCommand<C> {
pub dp_rank: u32,
pub command: C,
}
impl<C> SchedulerCommand<C> {
pub const fn new(dp_rank: u32, command: C) -> Self {
Self { dp_rank, command }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RankEffects<T> {
pub dp_rank: u32,
pub effects: T,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EngineEffects<T> {
pub by_rank: Vec<RankEffects<T>>,
}
impl<T> EngineEffects<T> {
fn empty() -> Self {
Self {
by_rank: Vec::new(),
}
}
pub(crate) fn one(dp_rank: u32, effects: T) -> Self {
Self {
by_rank: vec![RankEffects { dp_rank, effects }],
}
}
pub fn is_empty(&self) -> bool {
self.by_rank.is_empty()
}
pub fn into_by_rank(self) -> Vec<RankEffects<T>> {
self.by_rank
}
}
impl<T> Default for EngineEffects<T> {
fn default() -> Self {
Self::empty()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PassId(pub(crate) u64);
impl PassId {
pub const fn get(self) -> u64 {
self.0
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum SameTimestampRetry {
#[default]
NotApplicable,
Retry,
Exhausted,
}
#[derive(Debug)]
pub struct RankPass<S, P> {
pub end_ms: f64,
pub same_timestamp_retry: SameTimestampRetry,
pub start_effects: S,
pub pending: P,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RankPassStarted<T> {
pub dp_rank: u32,
pub rank_end_ms: f64,
pub effects: T,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EnginePassStarted<T> {
pub pass_id: PassId,
pub started_at_ms: f64,
pub end_ms: f64,
pub participating_ranks: NonZeroU32,
pub same_timestamp_retry: SameTimestampRetry,
pub by_rank: Vec<RankPassStarted<T>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EnginePassCompleted<T> {
pub pass_id: PassId,
pub effects: EngineEffects<T>,
}
pub trait RankEngine: Sized {
type Config;
type Command;
type CommandEffects;
type PassStartEffects;
type PendingPass;
type PassCompletionEffects;
type InternalEffects;
fn new(identity: RankIdentity, config: &Self::Config) -> Result<Self>;
fn apply_command_effects(
&mut self,
command: Self::Command,
context: CommandContext,
pending_pass: Option<&mut Self::PendingPass>,
) -> Result<Self::CommandEffects>;
fn is_ready(&self) -> bool;
fn waiting_for_external_command(&self) -> bool {
false
}
fn execute_pass(
&mut self,
now_ms: f64,
) -> Result<RankPass<Self::PassStartEffects, Self::PendingPass>>;
fn complete_pass(
&mut self,
pending: Self::PendingPass,
end_ms: f64,
) -> Result<Self::PassCompletionEffects>;
fn complete_idle_group_pass(
&mut self,
_started_at_ms: f64,
_end_ms: f64,
) -> Result<Option<Self::PassCompletionEffects>> {
Ok(None)
}
fn next_internal_deadline_ms(&self) -> Option<f64>;
fn process_internal_work(
&mut self,
now_ms: f64,
pass_in_flight: bool,
) -> Result<Self::InternalEffects>;
fn is_drained(&self) -> bool;
}