Skip to content

Commit 0569c3f

Browse files
authored
Full FE in memory word (#2472)
This helps making successive Poseidon2GL calls cheaper (e.g. in merkle tree and sponge). My plan for follow-up PRs: - use Poseidon2GL in the bootloader, hopefully making its trace smaller; - remove all variants of PoseidonGL, as it would have been superseded; - make another patch to the plonky3 verifier, so it benefits from this change (instead of suffering a regression).
1 parent 6440b72 commit 0569c3f

File tree

18 files changed

+606
-289
lines changed

18 files changed

+606
-289
lines changed

pipeline/tests/powdr_std.rs

+7
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ fn poseidon2_gl_test() {
9292
regular_test_gl(f, &[]);
9393
}
9494

95+
#[test]
96+
#[ignore = "Too slow"]
97+
fn split_gl_vec_test() {
98+
let f = "std/split_gl_vec_test.asm";
99+
regular_test_gl(f, &[]);
100+
}
101+
95102
#[test]
96103
#[ignore = "Too slow"]
97104
fn split_bn254_test() {

plonky3/src/params/poseidon2/goldilocks/powdr_accel_impl.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,32 @@ use p3_field::AbstractField;
33
use p3_goldilocks::Goldilocks;
44
use p3_symmetric::CryptographicPermutation;
55
use powdr_riscv_runtime::{
6-
goldilocks::Goldilocks as PowdrGoldilocks,
6+
goldilocks::{extract_opaque_vec8, Goldilocks as PowdrGoldilocks, OpaqueGoldilocks},
77
hash::{poseidon2_gl, poseidon2_gl_inplace},
88
};
99

1010
#[derive(Clone, Copy, Debug)]
1111
pub struct Permutation;
1212

1313
impl p3_symmetric::Permutation<[Goldilocks; 8]> for Permutation {
14-
// Both Goldilocks and PowdrGoldilocks are repr(transparent), and both use
15-
// canonical representation internally, so it is safe to cast between their
16-
// array's references.
17-
//
18-
// TODO: We are relying on implementation detail. So, ideally, we should
19-
// static assert that std::mem::transmute(Goldilocks::one()) == 1u64.
20-
2114
fn permute(&self, input: [Goldilocks; 8]) -> [Goldilocks; 8] {
15+
// TODO: as of this writing, I am temporarily introducing a performance regression to convert
16+
// p3_goldilocks::Goldilocks to and from OpaqueGoldilocks in software. To get an improvement,
17+
// we must patch the p3's Merkle Tree implementation to use OpaqueGoldilocks directly and do
18+
// the conversion only once, in the output.
19+
20+
// Both Goldilocks and PowdrGoldilocks are repr(transparent), and both use
21+
// canonical representation internally, so it is safe to cast between their
22+
// array's pointers.
2223
let input = unsafe { &*(&input as *const _ as *const [PowdrGoldilocks; 8]) };
23-
let output = poseidon2_gl(input);
24-
// Let's hope the compiler optimizes this into a no-op.
25-
output.map(|x| Goldilocks::from_canonical_u64(u64::from(x)))
24+
let input = input.map(|x| OpaqueGoldilocks::from(x));
25+
let output = poseidon2_gl(&input);
26+
27+
extract_opaque_vec8(&output).map(|x| Goldilocks::from_canonical_u64(x))
2628
}
2729

2830
fn permute_mut(&self, data: &mut [Goldilocks; 8]) {
29-
let data = unsafe { &mut *(data as *mut _ as *mut [PowdrGoldilocks; 8]) };
31+
let data = unsafe { &mut *(data as *mut _ as *mut [OpaqueGoldilocks; 8]) };
3032
poseidon2_gl_inplace(data);
3133
}
3234
}

powdr/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub use powdr_pilopt as pilopt;
88
pub use powdr_pipeline as pipeline;
99
pub use powdr_riscv as riscv;
1010
pub use powdr_riscv_executor as riscv_executor;
11+
use powdr_riscv_executor::hash_map_to_memory_state;
1112

1213
pub use powdr_pipeline::Pipeline;
1314

@@ -314,7 +315,7 @@ fn run_internal(
314315

315316
let trace_len = riscv_executor::execute(
316317
&asm,
317-
initial_memory,
318+
hash_map_to_memory_state(initial_memory),
318319
pipeline.data_callback().unwrap(),
319320
&riscv::continuations::bootloader::default_input(&[]),
320321
profiler,

0 commit comments

Comments
 (0)