Skip to main content

aisimulate_core/perfmodel/common/
error.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Crate-wide error type.
5//!
6//! `lib.rs` re-exports `AicError` so the FFI surface and other callers can
7//! use it without depending on this module path. The operator-layer
8//! `PerformanceResult` companion type lives in `operators/base.rs`.
9
10use std::path::PathBuf;
11
12use thiserror::Error;
13
14/// All errors surfaced by the Rust core.
15#[derive(Debug, Error)]
16pub enum AicError {
17    #[error("unsupported schema version for {kind}: got {got}, expected {expected}")]
18    UnsupportedSchemaVersion {
19        kind: &'static str,
20        got: u32,
21        expected: u32,
22    },
23    #[error("invalid engine config: {0}")]
24    InvalidEngineConfig(String),
25    #[error("engine spec wire-format error: {0}")]
26    EngineSpec(String),
27    #[error("invalid forward pass metrics: {0}")]
28    InvalidForwardPassMetrics(String),
29    #[error("unsupported model for Rust core estimator: {0}")]
30    UnsupportedModel(String),
31    #[error("failed to find AIC data roots: {0}")]
32    DataRoot(String),
33    #[error("model config error: {0}")]
34    ModelConfig(String),
35    #[error("perf database error: {0}")]
36    PerfDatabase(String),
37    /// A quant mode's compute dtype has no `*_tc_flops` entry in the system
38    /// YAML. Mirrors Python's `MissingSystemFlopsError`: the platform either
39    /// lacks hardware for that dtype or the YAML is incomplete — never
40    /// extrapolate a fictional throughput from bf16.
41    #[error("missing system flops: {0}")]
42    MissingSystemFlops(String),
43    /// The HYBRID/EMPIRICAL path found no calibration data for the requested
44    /// slice — no own-shape, cross-shape, or sibling transfer reference.
45    /// Mirrors Python's `EmpiricalNotImplementedError`: a coverage gap, never
46    /// converted into a fabricated `SOL / constant` value.
47    #[error("empirical estimation not implemented: {0}")]
48    EmpiricalNotImplemented(String),
49    /// The analytic SOL path cannot represent an operator required by the
50    /// requested estimate. Mirrors Python's `SolNotImplementedError` so an
51    /// optional SOL comparison can distinguish a coverage gap from an invalid
52    /// configuration or a programming error.
53    #[error("SOL estimation not implemented: {0}")]
54    SolNotImplemented(String),
55    #[error("I/O error at {path}: {source}")]
56    Io {
57        path: PathBuf,
58        #[source]
59        source: std::io::Error,
60    },
61    #[error("YAML error at {path}: {source}")]
62    Yaml {
63        path: PathBuf,
64        #[source]
65        source: serde_yaml::Error,
66    },
67    #[error("Parquet error at {path}: {source}")]
68    Parquet {
69        path: PathBuf,
70        #[source]
71        source: parquet::errors::ParquetError,
72    },
73}
74
75impl AicError {
76    /// The "missing silicon data" class that HYBRID converts into an
77    /// empirical estimate. Mirrors Python's
78    /// `_MISSING_SILICON_DATA_EXCEPTIONS` (`PerfDataNotAvailableError`,
79    /// `InterpolationDataNotAvailableError`) — the same set `Op::Fallback`
80    /// catches. `EmpiricalNotImplemented` is deliberately NOT in this set:
81    /// it is the terminal miss raised after the empirical path itself found
82    /// no calibration data.
83    pub fn is_missing_perf_data(&self) -> bool {
84        matches!(self, Self::PerfDatabase(_) | Self::Io { .. })
85    }
86}