use std::collections::BTreeSet;
use std::sync::Arc;
use onnx_runtime_ir::{DataType, Graph, NodeId, ValueId};
use crate::ExternalMmapRegion;
pub const NXRT_WEIGHT_PAGING_CAPABILITY: &str = "nxrt";
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct ExecutionProviderCapabilities {
flags: BTreeSet<String>,
}
impl ExecutionProviderCapabilities {
pub fn stock() -> Self {
Self::default()
}
pub fn nxrt_weight_paging() -> Self {
Self::from_flags([NXRT_WEIGHT_PAGING_CAPABILITY])
}
pub fn from_flags(flags: impl IntoIterator<Item = impl Into<String>>) -> Self {
Self {
flags: flags.into_iter().map(Into::into).collect(),
}
}
pub fn advertises(&self, capability: &str) -> bool {
self.flags.contains(capability)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ResidentWeight {
pub dtype: DataType,
pub shape: Vec<usize>,
bytes: Arc<[u8]>,
}
impl ResidentWeight {
pub fn new(
dtype: DataType,
shape: Vec<usize>,
bytes: impl Into<Arc<[u8]>>,
) -> Result<Self, WeightHandleError> {
let elements = checked_shape_product(&shape)?;
let expected = dtype.checked_storage_bytes(elements).ok_or_else(|| {
WeightHandleError::InvalidResident("resident weight byte count overflow".into())
})?;
if expected > isize::MAX as usize {
return Err(WeightHandleError::InvalidResident(
"resident weight byte count exceeds isize::MAX".into(),
));
}
let bytes = bytes.into();
if bytes.len() != expected {
return Err(WeightHandleError::InvalidResident(format!(
"resident weight has {} bytes, expected {expected}",
bytes.len()
)));
}
Ok(Self {
dtype,
shape,
bytes,
})
}
pub fn bytes(&self) -> &[u8] {
&self.bytes
}
}
fn checked_shape_product(shape: &[usize]) -> Result<usize, WeightHandleError> {
let mut product = 1usize;
let mut has_zero = false;
for &dimension in shape {
if dimension == 0 {
has_zero = true;
} else {
product = product.checked_mul(dimension).ok_or_else(|| {
WeightHandleError::InvalidResident("resident weight element count overflow".into())
})?;
}
}
Ok(if has_zero { 0 } else { product })
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LazyWeightBoundary {
MatMul,
BlockQuantizedMoe,
QMoe,
MatMulNBits,
}
impl LazyWeightBoundary {
pub const ALL: [LazyWeightBoundary; 4] = [
Self::MatMul,
Self::BlockQuantizedMoe,
Self::QMoe,
Self::MatMulNBits,
];
fn identity(self) -> (&'static str, &'static str) {
match self {
Self::MatMul => ("", "MatMul"),
Self::BlockQuantizedMoe => ("pkg.nxrt", "BlockQuantizedMoE"),
Self::QMoe => ("com.microsoft", "QMoE"),
Self::MatMulNBits => ("com.microsoft", "MatMulNBits"),
}
}
pub fn matches(self, domain: &str, op_type: &str) -> bool {
let (want_domain, want_op) = self.identity();
domain == want_domain && op_type == want_op
}
pub fn for_op(domain: &str, op_type: &str) -> Option<Self> {
Self::ALL
.into_iter()
.find(|boundary| boundary.matches(domain, op_type))
}
pub fn matches_any(domain: &str, op_type: &str) -> bool {
Self::for_op(domain, op_type).is_some()
}
pub const fn route_telemetry_producer_may_appear_after_compilation(self) -> bool {
matches!(self, Self::QMoe)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct LazyWeightCandidate {
pub value: ValueId,
pub boundary: LazyWeightBoundary,
pub first_consumer: NodeId,
}
pub fn lazy_weight_candidates(graph: &Graph) -> Vec<LazyWeightCandidate> {
let mut candidates = Vec::new();
for &value in graph.initializers.keys() {
let graph_value = graph.value(value);
let consumers = graph.consumers(value);
let Some(&first_consumer) = consumers.first() else {
continue;
};
let mut boundary = None;
let lazy_only = graph_value.producer.is_none()
&& !graph.outputs.contains(&value)
&& consumers.into_iter().all(|consumer| {
let node = graph.node(consumer);
match LazyWeightBoundary::for_op(&node.domain, &node.op_type) {
Some(found) => {
boundary.get_or_insert(found);
true
}
None => false,
}
});
if let Some(boundary) = boundary.filter(|_| lazy_only) {
candidates.push(LazyWeightCandidate {
value,
boundary,
first_consumer,
});
}
}
candidates
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ExpertWeightGroup {
pub node: NodeId,
pub boundary: LazyWeightBoundary,
pub members: Vec<ValueId>,
}
impl ExpertWeightGroup {
pub fn contains(&self, value: ValueId) -> bool {
self.members.contains(&value)
}
}
#[derive(Clone, Debug)]
pub struct FinalizedExpertWeight {
pub value: ValueId,
pub external_path: std::path::PathBuf,
pub weight: LazyWeight,
pub catalog: onnx_runtime_loader::WeightRegionCatalog,
}
#[derive(Clone, Debug)]
pub struct FinalizedExpertBank {
pub group: ExpertWeightGroup,
pub members: Vec<FinalizedExpertWeight>,
}
pub fn expert_weight_groups(graph: &Graph) -> Vec<ExpertWeightGroup> {
let mut groups = Vec::new();
for (node_id, node) in graph.nodes.iter() {
let boundary = match LazyWeightBoundary::for_op(&node.domain, &node.op_type) {
Some(LazyWeightBoundary::QMoe) => LazyWeightBoundary::QMoe,
Some(LazyWeightBoundary::BlockQuantizedMoe) => LazyWeightBoundary::BlockQuantizedMoe,
_ => continue,
};
let mut members = Vec::new();
for input in &node.inputs {
let Some(value) = input else { continue };
if graph.initializers.contains_key(value) && !members.contains(value) {
members.push(*value);
}
}
if !members.is_empty() {
groups.push(ExpertWeightGroup {
node: node_id,
boundary,
members,
});
}
}
groups
}
pub trait ResidentWeightMaterializer: Send + Sync {
fn materialize(&self) -> Result<ResidentWeight, WeightHandleError>;
}
impl<F> ResidentWeightMaterializer for F
where
F: Fn() -> Result<ResidentWeight, WeightHandleError> + Send + Sync,
{
fn materialize(&self) -> Result<ResidentWeight, WeightHandleError> {
self()
}
}
#[derive(Clone)]
pub struct LazyWeight {
pub boundary: LazyWeightBoundary,
pub dtype: DataType,
pub shape: Vec<usize>,
pub regions: Vec<ExternalMmapRegion>,
resident_materializer: Arc<dyn ResidentWeightMaterializer>,
}
impl std::fmt::Debug for LazyWeight {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter
.debug_struct("LazyWeight")
.field("boundary", &self.boundary)
.field("dtype", &self.dtype)
.field("shape", &self.shape)
.field("regions", &self.regions)
.field("resident_materializer", &"<deferred>")
.finish()
}
}
impl LazyWeight {
pub fn new<M>(
boundary: LazyWeightBoundary,
dtype: DataType,
shape: Vec<usize>,
regions: Vec<ExternalMmapRegion>,
resident_materializer: M,
) -> Result<Self, WeightHandleError>
where
M: ResidentWeightMaterializer + 'static,
{
if regions.is_empty() {
return Err(WeightHandleError::MissingRegions);
}
Ok(Self {
boundary,
dtype,
shape,
regions,
resident_materializer: Arc::new(resident_materializer),
})
}
pub fn block_quantized_moe<M>(
dtype: DataType,
shape: Vec<usize>,
regions: Vec<ExternalMmapRegion>,
resident_materializer: M,
) -> Result<Self, WeightHandleError>
where
M: ResidentWeightMaterializer + 'static,
{
Self::new(
LazyWeightBoundary::BlockQuantizedMoe,
dtype,
shape,
regions,
resident_materializer,
)
}
pub fn region_bytes_len(&self) -> usize {
self.regions.iter().map(|region| region.len).sum()
}
pub fn materialize(&self) -> Result<ResidentWeight, WeightHandleError> {
self.resident_materializer.materialize()
}
}
#[derive(Clone, Debug)]
pub enum WeightHandle {
Resident(ResidentWeight),
Lazy(LazyWeight),
}
impl WeightHandle {
pub fn negotiate(
&self,
capabilities: &ExecutionProviderCapabilities,
) -> Result<NegotiatedWeight, WeightHandleError> {
match self {
Self::Resident(weight) => Ok(NegotiatedWeight::Resident(weight.clone())),
Self::Lazy(weight) if capabilities.advertises(NXRT_WEIGHT_PAGING_CAPABILITY) => {
Ok(NegotiatedWeight::Lazy(weight.clone()))
}
Self::Lazy(weight) => Ok(NegotiatedWeight::Resident(weight.materialize()?)),
}
}
pub fn is_lazy_for(&self, capabilities: &ExecutionProviderCapabilities) -> bool {
matches!(self, Self::Lazy(_)) && capabilities.advertises(NXRT_WEIGHT_PAGING_CAPABILITY)
}
pub fn as_lazy(&self) -> Option<&LazyWeight> {
match self {
Self::Lazy(weight) => Some(weight),
Self::Resident(_) => None,
}
}
}
#[derive(Clone, Debug)]
pub enum NegotiatedWeight {
Resident(ResidentWeight),
Lazy(LazyWeight),
}
impl NegotiatedWeight {
pub fn materialize_host_fallback(&self) -> Result<ResidentWeight, WeightHandleError> {
match self {
Self::Resident(weight) => Ok(weight.clone()),
Self::Lazy(weight) => weight.materialize(),
}
}
pub fn try_bind_device<B: LazyDeviceWeightBinder>(
&self,
binder: &B,
) -> Result<B::Binding, WeightHandleError> {
match self {
Self::Resident(_) => Err(WeightHandleError::Unsupported(
"resident weights do not require lazy device binding".into(),
)),
Self::Lazy(weight) => binder.bind_block_quantized_moe(weight),
}
}
}
pub trait LazyDeviceWeightBinder {
type Binding;
fn bind_block_quantized_moe(
&self,
weight: &LazyWeight,
) -> Result<Self::Binding, WeightHandleError>;
}
pub trait MmapRegionSource {
fn region_bytes(&self, region: &ExternalMmapRegion) -> Result<&[u8], WeightHandleError>;
fn full_mapping_bytes(&self, _mapping_id: usize) -> Option<&[u8]> {
None
}
}
pub struct PagedWeight {
device_ptr: *const std::ffi::c_void,
device: onnx_runtime_ir::DeviceId,
len: usize,
keep_alive: Arc<dyn std::any::Any + Send + Sync>,
}
impl PagedWeight {
pub fn new(
device_ptr: *const std::ffi::c_void,
device: onnx_runtime_ir::DeviceId,
len: usize,
keep_alive: Arc<dyn std::any::Any + Send + Sync>,
) -> Self {
Self {
device_ptr,
device,
len,
keep_alive,
}
}
pub fn device_ptr(&self) -> *const std::ffi::c_void {
self.device_ptr
}
pub fn device(&self) -> onnx_runtime_ir::DeviceId {
self.device
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn keep_alive(&self) -> &Arc<dyn std::any::Any + Send + Sync> {
&self.keep_alive
}
}
impl std::fmt::Debug for PagedWeight {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter
.debug_struct("PagedWeight")
.field("device", &self.device)
.finish_non_exhaustive()
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Phase3aHostOnlyBinder;
impl LazyDeviceWeightBinder for Phase3aHostOnlyBinder {
type Binding = ();
fn bind_block_quantized_moe(
&self,
_weight: &LazyWeight,
) -> Result<Self::Binding, WeightHandleError> {
Err(WeightHandleError::Unsupported(
"live device weight paging is deferred to WEIGHT_OFFLOAD Phase 3b".into(),
))
}
}
#[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)]
pub enum WeightHandleError {
#[error("invalid resident weight: {0}")]
InvalidResident(String),
#[error("lazy weight requires at least one external mmap region")]
MissingRegions,
#[error("unsupported: {0}")]
Unsupported(String),
#[error("device weight binding failed: {0}")]
DeviceBinding(String),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ResidencyDegradationReason {
NonPageableCatalog(onnx_runtime_loader::NonPageableReason),
PolicyDeclinedSplit,
RejectedByValidation(String),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ResidencyDecision {
WholeBankResident {
reason: Option<ResidencyDegradationReason>,
},
PerExpertCandidate { experts: Vec<usize> },
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct ResidencyPlan {
decisions: std::collections::HashMap<ValueId, ResidencyDecision>,
policy_name: &'static str,
}
impl ResidencyPlan {
pub fn policy_name(&self) -> &'static str {
self.policy_name
}
pub fn decision(&self, value: ValueId) -> Option<&ResidencyDecision> {
self.decisions.get(&value)
}
pub fn ordered_values(&self) -> impl Iterator<Item = ValueId> + '_ {
let mut values: Vec<ValueId> = self.decisions.keys().copied().collect();
values.sort_unstable_by_key(|value| value.0);
values.into_iter()
}
pub fn len(&self) -> usize {
self.decisions.len()
}
pub fn is_empty(&self) -> bool {
self.decisions.is_empty()
}
pub fn resident_count(&self) -> usize {
self.decisions
.values()
.filter(|decision| {
matches!(
decision,
ResidencyDecision::WholeBankResident { reason: None }
)
})
.count()
}
pub fn degraded_count(&self) -> usize {
self.decisions
.values()
.filter(|decision| {
matches!(
decision,
ResidencyDecision::WholeBankResident { reason: Some(_) }
)
})
.count()
}
}
pub struct ResidencyPolicyInput<'a> {
pub value_id: ValueId,
pub boundary: LazyWeightBoundary,
pub catalog: &'a onnx_runtime_loader::WeightRegionCatalog,
pub budget_bytes: Option<u64>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EvictionClass {
Lru,
StableResident,
}
#[derive(Clone, Copy, Debug)]
pub struct AdmissionPolicyInput {
pub key: u64,
pub len_bytes: u64,
pub already_pinned: bool,
pub pinned_bytes_used: u64,
}
pub trait ResidencyPolicy: Send + Sync {
fn name(&self) -> &'static str;
fn decide(&self, input: &ResidencyPolicyInput<'_>) -> ResidencyDecision;
fn eviction_class(&self, boundary: LazyWeightBoundary) -> EvictionClass {
let _ = boundary;
EvictionClass::Lru
}
fn should_pin(&self, input: &AdmissionPolicyInput) -> bool {
let _ = input;
false
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct WholeBankResidentPolicy;
impl ResidencyPolicy for WholeBankResidentPolicy {
fn name(&self) -> &'static str {
"whole_bank_resident"
}
fn decide(&self, input: &ResidencyPolicyInput<'_>) -> ResidencyDecision {
let reason = if input.catalog.is_pageable() {
None
} else {
match input.catalog.pageability() {
onnx_runtime_loader::Pageability::NonPageable(reason) => Some(
ResidencyDegradationReason::NonPageableCatalog(reason.clone()),
),
onnx_runtime_loader::Pageability::Pageable => None,
}
};
ResidencyDecision::WholeBankResident { reason }
}
}
#[derive(Clone, Debug, Default)]
pub struct StaticProfileResidencyPolicy {
profile: std::collections::HashMap<ValueId, Vec<usize>>,
}
impl StaticProfileResidencyPolicy {
pub fn new(profile: std::collections::HashMap<ValueId, Vec<usize>>) -> Self {
let profile = profile
.into_iter()
.filter(|(_, experts)| !experts.is_empty())
.collect();
Self { profile }
}
pub fn with_entry(mut self, value: ValueId, experts: Vec<usize>) -> Self {
if experts.is_empty() {
self.profile.remove(&value);
} else {
self.profile.insert(value, experts);
}
self
}
pub fn profile_len(&self) -> usize {
self.profile.len()
}
}
impl ResidencyPolicy for StaticProfileResidencyPolicy {
fn name(&self) -> &'static str {
"static_profile"
}
fn decide(&self, input: &ResidencyPolicyInput<'_>) -> ResidencyDecision {
match self.profile.get(&input.value_id) {
Some(experts) if !experts.is_empty() => {
let mut sorted = experts.clone();
sorted.sort_unstable();
sorted.dedup();
ResidencyDecision::PerExpertCandidate { experts: sorted }
}
_ => WholeBankResidentPolicy.decide(input),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ResizeDirection {
Grow,
Shrink,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ResidencyResizeRequest {
pub direction: ResizeDirection,
pub target_bytes: u64,
pub priority: u32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct ResizeSafePoint {
pub capturing: bool,
pub pending_deferred_releases: u64,
pub admission_in_flight: bool,
pub multi_device: bool,
pub routed_guards_active: u64,
}
impl ResizeSafePoint {
pub fn is_safe(&self) -> bool {
!self.capturing
&& self.pending_deferred_releases == 0
&& !self.admission_in_flight
&& !self.multi_device
&& self.routed_guards_active == 0
}
pub fn blocking_reason(&self) -> Option<&'static str> {
if self.capturing {
return Some("a CUDA graph is currently capturing or replaying");
}
if self.pending_deferred_releases > 0 {
return Some("deferred weight-page releases have not settled");
}
if self.admission_in_flight {
return Some("a page admission is currently in flight");
}
if self.multi_device {
return Some(
"no existing barrier/authority coordinates a resize across devices/TP; \
failing closed rather than inventing distributed synchronization",
);
}
if self.routed_guards_active > 0 {
return Some(
"a RoutedResidencyProof guard is alive and promised its covered region \
set stays resident and unrelocated for its lifetime",
);
}
None
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ResizeRejection {
NotSafePoint(&'static str),
WouldExposeColdExpert,
ExecutionFailed(String),
NoOp,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ResidencyResizePlan {
Accepted(ResidencyResizeRequest),
Rejected {
request: ResidencyResizeRequest,
reason: ResizeRejection,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ResidencyResizeOutcome {
pub direction: ResizeDirection,
pub requested_bytes: u64,
pub accepted_bytes: u64,
pub before_bytes: u64,
pub after_bytes: u64,
pub rejection: Option<ResizeRejection>,
pub rollback_count: u32,
pub safe_point: ResizeSafePoint,
}
impl ResidencyResizeOutcome {
pub fn is_success(&self) -> bool {
self.rejection.is_none()
}
}
pub fn plan_resize(
request: ResidencyResizeRequest,
safe_point: ResizeSafePoint,
) -> ResidencyResizePlan {
if request.target_bytes == 0 {
return ResidencyResizePlan::Rejected {
request,
reason: ResizeRejection::NoOp,
};
}
if let Some(reason) = safe_point.blocking_reason() {
return ResidencyResizePlan::Rejected {
request,
reason: ResizeRejection::NotSafePoint(reason),
};
}
ResidencyResizePlan::Accepted(request)
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RoutedResidencyRequirement {
FusedRoutingUnknown,
HostKnownExperts { experts: Vec<usize> },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum WholeBankReason {
FusedRoutingHasNoHostVisibility,
InvalidExactSet(String),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RoutedResidencyCoverage {
WholeBank { reason: WholeBankReason },
ExactExperts { experts: Vec<usize> },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RoutedResidencyProof {
coverage: RoutedResidencyCoverage,
_sealed: (),
}
impl RoutedResidencyProof {
pub fn coverage(&self) -> &RoutedResidencyCoverage {
&self.coverage
}
pub fn blocks_resize(&self) -> bool {
true
}
}
pub trait RoutedResidencyGuardHandle: Send + Sync {
fn proof(&self) -> &RoutedResidencyProof;
}
pub fn prove_routed_residency(
requirement: RoutedResidencyRequirement,
catalog: &onnx_runtime_loader::WeightRegionCatalog,
) -> RoutedResidencyProof {
let coverage = match requirement {
RoutedResidencyRequirement::FusedRoutingUnknown => RoutedResidencyCoverage::WholeBank {
reason: WholeBankReason::FusedRoutingHasNoHostVisibility,
},
RoutedResidencyRequirement::HostKnownExperts { experts } => {
if !catalog.is_pageable() {
RoutedResidencyCoverage::WholeBank {
reason: WholeBankReason::InvalidExactSet(
"catalog is not pageable; cannot certify an exact expert set".into(),
),
}
} else {
let mut sorted = experts;
sorted.sort_unstable();
sorted.dedup();
match sorted
.iter()
.find(|&&expert| catalog.region(expert).is_none())
{
Some(&bad) => RoutedResidencyCoverage::WholeBank {
reason: WholeBankReason::InvalidExactSet(format!(
"expert index {bad} is out of range for this catalog"
)),
},
None => RoutedResidencyCoverage::ExactExperts { experts: sorted },
}
}
}
};
RoutedResidencyProof {
coverage,
_sealed: (),
}
}
pub fn plan_residency<'a>(
candidates: impl IntoIterator<
Item = (
ValueId,
LazyWeightBoundary,
&'a onnx_runtime_loader::WeightRegionCatalog,
),
>,
policy: &dyn ResidencyPolicy,
budget_bytes: Option<u64>,
) -> ResidencyPlan {
let mut decisions = std::collections::HashMap::new();
for (value, boundary, catalog) in candidates {
let input = ResidencyPolicyInput {
value_id: value,
boundary,
catalog,
budget_bytes,
};
let decision = policy.decide(&input);
let validated = validate_decision(catalog, decision);
decisions.insert(value, validated);
}
ResidencyPlan {
decisions,
policy_name: policy.name(),
}
}
fn validate_decision(
catalog: &onnx_runtime_loader::WeightRegionCatalog,
decision: ResidencyDecision,
) -> ResidencyDecision {
match decision {
ResidencyDecision::PerExpertCandidate { experts } => {
if !catalog.is_pageable() {
return ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(
"policy proposed per-expert placement over a nonpageable catalog".into(),
)),
};
}
let expert_count = catalog.layout().experts;
let mut seen = std::collections::HashSet::with_capacity(experts.len());
for &expert in &experts {
if expert >= expert_count {
return ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(format!(
"expert index {expert} out of range for a {expert_count}-expert bank"
))),
};
}
if !seen.insert(expert) {
return ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(format!(
"expert index {expert} appears more than once in one plan entry"
))),
};
}
if catalog.region(expert).is_none() {
return ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(format!(
"expert {expert} has no validated byte range in its catalog"
))),
};
}
}
let mut ordered = experts;
ordered.sort_unstable();
ResidencyDecision::PerExpertCandidate { experts: ordered }
}
whole_bank @ ResidencyDecision::WholeBankResident { .. } => whole_bank,
}
}
#[cfg(test)]
mod tests {
use std::sync::atomic::{AtomicUsize, Ordering};
use super::*;
fn resident() -> ResidentWeight {
ResidentWeight::new(DataType::Uint8, vec![4], vec![1, 2, 3, 4]).unwrap()
}
fn region() -> ExternalMmapRegion {
ExternalMmapRegion {
mapping_id: 7,
offset: 100,
len: 4,
}
}
fn lazy() -> WeightHandle {
WeightHandle::Lazy(
LazyWeight::block_quantized_moe(DataType::Uint8, vec![4], vec![region()], || {
Ok(resident())
})
.unwrap(),
)
}
#[test]
fn stock_ep_materializes_the_resident_fallback() {
let NegotiatedWeight::Resident(weight) = lazy()
.negotiate(&ExecutionProviderCapabilities::stock())
.unwrap()
else {
panic!("stock EP must receive resident materialization");
};
assert_eq!(weight.bytes(), &[1, 2, 3, 4]);
}
#[test]
fn nxrt_capability_preserves_lazy_block_quantized_moe_handle() {
let materializations = Arc::new(AtomicUsize::new(0));
let counter = Arc::clone(&materializations);
let lazy = WeightHandle::Lazy(
LazyWeight::block_quantized_moe(DataType::Uint8, vec![4], vec![region()], move || {
counter.fetch_add(1, Ordering::Relaxed);
Ok(resident())
})
.unwrap(),
);
let NegotiatedWeight::Lazy(weight) = lazy
.negotiate(&ExecutionProviderCapabilities::nxrt_weight_paging())
.unwrap()
else {
panic!("nxrt EP must receive lazy weight handle");
};
assert_eq!(weight.boundary, LazyWeightBoundary::BlockQuantizedMoe);
assert_eq!(weight.regions, vec![region()]);
assert_eq!(materializations.load(Ordering::Relaxed), 0);
assert_eq!(weight.materialize().unwrap().bytes(), &[1, 2, 3, 4]);
assert_eq!(materializations.load(Ordering::Relaxed), 1);
}
#[test]
fn offload_boundary_recognizes_dense_and_moe_boundaries() {
assert_eq!(
LazyWeightBoundary::for_op("", "MatMul"),
Some(LazyWeightBoundary::MatMul)
);
assert_eq!(
LazyWeightBoundary::for_op("pkg.nxrt", "BlockQuantizedMoE"),
Some(LazyWeightBoundary::BlockQuantizedMoe)
);
assert_eq!(
LazyWeightBoundary::for_op("com.microsoft", "QMoE"),
Some(LazyWeightBoundary::QMoe)
);
assert!(LazyWeightBoundary::matches_any("com.microsoft", "QMoE"));
assert!(LazyWeightBoundary::matches_any(
"pkg.nxrt",
"BlockQuantizedMoE"
));
assert!(LazyWeightBoundary::matches_any("", "MatMul"));
assert_eq!(LazyWeightBoundary::for_op("pkg.nxrt", "QMoE"), None);
assert_eq!(
LazyWeightBoundary::for_op("com.microsoft", "BlockQuantizedMoE"),
None
);
assert!(!LazyWeightBoundary::matches_any("ai.onnx", "MatMul"));
}
#[test]
fn only_qmoe_has_a_deferred_route_telemetry_producer() {
assert!(LazyWeightBoundary::QMoe.route_telemetry_producer_may_appear_after_compilation());
for boundary in [
LazyWeightBoundary::MatMul,
LazyWeightBoundary::BlockQuantizedMoe,
LazyWeightBoundary::MatMulNBits,
] {
assert!(
!boundary.route_telemetry_producer_may_appear_after_compilation(),
"{boundary:?} has no producer publication path"
);
}
}
fn shape1(n: usize) -> onnx_runtime_ir::Shape {
onnx_runtime_ir::static_shape([n])
}
fn inline_initializer(graph: &mut Graph, name: &str) -> ValueId {
let value = graph.create_named_value(name, DataType::Uint8, shape1(4));
graph.set_initializer(
value,
onnx_runtime_ir::WeightRef::Inline(onnx_runtime_ir::TensorData::from_raw(
DataType::Uint8,
vec![4],
vec![0u8; 4],
)),
);
value
}
#[test]
fn expert_weight_groups_groups_every_qmoe_input_initializer() {
let mut graph = Graph::new();
let input = graph.create_named_value("input", DataType::Float32, shape1(4));
let router = graph.create_named_value("router_probs", DataType::Float32, shape1(4));
let fc1_w = inline_initializer(&mut graph, "fc1_experts_weights");
let fc1_s = inline_initializer(&mut graph, "fc1_scales");
let fc1_b = inline_initializer(&mut graph, "fc1_experts_bias");
let fc2_w = inline_initializer(&mut graph, "fc2_experts_weights");
let fc2_s = inline_initializer(&mut graph, "fc2_scales");
let fc3_w = inline_initializer(&mut graph, "fc3_experts_weights");
let fc3_s = inline_initializer(&mut graph, "fc3_scales");
let output = graph.create_named_value("output", DataType::Float32, shape1(4));
let mut node = onnx_runtime_ir::Node::new(
NodeId(0),
"QMoE",
vec![
Some(input),
Some(router),
Some(fc1_w),
Some(fc1_s),
Some(fc1_b),
Some(fc2_w),
Some(fc2_s),
None,
Some(fc3_w),
Some(fc3_s),
],
vec![output],
);
node.domain = "com.microsoft".to_string();
let node_id = graph.insert_node(node);
let groups = expert_weight_groups(&graph);
assert_eq!(groups.len(), 1, "exactly one QMoE node -> one group");
let group = &groups[0];
assert_eq!(group.node, node_id);
assert_eq!(group.boundary, LazyWeightBoundary::QMoe);
assert_eq!(
group.members,
vec![fc1_w, fc1_s, fc1_b, fc2_w, fc2_s, fc3_w, fc3_s]
);
assert!(group.contains(fc1_w));
assert!(group.contains(fc3_s));
assert!(!group.contains(input));
assert!(!group.contains(router));
}
#[test]
fn expert_weight_groups_ignores_dense_matmul_and_empty_moe() {
let mut graph = Graph::new();
let dense_w = inline_initializer(&mut graph, "dense_weight");
let dense_in = graph.create_named_value("x", DataType::Float32, shape1(4));
let dense_out = graph.create_named_value("y", DataType::Float32, shape1(4));
graph.insert_node(onnx_runtime_ir::Node::new(
NodeId(0),
"MatMul",
vec![Some(dense_in), Some(dense_w)],
vec![dense_out],
));
let a = graph.create_named_value("a", DataType::Float32, shape1(4));
let b = graph.create_named_value("b", DataType::Float32, shape1(4));
let out2 = graph.create_named_value("out2", DataType::Float32, shape1(4));
let mut empty_qmoe =
onnx_runtime_ir::Node::new(NodeId(0), "QMoE", vec![Some(a), Some(b)], vec![out2]);
empty_qmoe.domain = "com.microsoft".to_string();
graph.insert_node(empty_qmoe);
assert!(expert_weight_groups(&graph).is_empty());
}
#[test]
fn phase3a_device_binding_is_explicitly_unsupported_with_host_route() {
let negotiated = lazy()
.negotiate(&ExecutionProviderCapabilities::nxrt_weight_paging())
.unwrap();
assert_eq!(
negotiated.try_bind_device(&Phase3aHostOnlyBinder),
Err(WeightHandleError::Unsupported(
"live device weight paging is deferred to WEIGHT_OFFLOAD Phase 3b".into()
))
);
assert_eq!(
negotiated.materialize_host_fallback().unwrap().bytes(),
&[1, 2, 3, 4]
);
}
use onnx_runtime_ir::WeightRef;
use onnx_runtime_loader::{
ExpertQuantization, ExpertStorageOrder, ExpertTensorLayout, WeightRegionCatalog,
};
fn expert_layout() -> ExpertTensorLayout {
ExpertTensorLayout {
version: 1,
experts: 3,
rows_per_expert: 2,
storage_elements_per_row: 4,
order: ExpertStorageOrder::ExpertMajor,
quantization: Some(ExpertQuantization {
bits: 4,
block_size: 16,
blocks_per_row: 1,
}),
}
}
fn pageable_catalog() -> WeightRegionCatalog {
let layout = expert_layout();
let weight = WeightRef::External {
path: std::path::PathBuf::from("/nonexistent/weights.bin"),
offset: 16,
length: layout.experts * layout.rows_per_expert * layout.storage_elements_per_row,
dtype: DataType::Uint8,
dims: vec![
layout.experts,
layout.rows_per_expert,
layout.storage_elements_per_row,
],
};
WeightRegionCatalog::classify(&weight, layout)
}
fn non_pageable_catalog() -> WeightRegionCatalog {
let mut layout = expert_layout();
layout.order = ExpertStorageOrder::Interleaved;
let weight = WeightRef::External {
path: std::path::PathBuf::from("/nonexistent/weights.bin"),
offset: 16,
length: layout.experts * layout.rows_per_expert * layout.storage_elements_per_row,
dtype: DataType::Uint8,
dims: vec![
layout.experts,
layout.rows_per_expert,
layout.storage_elements_per_row,
],
};
WeightRegionCatalog::classify(&weight, layout)
}
struct AlwaysSplitPolicy;
impl ResidencyPolicy for AlwaysSplitPolicy {
fn name(&self) -> &'static str {
"test_always_split"
}
fn decide(&self, input: &ResidencyPolicyInput<'_>) -> ResidencyDecision {
if input.catalog.is_pageable() {
ResidencyDecision::PerExpertCandidate {
experts: (0..input.catalog.layout().experts).collect(),
}
} else {
ResidencyDecision::WholeBankResident { reason: None }
}
}
}
struct OutOfRangePolicy;
impl ResidencyPolicy for OutOfRangePolicy {
fn name(&self) -> &'static str {
"test_out_of_range"
}
fn decide(&self, _input: &ResidencyPolicyInput<'_>) -> ResidencyDecision {
ResidencyDecision::PerExpertCandidate {
experts: vec![9999],
}
}
}
struct DuplicatePolicy;
impl ResidencyPolicy for DuplicatePolicy {
fn name(&self) -> &'static str {
"test_duplicate"
}
fn decide(&self, _input: &ResidencyPolicyInput<'_>) -> ResidencyDecision {
ResidencyDecision::PerExpertCandidate {
experts: vec![0, 0],
}
}
}
fn value(id: u32) -> ValueId {
ValueId(id)
}
#[test]
fn whole_bank_resident_policy_matches_default_behavior_for_pageable_catalog() {
let catalog = pageable_catalog();
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&WholeBankResidentPolicy,
None,
);
assert_eq!(plan.policy_name(), "whole_bank_resident");
assert_eq!(plan.len(), 1);
assert_eq!(plan.resident_count(), 1);
assert_eq!(plan.degraded_count(), 0);
assert_eq!(
plan.decision(value(1)),
Some(&ResidencyDecision::WholeBankResident { reason: None })
);
}
#[test]
fn whole_bank_resident_policy_surfaces_non_pageable_reason() {
let catalog = non_pageable_catalog();
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&WholeBankResidentPolicy,
None,
);
assert_eq!(
plan.decision(value(1)),
Some(&ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::NonPageableCatalog(
onnx_runtime_loader::NonPageableReason::NotExpertMajor
))
})
);
}
#[test]
fn alternate_policy_is_substitutable_and_produces_per_expert_candidates() {
let catalog = pageable_catalog();
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&AlwaysSplitPolicy,
None,
);
assert_eq!(plan.policy_name(), "test_always_split");
assert_eq!(
plan.decision(value(1)),
Some(&ResidencyDecision::PerExpertCandidate {
experts: vec![0, 1, 2]
})
);
}
#[test]
fn out_of_range_expert_index_degrades_to_whole_bank_with_reason() {
let catalog = pageable_catalog();
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&OutOfRangePolicy,
None,
);
assert_eq!(plan.resident_count(), 0);
match plan.decision(value(1)) {
Some(ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(_)),
}) => {}
other => panic!("expected rejected validation, got {other:?}"),
}
assert_eq!(plan.degraded_count(), 1);
}
#[test]
fn duplicate_expert_index_degrades_to_whole_bank_with_reason() {
let catalog = pageable_catalog();
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&DuplicatePolicy,
None,
);
match plan.decision(value(1)) {
Some(ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(_)),
}) => {}
other => panic!("expected rejected validation, got {other:?}"),
}
}
#[test]
fn per_expert_candidate_over_non_pageable_catalog_is_rejected() {
let catalog = non_pageable_catalog();
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&AlwaysSplitPolicy,
None,
);
assert!(matches!(
plan.decision(value(1)),
Some(ResidencyDecision::WholeBankResident { .. })
));
}
#[test]
fn plan_residency_orders_values_deterministically() {
let catalog = pageable_catalog();
let plan = plan_residency(
[
(value(5), LazyWeightBoundary::QMoe, &catalog),
(value(1), LazyWeightBoundary::QMoe, &catalog),
(value(3), LazyWeightBoundary::QMoe, &catalog),
],
&WholeBankResidentPolicy,
None,
);
let ordered: Vec<u32> = plan.ordered_values().map(|v| v.0).collect();
assert_eq!(ordered, vec![1, 3, 5]);
}
fn grow_request(bytes: u64) -> ResidencyResizeRequest {
ResidencyResizeRequest {
direction: ResizeDirection::Grow,
target_bytes: bytes,
priority: 0,
}
}
fn shrink_request(bytes: u64) -> ResidencyResizeRequest {
ResidencyResizeRequest {
direction: ResizeDirection::Shrink,
target_bytes: bytes,
priority: 0,
}
}
#[test]
fn plan_resize_accepts_at_a_safe_point() {
let plan = plan_resize(grow_request(1024), ResizeSafePoint::default());
assert_eq!(plan, ResidencyResizePlan::Accepted(grow_request(1024)));
}
#[test]
fn plan_resize_rejects_zero_byte_request_as_noop() {
let plan = plan_resize(grow_request(0), ResizeSafePoint::default());
assert_eq!(
plan,
ResidencyResizePlan::Rejected {
request: grow_request(0),
reason: ResizeRejection::NoOp,
}
);
}
#[test]
fn plan_resize_rejects_during_capture() {
let unsafe_point = ResizeSafePoint {
capturing: true,
..Default::default()
};
let plan = plan_resize(shrink_request(512), unsafe_point);
assert!(matches!(
plan,
ResidencyResizePlan::Rejected {
reason: ResizeRejection::NotSafePoint(_),
..
}
));
}
#[test]
fn plan_resize_rejects_with_pending_deferred_releases() {
let unsafe_point = ResizeSafePoint {
pending_deferred_releases: 3,
..Default::default()
};
let plan = plan_resize(shrink_request(512), unsafe_point);
assert!(matches!(
plan,
ResidencyResizePlan::Rejected {
reason: ResizeRejection::NotSafePoint(_),
..
}
));
}
#[test]
fn plan_resize_rejects_with_admission_in_flight() {
let unsafe_point = ResizeSafePoint {
admission_in_flight: true,
..Default::default()
};
let plan = plan_resize(grow_request(512), unsafe_point);
assert!(matches!(
plan,
ResidencyResizePlan::Rejected {
reason: ResizeRejection::NotSafePoint(_),
..
}
));
}
#[test]
fn plan_resize_fails_closed_under_multi_device() {
let unsafe_point = ResizeSafePoint {
multi_device: true,
..Default::default()
};
let plan = plan_resize(shrink_request(512), unsafe_point);
let ResidencyResizePlan::Rejected {
reason: ResizeRejection::NotSafePoint(reason),
..
} = plan
else {
panic!("multi-device must fail closed, not silently coordinate a resize");
};
assert!(reason.contains("barrier"));
}
#[test]
fn safe_point_blocking_reason_is_deterministic_when_several_conditions_hold() {
let point = ResizeSafePoint {
capturing: true,
pending_deferred_releases: 5,
admission_in_flight: true,
multi_device: true,
routed_guards_active: 1,
};
assert!(!point.is_safe());
assert_eq!(
point.blocking_reason(),
Some("a CUDA graph is currently capturing or replaying")
);
}
#[test]
fn resize_outcome_reports_success_only_without_rejection() {
let success = ResidencyResizeOutcome {
direction: ResizeDirection::Grow,
requested_bytes: 100,
accepted_bytes: 100,
before_bytes: 0,
after_bytes: 100,
rejection: None,
rollback_count: 0,
safe_point: ResizeSafePoint::default(),
};
assert!(success.is_success());
let failure = ResidencyResizeOutcome {
rejection: Some(ResizeRejection::WouldExposeColdExpert),
..success
};
assert!(!failure.is_success());
}
#[test]
fn fused_routing_unknown_always_yields_whole_bank() {
let catalog = pageable_catalog();
let proof =
prove_routed_residency(RoutedResidencyRequirement::FusedRoutingUnknown, &catalog);
assert_eq!(
proof.coverage(),
&RoutedResidencyCoverage::WholeBank {
reason: WholeBankReason::FusedRoutingHasNoHostVisibility
}
);
assert!(proof.blocks_resize());
}
#[test]
fn host_known_experts_over_a_pageable_catalog_yields_exact_sorted_deduped_set() {
let catalog = pageable_catalog();
let proof = prove_routed_residency(
RoutedResidencyRequirement::HostKnownExperts {
experts: vec![2, 0, 0, 1],
},
&catalog,
);
assert_eq!(
proof.coverage(),
&RoutedResidencyCoverage::ExactExperts {
experts: vec![0, 1, 2]
}
);
}
#[test]
fn host_known_experts_over_a_non_pageable_catalog_degrades_to_whole_bank_with_reason() {
let catalog = non_pageable_catalog();
let proof = prove_routed_residency(
RoutedResidencyRequirement::HostKnownExperts { experts: vec![0] },
&catalog,
);
let RoutedResidencyCoverage::WholeBank {
reason: WholeBankReason::InvalidExactSet(reason),
} = proof.coverage()
else {
panic!("a non-pageable catalog must never certify an exact expert set");
};
assert!(reason.contains("not pageable"));
}
#[test]
fn host_known_experts_with_an_out_of_range_index_degrades_to_whole_bank_with_reason() {
let catalog = pageable_catalog();
let proof = prove_routed_residency(
RoutedResidencyRequirement::HostKnownExperts {
experts: vec![0, 99],
},
&catalog,
);
let RoutedResidencyCoverage::WholeBank {
reason: WholeBankReason::InvalidExactSet(reason),
} = proof.coverage()
else {
panic!("an out-of-range expert index must never be certified");
};
assert!(reason.contains("99"));
}
#[test]
fn resize_safe_point_fails_closed_while_a_routed_guard_is_active() {
let point = ResizeSafePoint {
routed_guards_active: 1,
..Default::default()
};
assert!(!point.is_safe());
assert_eq!(
point.blocking_reason(),
Some(
"a RoutedResidencyProof guard is alive and promised its covered region \
set stays resident and unrelocated for its lifetime"
)
);
}
#[test]
fn resize_safe_point_is_safe_with_no_routed_guards() {
let point = ResizeSafePoint {
routed_guards_active: 0,
..Default::default()
};
assert!(point.is_safe());
}
#[test]
fn static_profile_policy_emits_per_expert_candidate_for_profiled_value() {
let catalog = pageable_catalog();
let mut profile = std::collections::HashMap::new();
profile.insert(value(7), vec![2, 0]);
let policy = StaticProfileResidencyPolicy::new(profile);
assert_eq!(policy.profile_len(), 1);
let plan = plan_residency(
[(value(7), LazyWeightBoundary::QMoe, &catalog)],
&policy,
None,
);
assert_eq!(plan.policy_name(), "static_profile");
assert_eq!(
plan.decision(value(7)),
Some(&ResidencyDecision::PerExpertCandidate {
experts: vec![0, 2]
})
);
}
#[test]
fn static_profile_policy_missing_value_falls_back_to_whole_bank() {
let catalog = pageable_catalog();
let policy = StaticProfileResidencyPolicy::new(std::collections::HashMap::new());
let plan = plan_residency(
[(value(1), LazyWeightBoundary::QMoe, &catalog)],
&policy,
None,
);
assert_eq!(
plan.decision(value(1)),
Some(&ResidencyDecision::WholeBankResident { reason: None })
);
}
#[test]
fn static_profile_policy_empty_entry_is_treated_as_missing() {
let catalog = pageable_catalog();
let policy = StaticProfileResidencyPolicy::default()
.with_entry(value(3), vec![])
.with_entry(value(4), vec![1]);
assert_eq!(policy.profile_len(), 1);
let plan = plan_residency(
[
(value(3), LazyWeightBoundary::QMoe, &catalog),
(value(4), LazyWeightBoundary::QMoe, &catalog),
],
&policy,
None,
);
assert!(matches!(
plan.decision(value(3)),
Some(&ResidencyDecision::WholeBankResident { .. })
));
assert!(matches!(
plan.decision(value(4)),
Some(&ResidencyDecision::PerExpertCandidate { .. })
));
}
#[test]
fn static_profile_policy_out_of_range_expert_degrades_via_validation() {
let catalog = pageable_catalog();
let policy = StaticProfileResidencyPolicy::default().with_entry(value(9), vec![9999]);
let plan = plan_residency(
[(value(9), LazyWeightBoundary::QMoe, &catalog)],
&policy,
None,
);
assert!(matches!(
plan.decision(value(9)),
Some(&ResidencyDecision::WholeBankResident {
reason: Some(ResidencyDegradationReason::RejectedByValidation(_))
})
));
}
}