Skip to main content

sp1_hypercube/
util.rs

1use sp1_primitives::{poseidon2_init, SP1Perm};
2
3/// The digest size.
4pub const DIGEST_SIZE: usize = 8;
5
6/// Compute the ceiling of the base-2 logarithm of a number.
7#[must_use]
8pub fn log2_ceil_usize(n: usize) -> usize {
9    // println!("n: {}", n);
10    n.next_power_of_two().ilog2() as usize
11}
12
13/// Get the inner perm
14#[must_use]
15pub fn inner_perm() -> SP1Perm {
16    poseidon2_init()
17}
18
19/// Get an array `xs` such that `xs[i] = i`.
20#[must_use]
21pub const fn indices_arr<const N: usize>() -> [usize; N] {
22    let mut indices_arr = [0; N];
23    let mut i = 0;
24    while i < N {
25        indices_arr[i] = i;
26        i += 1;
27    }
28    indices_arr
29}
30
31/// Pad to the next multiple of 32, with an option to specify the fixed height.
32//
33// The `rows` argument represents the rows of a matrix stored in row-major order. The function will
34// pad the rows using `row_fn` to create the padded rows. The padding will be to the next multiple
35// of 32 if `height` is `None`, or to the specified `height` if it is not `None`. The
36// function will panic of the number of rows is larger than the specified `height`.
37pub fn pad_rows_fixed<R: Clone>(rows: &mut Vec<R>, row_fn: impl Fn() -> R, height: Option<usize>) {
38    let nb_rows = rows.len();
39    let dummy_row = row_fn();
40    rows.resize(next_multiple_of_32(nb_rows, height), dummy_row);
41}
42
43/// Returns the internal value of the option if it is set, otherwise returns the next multiple of
44/// 32.
45#[track_caller]
46#[inline]
47#[allow(clippy::uninlined_format_args)]
48#[must_use]
49pub fn next_multiple_of_32(n: usize, fixed_height: Option<usize>) -> usize {
50    if let Some(height) = fixed_height {
51        if n > height {
52            panic!("fixed height is too small: got height {} for number of rows {}", height, n);
53        }
54        height
55    } else {
56        n.next_multiple_of(32).max(16)
57    }
58}