@@ -191,40 +191,62 @@ impl PolyOps for CpuBackend {
191191 poly : & CircleCoefficients < Self > ,
192192 domain : CircleDomain ,
193193 twiddles : & TwiddleTree < Self > ,
194+ ) -> CircleEvaluation < Self , BaseField , BitReversedOrder > {
195+ let buffer = vec ! [ BaseField :: zero( ) ; domain. size( ) ] ;
196+ Self :: evaluate_into ( poly, domain, twiddles, buffer)
197+ }
198+
199+ fn evaluate_into (
200+ poly : & CircleCoefficients < Self > ,
201+ domain : CircleDomain ,
202+ twiddles : & TwiddleTree < Self > ,
203+ mut buffer : Col < Self , BaseField > ,
194204 ) -> CircleEvaluation < Self , BaseField , BitReversedOrder > {
195205 assert ! ( domain. half_coset. is_doubling_of( twiddles. root_coset) ) ;
206+ assert_eq ! ( buffer. len( ) , domain. size( ) ) ;
196207
197- let mut values = poly. extend ( domain. log_size ( ) ) . coeffs ;
208+ // Copy extended coefficients into the buffer.
209+ let poly_len = poly. coeffs . len ( ) ;
210+ buffer[ ..poly_len] . copy_from_slice ( & poly. coeffs ) ;
211+ for v in & mut buffer[ poly_len..] {
212+ * v = BaseField :: zero ( ) ;
213+ }
198214
199215 if domain. log_size ( ) == 1 {
200- let ( mut v0, mut v1) = ( values [ 0 ] , values [ 1 ] ) ;
216+ let ( mut v0, mut v1) = ( buffer [ 0 ] , buffer [ 1 ] ) ;
201217 butterfly ( & mut v0, & mut v1, domain. half_coset . initial . y ) ;
202- return CircleEvaluation :: new ( domain, vec ! [ v0, v1] ) ;
218+ buffer[ 0 ] = v0;
219+ buffer[ 1 ] = v1;
220+ return CircleEvaluation :: new ( domain, buffer) ;
203221 }
204222
205223 if domain. log_size ( ) == 2 {
206- let ( mut v0, mut v1, mut v2, mut v3) = ( values [ 0 ] , values [ 1 ] , values [ 2 ] , values [ 3 ] ) ;
224+ let ( mut v0, mut v1, mut v2, mut v3) = ( buffer [ 0 ] , buffer [ 1 ] , buffer [ 2 ] , buffer [ 3 ] ) ;
207225 let CirclePoint { x, y } = domain. half_coset . initial ;
208226 butterfly ( & mut v0, & mut v2, x) ;
209227 butterfly ( & mut v1, & mut v3, x) ;
210228 butterfly ( & mut v0, & mut v1, y) ;
211229 butterfly ( & mut v2, & mut v3, -y) ;
212- return CircleEvaluation :: new ( domain, vec ! [ v0, v1, v2, v3] ) ;
230+ buffer[ 0 ] = v0;
231+ buffer[ 1 ] = v1;
232+ buffer[ 2 ] = v2;
233+ buffer[ 3 ] = v3;
234+ return CircleEvaluation :: new ( domain, buffer) ;
213235 }
214236
215237 let line_twiddles = domain_line_twiddles_from_tree ( domain, & twiddles. twiddles ) ;
216238 let circle_twiddles = circle_twiddles_from_line_twiddles ( line_twiddles[ 0 ] ) ;
217239
218240 for ( layer, layer_twiddles) in line_twiddles. iter ( ) . enumerate ( ) . rev ( ) {
219241 for ( h, & t) in layer_twiddles. iter ( ) . enumerate ( ) {
220- fft_layer_loop ( & mut values , layer + 1 , h, t, butterfly) ;
242+ fft_layer_loop ( & mut buffer , layer + 1 , h, t, butterfly) ;
221243 }
222244 }
223245 for ( h, t) in circle_twiddles. enumerate ( ) {
224- fft_layer_loop ( & mut values , 0 , h, t, butterfly) ;
246+ fft_layer_loop ( & mut buffer , 0 , h, t, butterfly) ;
225247 }
226248
227- CircleEvaluation :: new ( domain, values )
249+ CircleEvaluation :: new ( domain, buffer )
228250 }
229251
230252 fn precompute_twiddles ( coset : Coset ) -> TwiddleTree < Self > {
0 commit comments