exo_core/
thermodynamics.rs

1//! Landauer's Principle and Thermodynamic Efficiency Tracking
2//!
3//! This module implements thermodynamic efficiency metrics based on
4//! Landauer's principle - the fundamental limit of computation.
5//!
6//! # Landauer's Principle
7//!
8//! Minimum energy to erase one bit of information at temperature T:
9//! ```text
10//! E_min = k_B * T * ln(2)
11//! ```
12//!
13//! At room temperature (300K):
14//! - E_min ≈ 0.018 eV ≈ 2.9 × 10⁻²¹ J per bit
15//!
16//! # Current State of Computing
17//!
18//! - Modern CMOS: ~1000× above Landauer limit
19//! - Biological neurons: ~10× above Landauer limit
20//! - Reversible computing: Potential 4000× improvement
21//!
22//! # Usage
23//!
24//! ```rust,ignore
25//! use exo_core::thermodynamics::{ThermodynamicTracker, Operation};
26//!
27//! let tracker = ThermodynamicTracker::new(300.0); // Room temperature
28//!
29//! tracker.record_operation(Operation::BitErasure { count: 1000 });
30//! tracker.record_operation(Operation::VectorSimilarity { dimensions: 384 });
31//!
32//! let report = tracker.efficiency_report();
33//! println!("Efficiency ratio: {}x above Landauer", report.efficiency_ratio);
34//! ```
35
36use std::sync::atomic::{AtomicU64, Ordering};
37use std::sync::Arc;
38
39/// Boltzmann constant in joules per kelvin
40pub const BOLTZMANN_K: f64 = 1.380649e-23;
41
42/// Electron volt in joules
43pub const EV_TO_JOULES: f64 = 1.602176634e-19;
44
45/// Landauer limit at room temperature (300K) in joules
46pub const LANDAUER_LIMIT_300K: f64 = 2.87e-21; // k_B * T * ln(2)
47
48/// Landauer limit at room temperature in electron volts
49pub const LANDAUER_LIMIT_300K_EV: f64 = 0.0179; // ~0.018 eV
50
51/// Compute Landauer limit for a given temperature
52///
53/// # Arguments
54/// * `temperature_kelvin` - Temperature in Kelvin
55///
56/// # Returns
57/// * Minimum energy per bit erasure in joules
58pub fn landauer_limit(temperature_kelvin: f64) -> f64 {
59    BOLTZMANN_K * temperature_kelvin * std::f64::consts::LN_2
60}
61
62/// Types of computational operations for energy tracking
63#[derive(Debug, Clone, Copy)]
64pub enum Operation {
65    /// Bit erasure (irreversible operation)
66    BitErasure { count: u64 },
67
68    /// Bit copy (theoretically reversible)
69    BitCopy { count: u64 },
70
71    /// Vector similarity computation
72    VectorSimilarity { dimensions: usize },
73
74    /// Matrix-vector multiplication
75    MatrixVectorMultiply { rows: usize, cols: usize },
76
77    /// Neural network forward pass
78    NeuralForward { parameters: u64 },
79
80    /// Memory read (near-reversible)
81    MemoryRead { bytes: u64 },
82
83    /// Memory write (includes erasure)
84    MemoryWrite { bytes: u64 },
85
86    /// HNSW graph traversal
87    GraphTraversal { hops: u64 },
88
89    /// Custom operation with known bit erasures
90    Custom { bit_erasures: u64 },
91}
92
93impl Operation {
94    /// Estimate the number of bit erasures for this operation
95    ///
96    /// These are rough estimates based on typical implementations.
97    /// Actual values depend on hardware and implementation details.
98    pub fn estimated_bit_erasures(&self) -> u64 {
99        match self {
100            Operation::BitErasure { count } => *count,
101            Operation::BitCopy { count } => *count / 10, // Mostly reversible
102            Operation::VectorSimilarity { dimensions } => {
103                // ~32 ops per dimension, ~1 erasure per op
104                (*dimensions as u64) * 32
105            }
106            Operation::MatrixVectorMultiply { rows, cols } => {
107                // 2*N*M ops for NxM matrix
108                (*rows as u64) * (*cols as u64) * 2
109            }
110            Operation::NeuralForward { parameters } => {
111                // ~2 erasures per parameter (multiply-accumulate)
112                parameters * 2
113            }
114            Operation::MemoryRead { bytes } => {
115                // Mostly reversible, small overhead
116                bytes * 8 / 100
117            }
118            Operation::MemoryWrite { bytes } => {
119                // Write = read + erase old + write new
120                bytes * 8 * 2
121            }
122            Operation::GraphTraversal { hops } => {
123                // ~10 comparisons per hop
124                hops * 10
125            }
126            Operation::Custom { bit_erasures } => *bit_erasures,
127        }
128    }
129}
130
131/// Energy estimate for an operation
132#[derive(Debug, Clone, Copy)]
133pub struct EnergyEstimate {
134    /// Theoretical minimum (Landauer limit)
135    pub landauer_minimum_joules: f64,
136
137    /// Estimated actual energy (current technology)
138    pub estimated_actual_joules: f64,
139
140    /// Efficiency ratio (actual / minimum)
141    pub efficiency_ratio: f64,
142
143    /// Number of bit erasures
144    pub bit_erasures: u64,
145}
146
147/// Thermodynamic efficiency tracker
148///
149/// Tracks computational operations and calculates energy efficiency
150/// relative to the Landauer limit.
151pub struct ThermodynamicTracker {
152    /// Operating temperature in Kelvin
153    temperature: f64,
154
155    /// Landauer limit at operating temperature
156    landauer_limit: f64,
157
158    /// Total bit erasures recorded
159    total_erasures: Arc<AtomicU64>,
160
161    /// Total operations recorded
162    total_operations: Arc<AtomicU64>,
163
164    /// Assumed efficiency multiplier above Landauer (typical: 1000x for CMOS)
165    technology_multiplier: f64,
166}
167
168impl ThermodynamicTracker {
169    /// Create a new tracker at the specified temperature
170    ///
171    /// # Arguments
172    /// * `temperature_kelvin` - Operating temperature (default: 300K room temp)
173    pub fn new(temperature_kelvin: f64) -> Self {
174        Self {
175            temperature: temperature_kelvin,
176            landauer_limit: landauer_limit(temperature_kelvin),
177            total_erasures: Arc::new(AtomicU64::new(0)),
178            total_operations: Arc::new(AtomicU64::new(0)),
179            technology_multiplier: 1000.0, // Current CMOS ~1000x above limit
180        }
181    }
182
183    /// Create a tracker at room temperature (300K)
184    pub fn room_temperature() -> Self {
185        Self::new(300.0)
186    }
187
188    /// Set the technology multiplier
189    ///
190    /// - CMOS 2024: ~1000x
191    /// - Biological: ~10x
192    /// - Reversible (theoretical): ~1x
193    /// - Future neuromorphic: ~100x
194    pub fn with_technology_multiplier(mut self, multiplier: f64) -> Self {
195        self.technology_multiplier = multiplier;
196        self
197    }
198
199    /// Record an operation
200    pub fn record_operation(&self, operation: Operation) {
201        let erasures = operation.estimated_bit_erasures();
202        self.total_erasures.fetch_add(erasures, Ordering::Relaxed);
203        self.total_operations.fetch_add(1, Ordering::Relaxed);
204    }
205
206    /// Estimate energy for an operation
207    pub fn estimate_energy(&self, operation: Operation) -> EnergyEstimate {
208        let bit_erasures = operation.estimated_bit_erasures();
209        let landauer_minimum = (bit_erasures as f64) * self.landauer_limit;
210        let estimated_actual = landauer_minimum * self.technology_multiplier;
211
212        EnergyEstimate {
213            landauer_minimum_joules: landauer_minimum,
214            estimated_actual_joules: estimated_actual,
215            efficiency_ratio: self.technology_multiplier,
216            bit_erasures,
217        }
218    }
219
220    /// Get total bit erasures recorded
221    pub fn total_erasures(&self) -> u64 {
222        self.total_erasures.load(Ordering::Relaxed)
223    }
224
225    /// Get total operations recorded
226    pub fn total_operations(&self) -> u64 {
227        self.total_operations.load(Ordering::Relaxed)
228    }
229
230    /// Calculate total theoretical minimum energy (Landauer limit)
231    pub fn total_landauer_minimum(&self) -> f64 {
232        (self.total_erasures() as f64) * self.landauer_limit
233    }
234
235    /// Calculate estimated actual energy usage
236    pub fn total_estimated_energy(&self) -> f64 {
237        self.total_landauer_minimum() * self.technology_multiplier
238    }
239
240    /// Generate an efficiency report
241    pub fn efficiency_report(&self) -> EfficiencyReport {
242        let total_erasures = self.total_erasures();
243        let landauer_minimum = self.total_landauer_minimum();
244        let estimated_actual = self.total_estimated_energy();
245
246        // Calculate potential savings with reversible computing
247        let reversible_potential = estimated_actual - landauer_minimum;
248
249        EfficiencyReport {
250            temperature_kelvin: self.temperature,
251            landauer_limit_per_bit: self.landauer_limit,
252            total_bit_erasures: total_erasures,
253            total_operations: self.total_operations(),
254            landauer_minimum_joules: landauer_minimum,
255            landauer_minimum_ev: landauer_minimum / EV_TO_JOULES,
256            estimated_actual_joules: estimated_actual,
257            efficiency_ratio: self.technology_multiplier,
258            reversible_savings_potential: reversible_potential,
259            reversible_improvement_factor: self.technology_multiplier,
260        }
261    }
262
263    /// Reset all counters
264    pub fn reset(&self) {
265        self.total_erasures.store(0, Ordering::Relaxed);
266        self.total_operations.store(0, Ordering::Relaxed);
267    }
268}
269
270impl Default for ThermodynamicTracker {
271    fn default() -> Self {
272        Self::room_temperature()
273    }
274}
275
276/// Efficiency report
277#[derive(Debug, Clone)]
278pub struct EfficiencyReport {
279    /// Operating temperature
280    pub temperature_kelvin: f64,
281
282    /// Landauer limit per bit at operating temperature
283    pub landauer_limit_per_bit: f64,
284
285    /// Total irreversible bit erasures
286    pub total_bit_erasures: u64,
287
288    /// Total operations tracked
289    pub total_operations: u64,
290
291    /// Theoretical minimum energy (Landauer limit)
292    pub landauer_minimum_joules: f64,
293
294    /// Landauer minimum in electron volts
295    pub landauer_minimum_ev: f64,
296
297    /// Estimated actual energy with current technology
298    pub estimated_actual_joules: f64,
299
300    /// How many times above Landauer limit
301    pub efficiency_ratio: f64,
302
303    /// Potential energy savings with reversible computing
304    pub reversible_savings_potential: f64,
305
306    /// Improvement factor possible with reversible computing
307    pub reversible_improvement_factor: f64,
308}
309
310impl std::fmt::Display for EfficiencyReport {
311    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
312        writeln!(f, "=== Thermodynamic Efficiency Report ===")?;
313        writeln!(f, "Temperature: {:.1}K", self.temperature_kelvin)?;
314        writeln!(f, "Landauer limit: {:.2e} J/bit", self.landauer_limit_per_bit)?;
315        writeln!(f)?;
316        writeln!(f, "Operations tracked: {}", self.total_operations)?;
317        writeln!(f, "Total bit erasures: {}", self.total_bit_erasures)?;
318        writeln!(f)?;
319        writeln!(f, "Theoretical minimum: {:.2e} J ({:.2e} eV)",
320            self.landauer_minimum_joules, self.landauer_minimum_ev)?;
321        writeln!(f, "Estimated actual:   {:.2e} J", self.estimated_actual_joules)?;
322        writeln!(f, "Efficiency ratio:   {:.0}× above Landauer", self.efficiency_ratio)?;
323        writeln!(f)?;
324        writeln!(f, "Reversible computing potential:")?;
325        writeln!(f, "  - Savings: {:.2e} J ({:.1}%)",
326            self.reversible_savings_potential,
327            (self.reversible_savings_potential / self.estimated_actual_joules) * 100.0)?;
328        writeln!(f, "  - Improvement factor: {:.0}×", self.reversible_improvement_factor)?;
329        Ok(())
330    }
331}
332
333/// Technology profiles for different computing paradigms
334pub mod technology_profiles {
335    /// Current CMOS technology (~1000× above Landauer)
336    pub const CMOS_2024: f64 = 1000.0;
337
338    /// Biological neurons (~10× above Landauer)
339    pub const BIOLOGICAL: f64 = 10.0;
340
341    /// Future neuromorphic (~100× above Landauer)
342    pub const NEUROMORPHIC_PROJECTED: f64 = 100.0;
343
344    /// Reversible computing (approaching 1× limit)
345    pub const REVERSIBLE_IDEAL: f64 = 1.0;
346
347    /// Near-term reversible (~10× above Landauer)
348    pub const REVERSIBLE_2028: f64 = 10.0;
349
350    /// Superconducting qubits (cold, but higher per operation)
351    pub const SUPERCONDUCTING: f64 = 100.0;
352}
353
354#[cfg(test)]
355mod tests {
356    use super::*;
357
358    #[test]
359    fn test_landauer_limit_room_temp() {
360        let limit = landauer_limit(300.0);
361        // Should be approximately 2.87e-21 J
362        assert!((limit - 2.87e-21).abs() < 1e-22);
363    }
364
365    #[test]
366    fn test_tracker_operations() {
367        let tracker = ThermodynamicTracker::room_temperature();
368
369        tracker.record_operation(Operation::BitErasure { count: 1000 });
370        tracker.record_operation(Operation::VectorSimilarity { dimensions: 384 });
371
372        assert_eq!(tracker.total_operations(), 2);
373        assert!(tracker.total_erasures() > 1000); // Includes vector ops
374    }
375
376    #[test]
377    fn test_energy_estimate() {
378        let tracker = ThermodynamicTracker::room_temperature();
379        let estimate = tracker.estimate_energy(Operation::BitErasure { count: 1 });
380
381        assert!((estimate.landauer_minimum_joules - LANDAUER_LIMIT_300K).abs() < 1e-22);
382        assert_eq!(estimate.efficiency_ratio, 1000.0);
383    }
384
385    #[test]
386    fn test_efficiency_report() {
387        let tracker = ThermodynamicTracker::room_temperature()
388            .with_technology_multiplier(1000.0);
389
390        tracker.record_operation(Operation::BitErasure { count: 1_000_000 });
391
392        let report = tracker.efficiency_report();
393
394        assert_eq!(report.total_bit_erasures, 1_000_000);
395        assert_eq!(report.efficiency_ratio, 1000.0);
396        assert!(report.reversible_savings_potential > 0.0);
397    }
398
399    #[test]
400    fn test_technology_profiles() {
401        // Verify reversible computing is most efficient
402        assert!(technology_profiles::REVERSIBLE_IDEAL < technology_profiles::BIOLOGICAL);
403        assert!(technology_profiles::BIOLOGICAL < technology_profiles::NEUROMORPHIC_PROJECTED);
404        assert!(technology_profiles::NEUROMORPHIC_PROJECTED < technology_profiles::CMOS_2024);
405    }
406}