1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! Immutable backend-neutral semantic programs.
//!
//! Semantic structure freezes separately from tensor defaults and large
//! constants. Builder-issued values and binding keys are opaque and scoped to
//! one builder/program.
//!
//! # Build, bind, freeze, query, and import
//!
//! ```
//! use std::sync::Arc;
//! use tenferro_ops::dim_expr::DimExpr;
//! use tenferro_runtime::program::{
//! CoreSemanticOp, ProgramInputSpec, ProgramQueryError, ProgramImport,
//! SemanticProgramBuilder,
//! };
//! use tenferro_tensor::{DType, Tensor};
//!
//! let mut builder = SemanticProgramBuilder::new();
//! let input = builder.input(ProgramInputSpec::new(
//! DType::F64,
//! [DimExpr::Const(2)],
//! ))?;
//! let key = builder.bind_input(
//! input,
//! Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0])?,
//! )?;
//! let output = builder.add_op(CoreSemanticOp::Neg, &[input])?[0];
//! let frozen = builder.finish(&[output])?;
//! assert_eq!(frozen.bindings.iter().count(), 1);
//! assert!(frozen.bindings.get(key).is_some());
//! assert_eq!(frozen.program.semantic_fingerprint().as_bytes().len(), 16);
//!
//! let mut other = SemanticProgramBuilder::new();
//! let foreign = other.input(ProgramInputSpec::new(
//! DType::F64,
//! [DimExpr::Const(2)],
//! ))?;
//! assert_eq!(
//! frozen.program.value_metadata(foreign),
//! Err(ProgramQueryError::ForeignValue),
//! );
//!
//! let mut destination = SemanticProgramBuilder::new();
//! let imported = destination.import(ProgramImport {
//! program: frozen.program.as_ref(),
//! bindings: &frozen.bindings,
//! roots: frozen.program.outputs(),
//! })?;
//! let roundtrip = destination.finish(imported.roots())?;
//! assert!(frozen.program.semantic_eq(roundtrip.program.as_ref()));
//! assert_eq!(roundtrip.bindings.len(), 1);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Opaque identities
//!
//! Raw slots and builder nonces are deliberately inaccessible.
//!
//! ```compile_fail
//! use tenferro_runtime::program::ProgramValue;
//! fn raw_slot(value: ProgramValue) -> u32 {
//! value.slot
//! }
//! ```
//!
//! ```compile_fail
//! use tenferro_runtime::program::BindingKey;
//! fn raw_slot(key: BindingKey) -> u32 {
//! key.slot
//! }
//! ```
//!
//! Frozen operation views expose immutable slices only.
//!
//! ```compile_fail
//! use tenferro_runtime::program::SemanticOperationView;
//! fn mutate(view: SemanticOperationView<'_>) {
//! view.outputs()[0] = view.inputs()[0];
//! }
//! ```
//!
//! Structured control flow is a typed unsupported case until the reserved
//! region/block model is implemented.
//!
//! ```
//! use tenferro_runtime::program::ProgramBuildError;
//! let error = ProgramBuildError::UnsupportedControlFlow { construct: "while" };
//! assert!(matches!(
//! error,
//! ProgramBuildError::UnsupportedControlFlow { construct: "while" }
//! ));
//! ```
pub use ProgramBindings;
pub use SemanticProgramBuilder;
pub use ;
pub use SemanticFingerprint;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;