diff --git a/crates/backend/field/src/packed/packed_traits.rs b/crates/backend/field/src/packed/packed_traits.rs index bd9a643b..95b601d4 100644 --- a/crates/backend/field/src/packed/packed_traits.rs +++ b/crates/backend/field/src/packed/packed_traits.rs @@ -337,7 +337,6 @@ pub trait PackedFieldExtension impl Iterator; /// Given a iterator of packed extension field elements, convert to an iterator of @@ -360,7 +359,6 @@ pub trait PackedFieldExtension impl Iterator { Self::packed_ext_powers(base).take(unpacked_len.div_ceil(BaseField::Packing::WIDTH)) } diff --git a/crates/backend/poly/src/eq_mle.rs b/crates/backend/poly/src/eq_mle.rs index 3ab98c6e..67952b06 100644 --- a/crates/backend/poly/src/eq_mle.rs +++ b/crates/backend/poly/src/eq_mle.rs @@ -1021,12 +1021,9 @@ fn base_eval_eq_packed_with_packed_output( F: Field, EF: ExtensionField, { - // Ensure that the output buffer size is correct: - // It should be of size `2^n`, where `n` is the number of variables. - let width = F::Packing::WIDTH; - let log_packing_width = log2_strict_usize(width); + // `eval_points` is the middle slice from `par_eval_eq`, so its length says nothing about the + // packing width (the callers assert that against the full point). debug_assert_eq!(out.len(), 1 << eval_points.len()); - debug_assert!(log_packing_width <= eval_points.len()); match eval_points.len() { 0 => { @@ -1320,6 +1317,29 @@ mod tests { } } + /// `par_eval_eq` hands the kernel a middle slice of any length >= 2, so the hardcoded arms + /// below `log_packing_width` must agree with the unpacked-output twin. Calling the kernel + /// directly keeps this independent of the SIMD width and thread count. + #[test] + fn base_packed_kernel_handles_short_slices() { + let mut rng = StdRng::seed_from_u64(11); + let scalar: EF = rng.random(); + let eq_evals = ::Packing::from_fn(|_| rng.random()); + + for len in 1..=3 { + let points: Vec = (0..len).map(|_| rng.random()).collect(); + + let mut expected = EF::zero_vec(::Packing::WIDTH << len); + base_eval_eq_packed::(&points, &mut expected, eq_evals, scalar); + + let mut packed = EFPacking::::zero_vec(1 << len); + let packed_scalar = EFPacking::::from(scalar); + base_eval_eq_packed_with_packed_output::(&points, &mut packed, eq_evals, packed_scalar); + + assert_eq!(expected, EFPacking::::to_ext_iter_vec(packed), "len = {len}"); + } + } + #[test] fn test_compute_eval_eq_packed_dual() { let packing_width = ::Packing::WIDTH;