@@ -35,12 +35,6 @@ pub mod opener;
3535/// Computation of DEEP quotient polynomial and commitment
3636pub mod quotient;
3737
38- /// Proves multiple chips with interactions together.
39- /// This prover implementation is specialized for Interactive AIRs.
40- pub struct MultiTraceStarkProver < ' c , SC : StarkGenericConfig > {
41- pub config : & ' c SC ,
42- }
43-
4438/// CPU backend using Plonky3 traits.
4539#[ derive( Derivative ) ]
4640#[ derivative( Clone ( bound = "" ) , Copy ( bound = "" ) , Default ( bound = "" ) ) ]
@@ -52,6 +46,9 @@ pub struct CpuBackend<SC> {
5246#[ derivative( Clone ( bound = "" ) , Copy ( bound = "" ) ) ]
5347pub struct CpuDevice < ' a , SC > {
5448 config : & ' a SC ,
49+ /// When committing a matrix, the matrix is cloned into newly allocated memory.
50+ /// The size of the newly allocated memory will be `matrix.size() << log_blowup_factor`.
51+ log_blowup_factor : usize ,
5552}
5653
5754impl < SC : StarkGenericConfig > ProverBackend for CpuBackend < SC > {
@@ -103,6 +100,7 @@ impl<SC: StarkGenericConfig> ProverDevice<CpuBackend<SC>> for CpuDevice<'_, SC>
103100
104101impl < SC : StarkGenericConfig > TraceCommitter < CpuBackend < SC > > for CpuDevice < ' _ , SC > {
105102 fn commit ( & self , traces : & [ Arc < RowMajorMatrix < Val < SC > > > ] ) -> ( Com < SC > , PcsData < SC > ) {
103+ let log_blowup_factor = self . log_blowup_factor ;
106104 let pcs = self . pcs ( ) ;
107105 let ( log_trace_heights, traces_with_domains) : ( Vec < _ > , Vec < _ > ) = traces
108106 . iter ( )
@@ -111,7 +109,33 @@ impl<SC: StarkGenericConfig> TraceCommitter<CpuBackend<SC>> for CpuDevice<'_, SC
111109 let log_height: u8 = log2_strict_usize ( height) . try_into ( ) . unwrap ( ) ;
112110 // Recomputing the domain is lightweight
113111 let domain = pcs. natural_domain_for_degree ( height) ;
114- ( log_height, ( domain, matrix. as_ref ( ) . clone ( ) ) )
112+ // pcs.commit takes the trace matrix and in the case of FRI, does in-place cosetDFT
113+ // which requires resizing to a larger buffer size. Since we are cloning anyways,
114+ // we should just allocate the larger size to avoid memory-reallocation
115+ // ref: https://github.com/Plonky3/Plonky3/blob/8c8bbb4c17bd2b7ef2404338ab8f9036d5f08337/dft/src/traits.rs#L116
116+ let trace_slice = & matrix. as_ref ( ) . values ;
117+ let new_buffer_size = trace_slice
118+ . len ( )
119+ . checked_shl ( log_blowup_factor. try_into ( ) . unwrap ( ) )
120+ . unwrap ( ) ;
121+ let mut new_buffer = Vec :: with_capacity ( new_buffer_size) ;
122+ // SAFETY:
123+ // - `trace_slice` is allocated for `trace_slice.len() * size_of::<F>` bytes, obviously
124+ // - we just allocated `new_buffer` for at least `trace_slice.len() * size_of::<F>` bytes above (more if there's blowup)
125+ // - both are slices of &[F] so alignment is guaranteed
126+ // - `new_buffer` is newly allocated so non-overlapping with `trace_slice`
127+ unsafe {
128+ std:: ptr:: copy_nonoverlapping (
129+ trace_slice. as_ptr ( ) ,
130+ new_buffer. as_mut_ptr ( ) ,
131+ trace_slice. len ( ) ,
132+ ) ;
133+ new_buffer. set_len ( trace_slice. len ( ) ) ;
134+ }
135+ (
136+ log_height,
137+ ( domain, RowMajorMatrix :: new ( new_buffer, matrix. width ) ) ,
138+ )
115139 } )
116140 . unzip ( ) ;
117141 let ( commit, data) = pcs. commit ( traces_with_domains) ;
0 commit comments