openvm_stark_backend/
chip.rs

1use std::{
2    any::Any,
3    cell::RefCell,
4    rc::Rc,
5    sync::{Arc, Mutex},
6};
7
8use crate::prover::{hal::ProverBackend, types::AirProvingContext};
9
10/// A chip is a [ProverBackend]-specific object that converts execution logs (also referred to as
11/// records) into a trace matrix.
12///
13/// A chip may be stateful and store state on either host or device, although it is preferred that
14/// all state is received through records.
15pub trait Chip<R, PB: ProverBackend> {
16    /// Generate all necessary context for proving a single AIR.
17    fn generate_proving_ctx(&self, records: R) -> AirProvingContext<PB>;
18}
19
20/// Auto-implemented trait for downcasting of trait objects.
21pub trait AnyChip<R, PB: ProverBackend>: Chip<R, PB> {
22    fn as_any(&self) -> &dyn Any;
23}
24
25impl<R, PB: ProverBackend, C: Chip<R, PB> + 'static> AnyChip<R, PB> for C {
26    fn as_any(&self) -> &dyn Any {
27        self
28    }
29}
30
31impl<R, PB: ProverBackend, C: Chip<R, PB>> Chip<R, PB> for RefCell<C> {
32    fn generate_proving_ctx(&self, records: R) -> AirProvingContext<PB> {
33        self.borrow().generate_proving_ctx(records)
34    }
35}
36impl<R, PB: ProverBackend, C: Chip<R, PB>> Chip<R, PB> for Rc<C> {
37    fn generate_proving_ctx(&self, records: R) -> AirProvingContext<PB> {
38        self.as_ref().generate_proving_ctx(records)
39    }
40}
41impl<R, PB: ProverBackend, C: Chip<R, PB>> Chip<R, PB> for Arc<C> {
42    fn generate_proving_ctx(&self, records: R) -> AirProvingContext<PB> {
43        self.as_ref().generate_proving_ctx(records)
44    }
45}
46impl<R, PB: ProverBackend, C: Chip<R, PB>> Chip<R, PB> for Mutex<C> {
47    fn generate_proving_ctx(&self, records: R) -> AirProvingContext<PB> {
48        self.lock().unwrap().generate_proving_ctx(records)
49    }
50}
51
52// TODO: consider deleting this
53/// A trait to get chip usage information.
54pub trait ChipUsageGetter {
55    fn air_name(&self) -> String;
56    /// If the chip has a state-independent trace height that is determined
57    /// upon construction, return this height. This is used to distinguish
58    /// "static" versus "dynamic" usage metrics.
59    fn constant_trace_height(&self) -> Option<usize> {
60        None
61    }
62    /// Height of used rows in the main trace.
63    fn current_trace_height(&self) -> usize;
64    /// Width of the main trace
65    fn trace_width(&self) -> usize;
66    /// For metrics collection
67    fn current_trace_cells(&self) -> usize {
68        self.trace_width() * self.current_trace_height()
69    }
70}
71
72impl<C: ChipUsageGetter> ChipUsageGetter for Rc<C> {
73    fn air_name(&self) -> String {
74        self.as_ref().air_name()
75    }
76    fn constant_trace_height(&self) -> Option<usize> {
77        self.as_ref().constant_trace_height()
78    }
79    fn current_trace_height(&self) -> usize {
80        self.as_ref().current_trace_height()
81    }
82    fn trace_width(&self) -> usize {
83        self.as_ref().trace_width()
84    }
85}
86
87impl<C: ChipUsageGetter> ChipUsageGetter for RefCell<C> {
88    fn air_name(&self) -> String {
89        self.borrow().air_name()
90    }
91    fn constant_trace_height(&self) -> Option<usize> {
92        self.borrow().constant_trace_height()
93    }
94    fn current_trace_height(&self) -> usize {
95        self.borrow().current_trace_height()
96    }
97    fn trace_width(&self) -> usize {
98        self.borrow().trace_width()
99    }
100}
101
102impl<C: ChipUsageGetter> ChipUsageGetter for Mutex<C> {
103    fn air_name(&self) -> String {
104        self.lock().unwrap().air_name()
105    }
106    fn constant_trace_height(&self) -> Option<usize> {
107        self.lock().unwrap().constant_trace_height()
108    }
109    fn current_trace_height(&self) -> usize {
110        self.lock().unwrap().current_trace_height()
111    }
112    fn trace_width(&self) -> usize {
113        self.lock().unwrap().trace_width()
114    }
115}