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

jit interpreter branch handling #2481

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

jit interpreter branch handling #2481

wants to merge 10 commits into from

Conversation

pacheco
Copy link
Collaborator

@pacheco pacheco commented Feb 13, 2025

No description provided.

@pacheco pacheco marked this pull request as ready for review February 14, 2025 11:55
MachineCallArgumentIdx::Unknown(idx) => {
let var = &mut vars[*idx] as *mut T;
LookupCell::Output(unsafe { var.as_mut().unwrap() })
let mut block_stack = vec![self.actions.iter()];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handling of the existing actions didn't change, its only code for handling the Branch action that is new

@@ -29,10 +29,15 @@ use super::{
variable::Variable,
};

pub struct WitgenFunction<T> {
pub enum WitgenFunction<T: FieldElement> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to keep compiler.rs only concerned about compiling effects and transforming parameters to fit the loaded function.

What do you think about putting the enum in function_cache? Then we also don't need a #[cfg(test)]-function for the unit tests here.

prover_functions,
)
.unwrap();
let compiled_jit = !matches!(std::env::var("POWDR_JIT_INTERPRETER"), Ok(val) if val == "1");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you know, I'm not so happy about changing the behaviour of a function by something that is not an argument to the function.

How do you use this environment variable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seemed like the smallest change to have a way of enabling the interpreter, at least for now:
interpreter is disabled by default, and only enabled when POWDR_JIT_INTERPRETER=1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could enable it if the field is not supported by the compiler, for example. Then we test it on a lot of inputs and in the future, we can think about enabling it if the degree is small.

Comment on lines 313 to 317
if condition {
block_stack.push(if_branch.iter());
} else {
block_stack.push(else_branch.iter());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if condition {
block_stack.push(if_branch.iter());
} else {
block_stack.push(else_branch.iter());
}
block_stack.push(if condition {
if_branch.iter()
} else {
else_branch.iter()
});

#[derive(Debug)]
enum BranchTest<T: FieldElement> {
Equal { var: usize, value: T },
Less { var: usize, min: T, max: T },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this case, we could maybe call them Inside and Outside.

Comment on lines 371 to 373
if_actions.iter().chain(else_actions).for_each(|a| {
set.extend(a.writes());
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if_actions.iter().chain(else_actions).for_each(|a| {
set.extend(a.writes());
});
set.extend(if_actions.iter().chain(else_actions).flat_map(|a| a.writes()));

use bit_vec::BitVec;
use itertools::Itertools;
use powdr_number::GoldilocksField;

#[test]
fn branching() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice test!

);

// 3 - 2
params[0] = 3.into();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe avoid some code repetition here?
Something like

let inputs = vec![3,2,0,0,1];
let expected outputs = vec![0];
test(inputs, some_other_args, expected_outputs)

?

@@ -44,8 +45,39 @@ pub struct FunctionCache<'a, T: FieldElement> {
parts: MachineParts<'a, T>,
}

enum WitgenFunction<T: FieldElement> {
// TODO We might want to pass arguments as direct function parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this comment back to CompiledFunction? It mainly concerns the WitgenFunctionParameters, i.e. could also be moved there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants