-
Notifications
You must be signed in to change notification settings - Fork 50
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
Refactor with a backend trait #36
Conversation
Please enter the commit message for your changes. Lines starting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful, I left you some comments but I think we can merge this :)
// TODO: should it be cloneable? It is now so because FnInfo needs to be cloneable. | ||
pub trait Backend: Clone { | ||
/// The circuit field / scalar field that the circuit is written on. | ||
type Field: Field + PrettyField; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: to avoid lines like Field: Field
I often qualify, so that it looks like Field: ark_ff::Field
@@ -4,6 +4,7 @@ | |||
|
|||
pub mod asm; | |||
pub mod circuit_writer; | |||
pub mod backends; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw it dawns on me that we're not really supporting multiple backends here, but rather multiple constraint systems. Maybe we should rename backends to constraint systems? wdyt? (let's not do this in this PR though, not urgent, more of a philosophical discussion)
let ctx = &mut ParserCtx::default(); | ||
let mut tokens = Token::parse(0, name).unwrap(); | ||
let sig = FnSig::parse(ctx, &mut tokens).unwrap(); | ||
|
||
let fn_handle = match name { | ||
POSEIDON_FN => poseidon, | ||
POSEIDON_FN => B::poseidon(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw I think a better idea here would be to have a default implementation if B::poseidon()
returns None
(maybe I can create an issue for that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The constraint backend for the circuit. | ||
/// For now, this needs to be exposed for the kimchi prover for kimchi specific low level data. | ||
/// So we might make this private if the prover facilities can be deprecated. | ||
pub backend: B, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub(crate)
?
impl KimchiVesta { | ||
pub fn compile_to_indexes( | ||
&self, | ||
public_input_size: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still find it weird that we have to pass this, maybe it should live in the backend as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to only related to the proving function that we might want to deprecate?
Maybe hold this decision until we decided if the proving function is to be removed.
if !self.finalized { | ||
unreachable!(); | ||
} | ||
&self.gates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still wondering if we should still have a function like this, to make sure that someone is not using the constraint system directly when it's not finalized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is checked before generating witness: https://github.com/katat/noname/blob/d48d95f76c7a7bcca5e6219379026a7c3ec181a8/src/backends/kimchi/mod.rs#L466
let returned_cells = circuit_writer.compile_main_function(fn_env, &function)?; | ||
let main_span = circuit_writer.main_info().unwrap().span; | ||
let private_input_indices = circuit_writer.private_input_indices.clone(); | ||
let public_output = circuit_writer.public_output.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the clones here instead of passing as a ref?
circuit_writer.compile_main_function(fn_env, &function)?; | ||
let returned_cells = circuit_writer.compile_main_function(fn_env, &function)?; | ||
let main_span = circuit_writer.main_info().unwrap().span; | ||
let private_input_indices = circuit_writer.private_input_indices.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think private_input_indices
should keep track of CellVar
s instead of indices, as indices is a backend implementation detail.
Maybe we should remove the pub
in CellVar { pub index: usize
and see what breaks
@@ -57,11 +57,11 @@ pub struct Gate | |||
|
|||
/// Coefficients | |||
#[serde(skip)] | |||
pub coeffs: Vec<Field>, | |||
pub coeffs: Vec<VestaField>, | |||
} | |||
|
|||
impl Gate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all this kimchi-specific code should be moved to the backend stuff
for (col, var) in row_of_vars.iter().enumerate() { | ||
let val = if let Some(var) = var { | ||
// if it's a public output, defer it's computation | ||
if matches!(self.witness_vars()[&var.index], Value::PublicOutput(_)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead: self.witness_vars[&var.index]
|
||
/// This provides a standard way to access to all the internal vars. | ||
/// Different backends should be accessible in the same way by the variable index. | ||
fn witness_vars(&self) -> &HashMap<usize, Value<Self>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok so I think that we should not do that, instead we should expose this:
fn witness_vars(&self, var: &CellVar) -> Value<Self>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and probably rename this to get_cellvar_value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/backends/mod.rs
Outdated
span: Span, | ||
) -> CellVar; | ||
|
||
fn debug_info(&self) -> &[DebugInfo]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah so I believe we could easily remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No description provided.