Skip to main content

tenferro_runtime/graph/
program.rs

1use tenferro_ops::input_key::TensorInputKey;
2
3use crate::compiler::CompilerOptions;
4use crate::program::{FrozenProgram, ProgramBindings, SemanticProgram};
5
6/// A backend-neutral compiled semantic graph with runtime-private execution staging.
7///
8/// Public consumers inspect only the immutable semantic program and its
9/// process-local tensor bindings. Native execution staging remains owned by
10/// `tenferro-runtime` and is removed in Phase 5.
11#[derive(Clone)]
12pub struct CompiledGraph {
13    pub(crate) frozen: FrozenProgram,
14    pub(crate) compiler_options: CompilerOptions,
15    pub(crate) input_keys: Box<[TensorInputKey]>,
16}
17
18impl CompiledGraph {
19    pub(crate) fn new(
20        frozen: FrozenProgram,
21        compiler_options: CompilerOptions,
22        input_keys: impl Into<Box<[TensorInputKey]>>,
23    ) -> Self {
24        Self {
25            frozen,
26            compiler_options,
27            input_keys: input_keys.into(),
28        }
29    }
30
31    #[allow(
32        dead_code,
33        reason = "Phase 5 runtime-owned execution consumes compiled frozen programs"
34    )]
35    pub(crate) fn frozen(&self) -> &FrozenProgram {
36        &self.frozen
37    }
38
39    /// Borrow the frozen semantic program and its bindings.
40    #[doc(hidden)]
41    pub fn frozen_program(&self) -> &FrozenProgram {
42        &self.frozen
43    }
44
45    pub(crate) fn compiler_options(&self) -> CompilerOptions {
46        self.compiler_options
47    }
48
49    /// Borrow the immutable backend-neutral semantic program.
50    pub fn program(&self) -> &SemanticProgram {
51        &self.frozen.program
52    }
53
54    /// Borrow tensor defaults and large constants kept outside semantic structure.
55    pub fn bindings(&self) -> &ProgramBindings {
56        &self.frozen.bindings
57    }
58
59    /// Return the number of ordered semantic inputs.
60    pub fn input_count(&self) -> usize {
61        self.frozen.program.inputs().len()
62    }
63
64    /// Borrow ordered trace input keys corresponding to semantic input order.
65    #[doc(hidden)]
66    pub fn input_keys(&self) -> &[TensorInputKey] {
67        &self.input_keys
68    }
69
70    /// Return the semantic input index for a trace input key.
71    #[doc(hidden)]
72    pub fn input_key_index(&self, key: &TensorInputKey) -> Option<usize> {
73        self.input_keys
74            .iter()
75            .position(|candidate| candidate == key)
76    }
77
78    /// Return the number of ordered semantic outputs.
79    pub fn output_count(&self) -> usize {
80        self.frozen.program.outputs().len()
81    }
82}
83
84impl std::fmt::Debug for CompiledGraph {
85    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        formatter
87            .debug_struct("CompiledGraph")
88            .field("inputs", &self.input_count())
89            .field("outputs", &self.output_count())
90            .field("input_keys", &self.input_keys.len())
91            .field("bindings", &self.bindings().len())
92            .field(
93                "semantic_fingerprint",
94                &self.program().semantic_fingerprint(),
95            )
96            .finish()
97    }
98}