rustd_runtime/
lib.rs

1//! # HLX Runtime
2//! 
3//! Deterministic execution engine for LC-B crates.
4//! 
5//! ## Architecture
6//! 
7//! ```text
8//! LC-B Crate
9//!      │
10//!      ▼
11//! ┌─────────────────┐
12//! │  Runtime        │
13//! │  ┌───────────┐  │
14//! │  │ Validator │  │  ← Integrity check (BLAKE3)
15//! │  └───────────┘  │
16//! │       │         │
17//! │       ▼         │
18//! │  ┌───────────┐  │
19//! │  │ Executor  │  │  ← Instruction dispatch
20//! │  └───────────┘  │
21//! │       │         │
22//! │       ▼         │
23//! │  ┌───────────┐  │
24//! │  │ Backend   │◄─┼── CPU (ndarray) | Vulkan (SPIR-V)
25//! │  └───────────┘  │
26//! └─────────────────┘
27//!      │
28//!      ▼
29//!   Result (Value)
30//! ```
31//! 
32//! ## Determinism Guarantees
33//! 
34//! 1. Same crate + same config = same result
35//! 2. Fixed workgroup sizes on GPU
36//! 3. Deterministic reduction order
37//! 4. No dynamic memory allocation during execution
38
39pub mod config;
40pub mod backend;
41pub mod executor;
42pub mod value_store;
43pub mod tuning;
44pub mod speculation;
45
46#[cfg(feature = "cpu")]
47pub mod backends;
48
49pub use config::RuntimeConfig;
50pub use backend::Backend;
51pub use executor::Executor;
52pub use value_store::ValueStore;
53pub use speculation::{SpeculationCoordinator, SpeculationConfig, AgentState, BarrierCoordinator};
54
55use rustd_core::{RustDCrate, Value, Result};
56use std::cell::{Cell, RefCell};
57use std::sync::Arc;
58
59thread_local! {
60    /// Thread-local flag to disable speculation (prevents infinite recursion)
61    static SPECULATION_DISABLED: Cell<bool> = Cell::new(false);
62
63    /// Thread-local barrier coordinator for speculation agents
64    static BARRIER_COORDINATOR: RefCell<Option<Arc<BarrierCoordinator>>> = RefCell::new(None);
65
66    /// Thread-local agent ID for speculation agents
67    static AGENT_ID: Cell<Option<usize>> = Cell::new(None);
68}
69
70/// Check if speculation is disabled for this thread
71pub(crate) fn is_speculation_disabled() -> bool {
72    SPECULATION_DISABLED.with(|d| d.get())
73}
74
75/// Disable speculation for this thread (used by speculation agents)
76pub(crate) fn disable_speculation() {
77    SPECULATION_DISABLED.with(|d| d.set(true));
78}
79
80/// Set barrier coordinator for this thread (used by speculation agents)
81pub(crate) fn set_barrier_coordinator(coordinator: Option<Arc<BarrierCoordinator>>, agent_id: Option<usize>) {
82    BARRIER_COORDINATOR.with(|c| *c.borrow_mut() = coordinator);
83    AGENT_ID.with(|id| id.set(agent_id));
84}
85
86/// Get barrier coordinator for this thread
87pub(crate) fn get_barrier_coordinator() -> Option<Arc<BarrierCoordinator>> {
88    BARRIER_COORDINATOR.with(|c| c.borrow().clone())
89}
90
91/// Get agent ID for this thread
92pub(crate) fn get_agent_id() -> Option<usize> {
93    AGENT_ID.with(|id| id.get())
94}
95
96/// Execute a crate with default configuration
97pub fn execute(krate: &RustDCrate) -> Result<Value> {
98    let config = RuntimeConfig::default();
99    execute_with_config(krate, &config)
100}
101
102/// High-level entry point to execute a crate with specific config
103pub fn execute_with_config(krate: &RustDCrate, config: &RuntimeConfig) -> Result<Value> {
104    let mut executor = Executor::new(config)?;
105    executor.run(krate)
106}
107
108/// Quick test: 5 + 3 = 8
109#[cfg(test)]
110mod smoke_tests {
111    use super::*;
112    use rustd_core::{RustDCrate, Instruction, Value};
113
114    #[test]
115    fn test_basic_addition() {
116        // 🜃5 + 🜃3 = 8
117        let krate = RustDCrate::new(vec![
118            Instruction::Constant { out: 0, val: Value::Integer(5) },
119            Instruction::Constant { out: 1, val: Value::Integer(3) },
120            Instruction::Add { out: 2, lhs: 0, rhs: 1 },
121            Instruction::Return { val: 2 },
122        ]);
123        
124        let result = execute(&krate).unwrap();
125        assert_eq!(result, Value::Integer(8));
126    }
127
128    #[test]
129    fn test_determinism() {
130        let krate = RustDCrate::new(vec![
131            Instruction::Constant { out: 0, val: Value::Integer(42) },
132            Instruction::Constant { out: 1, val: Value::Integer(10) },
133            Instruction::Mul { out: 2, lhs: 0, rhs: 1 },
134            Instruction::Return { val: 2 },
135        ]);
136        
137        // Run 100 times
138        let results: Vec<_> = (0..100)
139            .map(|_| execute(&krate).unwrap())
140            .collect();
141        
142        // All must be identical
143        assert!(results.iter().all(|r| *r == Value::Integer(420)));
144    }
145
146    #[test]
147    fn test_crate_validation() {
148        let mut krate = RustDCrate::new(vec![
149            Instruction::Constant { out: 0, val: Value::Integer(1) },
150        ]);
151        
152        // Tamper with hash
153        krate.hash[0] ^= 0xFF;
154        
155        // Should fail validation
156        assert!(execute(&krate).is_err());
157    }
158}