Skip to main content

tokitai_dl/
lib.rs

1//! # tokitai-dl
2//!
3//! An **additive** bridge crate connecting two deep-learning libraries:
4//!
5//! - `tokitai-operator` — a DL kernel compiler with selected formally checked
6//!   kernels and theorem bindings. Edition 2024. Paper-artifact grade.
7//! - `god-graph` — a DL model analysis toolbox (differentiable structures, VGI, CAD-LLM, Safetensors I/O). Edition 2021. v0.6.0-alpha.
8//!
9//! ## What this crate does
10//!
11//! Treats a `tokitai_operator::ir::SemanticGraph` (an operator DAG) as a
12//! `god_graph::graph::Graph<String, ()>` so that god-graph's algorithm library
13//! — BFS, DFS, topological sort, connected components, MST, PageRank, shortest
14//! path, etc. — can inspect the operator DAG shape. This is graph analysis, not
15//! a new proof that those algorithms or their outputs are formally verified.
16//!
17//! ## What this crate does NOT do
18//!
19//! - It does not modify `tokitai-operator` (paper-artifact claim boundary is closed).
20//! - It does not modify `god-graph` (v0.6 release cadence is independent).
21//! - It does not require a workspace root Cargo.toml.
22//! - It does not bump either crate's edition.
23//! - It does not re-export `pub use` from either crate; types are referenced by full path.
24//!
25//! ## Features
26//!
27//! | Feature     | Brings in                              |
28//! |-------------|----------------------------------------|
29//! | `graph`     | god-graph (default-features = false)   |
30//! | `operator`  | tokitai-operator                        |
31//! | `llm`       | god-graph Safetensors loader; use with `operator` for `llm_bridge` |
32//!
33//! Default features are empty. This is also the docs.rs-safe baseline because it
34//! avoids optional dependencies such as the local-development
35//! `tokitai-operator` sibling path dependency.
36//!
37//! ## Quickstart
38//!
39//! ```rust
40//! # #[cfg(all(feature = "graph", feature = "operator"))]
41//! use tokitai_dl::op_dag_graph::semantic_to_god_graph;
42//! ```
43
44#![deny(missing_docs)]
45#![warn(rust_2018_idioms)]
46#![forbid(unsafe_code)]
47
48#[cfg(feature = "operator")]
49pub mod op_dag_graph;
50
51#[cfg(feature = "operator")]
52pub mod sheaf_partitioner;
53
54#[cfg(all(feature = "graph", feature = "operator"))]
55pub mod witness_bridge;
56
57#[cfg(all(feature = "graph", feature = "operator"))]
58pub mod cad_bridge;
59
60#[cfg(all(feature = "graph", feature = "operator"))]
61pub mod lean_proof_bridge;
62
63#[cfg(all(feature = "llm", feature = "operator"))]
64pub mod llm_bridge;
65
66/// Errors that the bridge's adapter functions can return.
67///
68/// The `Unsupported` arm is used when an input is a variant we
69/// explicitly don't know how to map (currently reserved for
70/// future `EditOperation::Custom` / `DefectType::Custom`).
71/// The `Upstream` arm wraps a god-graph error (e.g. a failed
72/// Safetensors load). The `Io` arm wraps a std::io error.
73///
74/// # Example
75///
76/// ```rust
77/// # #[cfg(all(feature = "graph", feature = "operator"))]
78/// # fn demo() {
79/// use tokitai_dl::BridgeError;
80/// // Pattern-match on the variant to recover the underlying cause.
81/// let err = BridgeError::Upstream("safetensors header malformed".to_string());
82/// match err {
83///     BridgeError::Unsupported(msg)  => println!("unsupported: {msg}"),
84///     BridgeError::Upstream(msg)     => println!("upstream: {msg}"),
85///     BridgeError::Io(msg)           => println!("io: {msg}"),
86///     BridgeError::Context { source, context } => println!("{context}: {source}"),
87/// }
88/// # }
89/// ```
90#[cfg(all(feature = "graph", feature = "operator"))]
91#[derive(Debug, Clone, PartialEq, Eq)]
92pub enum BridgeError {
93    /// The input is a variant we explicitly don't know how to map.
94    /// Currently reserved for `EditOperation::Custom` / `DefectType::Custom`.
95    ///
96    /// # No example
97    ///
98    /// `Unsupported` is the *catch-all* arm that the bridge reserves
99    /// for future input variants. It is currently never constructed
100    /// by the bridge, so a runnable example would have no realistic
101    /// call site. Constructing one by hand (`BridgeError::Unsupported("x".into())`)
102    /// is the intended downstream use, but adds no testable value
103    /// over the source code itself.
104    Unsupported(String),
105    /// An upstream crate (god-graph) returned an error. The string
106    /// carries the formatted upstream error so downstream code can
107    /// still log / report it.
108    Upstream(String),
109    /// A `std::io` error occurred (file open, read, etc.). The
110    /// string carries the formatted error.
111    Io(String),
112    /// An error wrapped with caller-supplied context. The `source` is the
113    /// original error; the `context` is a human-readable string the caller
114    /// attached (e.g. "while loading model 'foo.safetensors'").
115    Context {
116        /// The underlying error.
117        source: Box<BridgeError>,
118        /// Caller-supplied context. Displayed alongside the source in
119        /// the outer Display impl.
120        context: String,
121    },
122}
123
124#[cfg(all(feature = "graph", feature = "operator"))]
125impl BridgeError {
126    /// Wrap `self` with caller-supplied context, producing a
127    /// `Context { source, context }` variant. Useful for attaching
128    /// high-level context (e.g. which file was being processed) to a
129    /// lower-level error from one of the bridge adapters.
130    pub fn with_context(self, ctx: impl Into<String>) -> Self {
131        Self::Context {
132            source: Box::new(self),
133            context: ctx.into(),
134        }
135    }
136}
137
138#[cfg(all(feature = "graph", feature = "operator"))]
139impl std::fmt::Display for BridgeError {
140    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141        match self {
142            Self::Unsupported(msg) => write!(f, "unsupported bridge input: {msg}"),
143            Self::Upstream(msg) => write!(f, "upstream error: {msg}"),
144            Self::Io(msg) => write!(f, "io error: {msg}"),
145            Self::Context { source, context } => write!(f, "{context}: {source}"),
146        }
147    }
148}
149
150#[cfg(all(feature = "graph", feature = "operator"))]
151impl std::error::Error for BridgeError {
152    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
153        match self {
154            Self::Context { source, .. } => Some(source.as_ref()),
155            _ => None,
156        }
157    }
158}
159
160#[cfg(all(test, feature = "graph", feature = "operator"))]
161mod bridge_error_tests {
162    use super::BridgeError;
163    #[test]
164    fn context_wraps_underlying() {
165        let inner = BridgeError::Upstream("header malformed".into());
166        let outer = inner.with_context("while loading model 'foo.safetensors'");
167        match &outer {
168            BridgeError::Context { source, context } => {
169                assert_eq!(context, "while loading model 'foo.safetensors'");
170                assert!(matches!(source.as_ref(), BridgeError::Upstream(_)));
171            }
172            _ => panic!("expected Context variant"),
173        }
174        let chain: String = outer.to_string();
175        assert!(chain.contains("loading model"));
176        assert!(chain.contains("header malformed"));
177    }
178}