Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ p3-poseidon2-air.workspace = true
lookup.workspace = true
sumcheck.workspace = true
vm.workspace = true
thiserror.workspace = true

[dev-dependencies]
hashsig.workspace = true
25 changes: 6 additions & 19 deletions crates/compiler/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::BTreeMap;
use p3_field::PrimeCharacteristicRing;
use pest::{Parser, iterators::Pair};
use pest_derive::Parser;
use thiserror::Error;
use utils::ToUsize;
use vm::F;

Expand All @@ -18,29 +19,15 @@ use crate::{
#[grammar = "grammar.pest"]
pub struct LangParser;

#[derive(Debug)]
#[derive(Debug, Error)]
pub(crate) enum ParseError {
PestError(pest::error::Error<Rule>),
SemanticError(String),
}

impl From<pest::error::Error<Rule>> for ParseError {
fn from(error: pest::error::Error<Rule>) -> Self {
Self::PestError(error)
}
}
#[error(transparent)]
PestError(#[from] pest::error::Error<Rule>),

impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::PestError(e) => write!(f, "Parse error: {e}"),
Self::SemanticError(e) => write!(f, "Semantic error: {e}"),
}
}
#[error("Semantic error: {0}")]
SemanticError(String),
}

impl std::error::Error for ParseError {}

pub(crate) fn parse_program(input: &str) -> Result<Program, ParseError> {
let input = remove_comments(input);
let mut pairs = LangParser::parse(Rule::program, &input)?;
Expand Down
3 changes: 1 addition & 2 deletions crates/pcs/src/combinatorics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ impl TreeOfVariablesInner {

impl TreeOfVariables {
pub fn compute_optimal(vars_per_polynomial: Vec<usize>) -> Self {
let n = vars_per_polynomial.len();
assert!(n > 0);
assert!(!vars_per_polynomial.is_empty());

let root = Self::compute_greedy(&vars_per_polynomial);

Expand Down
2 changes: 1 addition & 1 deletion crates/utils/src/constraints_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl<'a, EF: ExtensionField<PF<EF>> + ExtensionField<IF>, IF: ExtensionField<PF<

#[inline]
fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
let x: IF = x.into();
let x = x.into();
if !x.is_zero() {
self.errors.push(self.constraint_index);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/utils/src/constraints_folder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ where

#[inline]
fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
let x: NF = x.into();
let x = x.into();
let alpha_power = self.alpha_powers[self.constraint_index];
self.accumulator += alpha_power * x;
self.constraint_index += 1;
Expand Down
33 changes: 3 additions & 30 deletions crates/utils/src/misc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::ops::Range;

use p3_field::{BasedVectorSpace, ExtensionField, Field};
use p3_field::{ExtensionField, Field};
use rayon::prelude::*;

use crate::PF;
Expand All @@ -15,31 +13,6 @@ pub fn transmute_slice<Before, After>(slice: &[Before]) -> &[After] {
unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<After>(), new_len) }
}

#[must_use]
pub const fn shift_range(range: Range<usize>, shift: usize) -> Range<usize> {
Range {
start: range.start + shift,
end: range.end + shift,
}
}

#[must_use]
pub const fn diff_to_next_power_of_two(n: usize) -> usize {
n.next_power_of_two() - n
}

pub fn left_mut<A>(slice: &mut [A]) -> &mut [A] {
assert!(slice.len().is_multiple_of(2));
let mid = slice.len() / 2;
&mut slice[..mid]
}

pub fn right_mut<A>(slice: &mut [A]) -> &mut [A] {
assert!(slice.len().is_multiple_of(2));
let mid = slice.len() / 2;
&mut slice[mid..]
}

pub fn left_ref<A>(slice: &[A]) -> &[A] {
assert!(slice.len().is_multiple_of(2));
let mid = slice.len() / 2;
Expand Down Expand Up @@ -71,9 +44,9 @@ pub fn field_slice_as_base<F: Field, EF: ExtensionField<F>>(slice: &[EF]) -> Opt
}

pub fn dot_product_with_base<EF: ExtensionField<PF<EF>>>(slice: &[EF]) -> EF {
assert_eq!(slice.len(), <EF as BasedVectorSpace<PF<EF>>>::DIMENSION);
assert_eq!(slice.len(), EF::DIMENSION);
(0..EF::DIMENSION)
.map(|i| slice[i] * <EF as BasedVectorSpace<PF<EF>>>::ith_basis_element(i).unwrap())
.map(|i| slice[i] * EF::ith_basis_element(i).unwrap())
.sum::<EF>()
}

Expand Down
99 changes: 1 addition & 98 deletions crates/utils/src/multilinear.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,12 @@
use std::borrow::Borrow;

use p3_field::{BasedVectorSpace, ExtensionField, Field, PackedValue, dot_product};
use p3_field::{ExtensionField, Field, dot_product};
use rayon::prelude::*;
use tracing::instrument;
use whir_p3::poly::evals::EvaluationsList;

use crate::{EFPacking, PF};

pub fn fold_multilinear_in_small_field<F: Field, EF: ExtensionField<F>, D>(
m: &[D],
scalars: &[F],
) -> Vec<EF> {
// TODO ...
assert!(scalars.len().is_power_of_two() && scalars.len() <= m.len());
let new_size = m.len() / scalars.len();

let dim = <EF as BasedVectorSpace<F>>::DIMENSION;

let m_transmuted: &[F] =
unsafe { std::slice::from_raw_parts(m.as_ptr().cast::<F>(), m.len() * dim) };
let res_transmuted = {
let new_size = m.len() * dim / scalars.len();

if new_size < F::Packing::WIDTH {
(0..new_size)
.into_par_iter()
.map(|i| {
scalars
.iter()
.enumerate()
.map(|(j, s)| *s * m_transmuted[i + j * new_size])
.sum()
})
.collect()
} else {
let inners = (0..scalars.len())
.map(|i| &m_transmuted[i * new_size..(i + 1) * new_size])
.collect::<Vec<_>>();
let inners_packed = inners
.iter()
.map(|&inner| F::Packing::pack_slice(inner))
.collect::<Vec<_>>();

let packed_res = (0..new_size / F::Packing::WIDTH)
.into_par_iter()
.map(|i| {
scalars
.iter()
.enumerate()
.map(|(j, s)| inners_packed[j][i] * *s)
.sum::<F::Packing>()
})
.collect::<Vec<_>>();

let mut unpacked: Vec<F> = unsafe { std::mem::transmute(packed_res) };
unsafe {
unpacked.set_len(new_size);
}

unpacked
}
};
let res: Vec<EF> = unsafe {
let mut res: Vec<EF> = std::mem::transmute(res_transmuted);
res.set_len(new_size);
res
};

res
}

pub fn fold_multilinear_in_large_field<F: Field, EF: ExtensionField<F>>(
m: &[F],
scalars: &[EF],
Expand Down Expand Up @@ -145,40 +82,6 @@ pub fn batch_fold_multilinear_in_large_field_packed<EF: ExtensionField<PF<EF>>>(
.collect()
}

pub fn batch_fold_multilinear_in_small_field<F: Field, EF: ExtensionField<F>>(
polys: &[&[EF]],
scalars: &[F],
) -> Vec<Vec<EF>> {
polys
.par_iter()
.map(|poly| fold_multilinear_in_small_field(poly, scalars))
.collect()
}

pub fn batch_fold_multilinear_in_small_field_packed<EF: ExtensionField<PF<EF>>>(
polys: &[&[EFPacking<EF>]],
scalars: &[PF<EF>],
) -> Vec<Vec<EF>> {
polys
.par_iter()
.map(|poly| fold_multilinear_in_small_field(poly, scalars))
.collect()
}

// pub fn packed_multilinear<F: Field>(pols: &[Vec<F>]) -> Vec<F> {
// let n_vars = pols[0].num_variables();
// assert!(pols.iter().all(|p| p.num_variables() == n_vars));
// let packed_len = (pols.len() << n_vars).next_power_of_two();
// let mut dst = F::zero_vec(packed_len);
// let mut offset = 0;
// // TODO parallelize
// for pol in pols {
// dst[offset..offset + pol.num_evals()].copy_from_slice(pol);
// offset += pol.num_evals();
// }
// dst
// }

#[instrument(name = "add_multilinears", skip_all)]
pub fn add_multilinears<F: Field>(pol1: &[F], pol2: &[F]) -> Vec<F> {
assert_eq!(pol1.len(), pol2.len());
Expand Down
4 changes: 2 additions & 2 deletions crates/utils/src/packed_constraints_folder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<'a, EF: ExtensionField<PF<EF>>> AirBuilder for ConstraintFolderPackedBase<'
#[inline]
fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
let alpha_power = self.alpha_powers[self.constraint_index];
let x: PFPacking<EF> = x.into();
let x = x.into();
self.accumulator += Into::<EFPacking<EF>>::into(alpha_power) * x;
self.constraint_index += 1;
}
Expand Down Expand Up @@ -102,7 +102,7 @@ impl<'a, EF: ExtensionField<PF<EF>>> AirBuilder for ConstraintFolderPackedExtens
#[inline]
fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
let alpha_power = self.alpha_powers[self.constraint_index];
let x: EFPacking<EF> = x.into();
let x = x.into();
self.accumulator += x * alpha_power;
self.constraint_index += 1;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/utils/src/wrappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn pack_extension<EF: ExtensionField<PF<EF>>>(slice: &[EF]) -> Vec<EFPacking
slice
.par_chunks_exact(packing_width::<EF>())
.map(EFPacking::<EF>::from_ext_slice)
.collect::<Vec<_>>()
.collect()
}

pub fn unpack_extension<EF: ExtensionField<PF<EF>>>(vec: &[EFPacking<EF>]) -> Vec<EF> {
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/bytecode/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl Hint {
let values = content
.iter()
.map(|m| Ok(m.read_value(memory, fp)?.to_string()))
.collect::<Result<Vec<_>, RunnerError>>()?;
.collect::<Result<Vec<_>, _>>()?;

// Logs for performance analysis:
if values.first().is_some_and(|s| s == "123456789") {
Expand Down
9 changes: 4 additions & 5 deletions crates/xmss/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@ impl WotsSecretKey {

#[must_use]
pub fn new(pre_images: [Digest; N_CHAINS], poseidon16: &Poseidon16) -> Self {
let mut public_key = [Default::default(); N_CHAINS];
for i in 0..N_CHAINS {
public_key[i] = iterate_hash(&pre_images[i], CHAIN_LENGTH, poseidon16);
}
let public_key = WotsPublicKey(std::array::from_fn(|i| {
iterate_hash(&pre_images[i], CHAIN_LENGTH, poseidon16)
}));
Self {
pre_images,
public_key: WotsPublicKey(public_key),
public_key,
}
}

Expand Down
Loading