Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split halo2 frontend and backend #239

Closed
ed255 opened this issue Dec 15, 2023 · 2 comments · Fixed by #254
Closed

Split halo2 frontend and backend #239

ed255 opened this issue Dec 15, 2023 · 2 comments · Fixed by #254
Assignees
Labels
enhancement New feature or request

Comments

@ed255
Copy link
Member

ed255 commented Dec 15, 2023

Currently the halo2 library implements an API to define circuits and the halo2 proof system without a clear separation. A summary of this work is to clearly separate the library into 2 parts:

  • frontend: responsible of offering an API to define circuits, perform necessary transformations and generate a low level plonkish circuit definition. Also responsible of helping generate the witness.
  • backend: responsible of performing the setup, proof generation and verification based on the output from the frontend.

I wrote this proposal which contains details on the rationale, goals and approach. Feel free to comment and provide feedback on this proposal (either in this issue, or in the hackmd document)

Meanwhile I have started exploring the implementation side in this branch https://github.com/privacy-scaling-explorations/halo2/tree/feature/frontend-backend with the goal of figuring out more details and testing the performance.

@ed255 ed255 added enhancement New feature or request breaking-change Changes that will break the current API labels Dec 15, 2023
@ed255 ed255 self-assigned this Dec 15, 2023
@jonathanpwang
Copy link

This is cool!

I would also advertise if possible that the front-end has some kind of statefulness with respect to challenge API phases. So the prover knows when it can switch phases. However there are some UX difficulties with this: either the frontend needs to specify what operations are done in what phase, or some IR layer needs to automatically create a computation graph sorted by phase.

For multi-threaded witness generation, if the backend were to fully control it then does that mean some kind of native support for parallel assignment to multiple regions? I think the issues there were (1) ensuring deterministic execution order, (2) how to lay out the regions parallel-ly. The latter could be solved if in keygen there is some inefficient process to layout regions etc, but then everything is pinned and the prover gets a computation graph.

In general having this separation between frontend and backend could mean you could potentially do lots of computation graph type optimizations during keygen, and then pin everything for optimal prover performance.

@ed255
Copy link
Member Author

ed255 commented Jan 11, 2024

In general having this separation between frontend and backend could mean you could potentially do lots of computation graph type optimizations during keygen, and then pin everything for optimal prover performance.

This is one of the main points! To clarify the scope of this task: this is only about creating the interface where the frontend and backend are different components; and making sure this interface/API is flexible enough to support all the use cases that you mention; but this use cases will not yet be implemented as part of this task. The current features of the circuit generation and circuit proving of halo2 will remain the same; but their implementation will be modularized.

I made a PR preview with this split here #243 and I think it fulfills the setting you describe. You can see an example of the new API in this test

fn test_mycircuit_full_split() {
You'll see there's a new type called CompiledCircuitV2 which is generated before keygen. The idea is that this compiled circuit contains a low level representation of the circuit ready for consumption by keygen and proving; and the frontend is free to perform any kind of expensive transformation/optimization from the high level circuit representation to this format. Then when proving, the frontend is free to calculate advice columns however it sees fit (and there's no limitation on parallelizing that). Then these advice column values are passed to the backend to be committed (and again, the backend is free to commit them in parallel).

The only serial point is when passing the advice column values from frontend to backend. I wonder if this is a limitation...

Regarding the phases part, it will be a responsibility of the frontend to figure out what happens in each phase (and this can be done in the compilation phase, previous to keygen). Then the API for proving involves a loop with one iteration per phase:

for phase in 0..cs.phases().count() {
where the frontend and backend go back and forth. This can probably be done with a generic function (that works with a generic frontend and a generic backend) to simplify the code.

@ed255 ed255 removed the breaking-change Changes that will break the current API label Feb 2, 2024
@ed255 ed255 linked a pull request Feb 2, 2024 that will close this issue
15 tasks
@ed255 ed255 closed this as completed in #254 Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants