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

Target test for JIT compiler #1836

Draft
wants to merge 77 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
e4c35fe
Experimental pil to rust compiler.
chriseth Feb 29, 2024
686bdc6
Compile and dlopen.
chriseth Aug 3, 2024
b2f8d88
oeu
chriseth Aug 3, 2024
392afc1
oeu
chriseth Aug 3, 2024
6b2029a
loaded sym
chriseth Aug 3, 2024
7ee9afc
log time
chriseth Aug 3, 2024
44e80b8
new crate.
chriseth Sep 12, 2024
65e5f44
fix
chriseth Sep 12, 2024
ec40700
work
chriseth Sep 12, 2024
0be7ac0
work
chriseth Sep 12, 2024
6aa9f45
wor
chriseth Sep 12, 2024
01272e8
loading
chriseth Sep 12, 2024
249f3c8
fix
chriseth Sep 12, 2024
1570fb0
sqrt
chriseth Sep 12, 2024
81dca2b
add benchmark
chriseth Sep 12, 2024
641f1f2
forgot test file
chriseth Sep 12, 2024
65c6c04
clean.
chriseth Sep 13, 2024
1578b1e
fix
chriseth Sep 13, 2024
ffa6187
Some logging.
chriseth Sep 13, 2024
51cae14
size in mb.
chriseth Sep 13, 2024
22de29a
Update pil-analyzer/tests/types.rs
chriseth Sep 13, 2024
2682d27
Use ibig.
chriseth Sep 13, 2024
e9d2910
Use native cpu.
chriseth Sep 13, 2024
541d8dc
clippy
chriseth Sep 19, 2024
306cbb2
Merge remote-tracking branch 'origin/main' into compi
chriseth Sep 23, 2024
5aea6b2
merge fix.
chriseth Sep 23, 2024
1a6db99
Remove ibig features.
chriseth Sep 23, 2024
5322ccd
Merge remote-tracking branch 'origin/main' into compi
chriseth Sep 23, 2024
cdf3ba9
Nicer error messages.
chriseth Sep 24, 2024
7b0dceb
Partial compile.
chriseth Sep 24, 2024
76e6389
clippy
chriseth Sep 24, 2024
00b56e6
fmt
chriseth Sep 24, 2024
3544d57
Update jit-compiler/src/lib.rs
chriseth Sep 24, 2024
5cf259c
Portability.
chriseth Sep 24, 2024
dc7e113
Merge branch 'compi' of ssh://github.com/powdr-labs/powdr into compi
chriseth Sep 24, 2024
e928a37
Update jit-compiler/tests/execution.rs
chriseth Sep 24, 2024
86b0a2d
fix error message.
chriseth Sep 24, 2024
3327e52
clippy
chriseth Sep 24, 2024
2a45653
Use extern c.
chriseth Sep 25, 2024
5647eb6
Use libloading.
chriseth Sep 25, 2024
540671d
Update jit-compiler/src/compiler.rs
chriseth Sep 25, 2024
2937860
Extract sqrt code.
chriseth Sep 25, 2024
681937a
Remove drop.
chriseth Sep 25, 2024
6a96b72
Add release - we need the variable.
chriseth Sep 25, 2024
8db0eba
Encapsulate temp dir in struct.
chriseth Sep 25, 2024
b47df41
Simplify compiler state.
chriseth Sep 25, 2024
bdc2d38
Error message.
chriseth Sep 25, 2024
8c23119
use unsafe extern C fn
chriseth Sep 25, 2024
9501ef9
use mebibytes.
chriseth Sep 25, 2024
1b44c1c
Match expressions.
chriseth Sep 24, 2024
3cf303b
test.
chriseth Sep 26, 2024
0d7df72
better match exprs
chriseth Sep 26, 2024
f22c2bb
comment
chriseth Sep 26, 2024
ed0c985
simple match test.
chriseth Sep 26, 2024
01dcb4b
match expressions for tuples.
chriseth Sep 26, 2024
48458fe
proper numbers
chriseth Sep 26, 2024
7f88008
more pat
chriseth Sep 26, 2024
e48c256
more pat
chriseth Sep 26, 2024
9a3242c
arrays
chriseth Sep 26, 2024
e79c610
docstring.
chriseth Sep 26, 2024
6a8462d
trigger change request
chriseth Sep 26, 2024
ca0ae6f
undo change.
chriseth Sep 26, 2024
5b54d2d
Try to generate constant values via jit.
chriseth Sep 23, 2024
db6ca37
clippy
chriseth Sep 27, 2024
12ec72c
Turn panics into errors.
chriseth Sep 27, 2024
244566a
Do not use JIT for short columns.
chriseth Sep 27, 2024
62ecc08
Merge remote-tracking branch 'origin/main' into use_compi
chriseth Sep 30, 2024
c0fcc59
Merge remote-tracking branch 'origin/main' into match_expr
chriseth Sep 30, 2024
a8b1406
fix
chriseth Sep 30, 2024
b24ee27
Let statements
chriseth Sep 30, 2024
98c2ff6
Formatting.
chriseth Sep 30, 2024
ae4869d
Add functionality benchmark.
chriseth Sep 24, 2024
10e886a
Merge branch 'use_compi' into target_test
chriseth Oct 1, 2024
281a2b0
Support enums in jit.
chriseth Oct 1, 2024
f9f58cb
Proper escaping for enum variants.
chriseth Oct 1, 2024
24eddf9
Merge remote-tracking branch 'origin/main' into jit_enums
chriseth Oct 1, 2024
8f99217
Merge branch 'jit_enums' into target_test
chriseth Oct 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ast/src/parsed/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,17 @@ impl SymbolPath {
})
}

/// Returns the path up to the last part and the last part individually.
/// Returns None if the last part is `super` or the path is empty.
pub fn try_split_off_last_part(&self) -> Option<(Self, String)> {
let mut parts = self.parts.clone();
let last_part = parts.pop().and_then(|p| match p {
Part::Super => None,
Part::Named(n) => Some(n),
})?;
Some((Self { parts }, last_part))
}

/// Returns the last part of the path. Panics if it is "super" or if the path is empty.
pub fn name(&self) -> &String {
self.try_last_part().unwrap()
Expand Down
1 change: 1 addition & 0 deletions executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ powdr-ast.workspace = true
powdr-number.workspace = true
powdr-parser-util.workspace = true
powdr-pil-analyzer.workspace = true
powdr-jit-compiler.workspace = true

itertools = "0.13"
log = { version = "0.4.17" }
Expand Down
158 changes: 158 additions & 0 deletions executor/src/constant_evaluator/interpreter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use std::{
collections::{BTreeMap, HashMap},
sync::{Arc, RwLock},
};

use powdr_ast::{
analyzed::{Analyzed, Expression, FunctionValueDefinition, Symbol, TypedExpression},
parsed::{
types::{ArrayType, Type},
IndexAccess,
},
};
use powdr_number::{BigInt, BigUint, DegreeType, FieldElement};
use powdr_pil_analyzer::evaluator::{self, Definitions, SymbolLookup, Value};
use rayon::iter::{IntoParallelIterator, ParallelIterator};

/// Evaluates the fixed polynomial `name` on all values from 0 to `degree - 1`
/// using an interpreter.
/// If `index` is `Some(i)`, evaluates the `i`-th element of the array.
pub fn generate_values<T: FieldElement>(
analyzed: &Analyzed<T>,
degree: DegreeType,
name: &str,
body: &FunctionValueDefinition,
index: Option<u64>,
) -> Vec<T> {
let symbols = CachedSymbols {
symbols: &analyzed.definitions,
solved_impls: &analyzed.solved_impls,
cache: Arc::new(RwLock::new(Default::default())),
degree,
};
let result = match body {
FunctionValueDefinition::Expression(TypedExpression { e, type_scheme }) => {
if let Some(type_scheme) = type_scheme {
assert!(type_scheme.vars.is_empty());
let ty = &type_scheme.ty;
if ty == &Type::Col {
assert!(index.is_none());
} else if let Type::Array(ArrayType { base, length: _ }) = ty {
assert!(index.is_some());
assert_eq!(base.as_ref(), &Type::Col);
} else {
panic!("Invalid fixed column type: {ty}");
}
};
let index_expr;
let e = if let Some(index) = index {
index_expr = IndexAccess {
array: e.clone().into(),
index: Box::new(BigUint::from(index).into()),
}
.into();
&index_expr
} else {
e
};
let fun = evaluator::evaluate(e, &mut symbols.clone()).unwrap();
(0..degree)
.into_par_iter()
.map(|i| {
evaluator::evaluate_function_call(
fun.clone(),
vec![Arc::new(Value::Integer(BigInt::from(i)))],
&mut symbols.clone(),
)?
.try_to_field_element()
})
.collect::<Result<Vec<_>, _>>()
}
FunctionValueDefinition::Array(values) => {
assert!(index.is_none());
values
.to_repeated_arrays(degree)
.map(|elements| {
let items = elements
.pattern()
.iter()
.map(|v| {
let mut symbols = symbols.clone();
evaluator::evaluate(v, &mut symbols)
.and_then(|v| v.try_to_field_element())
})
.collect::<Result<Vec<_>, _>>()?;

Ok(items
.into_iter()
.cycle()
.take(elements.size() as usize)
.collect::<Vec<_>>())
})
.collect::<Result<Vec<_>, _>>()
.map(|values| {
let values: Vec<T> = values.into_iter().flatten().collect();
assert_eq!(values.len(), degree as usize);
values
})
}
FunctionValueDefinition::TypeDeclaration(_)
| FunctionValueDefinition::TypeConstructor(_, _)
| FunctionValueDefinition::TraitDeclaration(_)
| FunctionValueDefinition::TraitFunction(_, _) => panic!(),
};
match result {
Err(err) => {
eprintln!("Error evaluating fixed polynomial {name}{body}:\n{err}");
panic!("{err}");
}
Ok(v) => v,
}
}

type SymbolCache<'a, T> = HashMap<String, BTreeMap<Option<Vec<Type>>, Arc<Value<'a, T>>>>;

#[derive(Clone)]
pub struct CachedSymbols<'a, T> {
symbols: &'a HashMap<String, (Symbol, Option<FunctionValueDefinition>)>,
solved_impls: &'a HashMap<String, HashMap<Vec<Type>, Arc<Expression>>>,
cache: Arc<RwLock<SymbolCache<'a, T>>>,
degree: DegreeType,
}

impl<'a, T: FieldElement> SymbolLookup<'a, T> for CachedSymbols<'a, T> {
fn lookup(
&mut self,
name: &'a str,
type_args: &Option<Vec<Type>>,
) -> Result<Arc<Value<'a, T>>, evaluator::EvalError> {
if let Some(v) = self
.cache
.read()
.unwrap()
.get(name)
.and_then(|map| map.get(type_args))
{
return Ok(v.clone());
}
let result = Definitions::lookup_with_symbols(
self.symbols,
self.solved_impls,
name,
type_args,
self,
)?;
self.cache
.write()
.unwrap()
.entry(name.to_string())
.or_default()
.entry(type_args.clone())
.or_insert_with(|| result.clone());
Ok(result)
}

fn degree(&self) -> Result<Arc<Value<'a, T>>, evaluator::EvalError> {
Ok(Value::Integer(self.degree.into()).into())
}
}
62 changes: 62 additions & 0 deletions executor/src/constant_evaluator/jit_compiler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::collections::HashMap;

use powdr_ast::analyzed::{Analyzed, PolyID};
use powdr_number::FieldElement;
use rayon::iter::{IntoParallelIterator, ParallelIterator};

use super::VariablySizedColumn;

/// Tries to just-in-time compile all fixed columns in `analyzed`
/// and then evaluates those functions to return `VariablySizedColumn`s.
/// Ignoreds all columns where the compilation fails.
pub fn generate_values<T: FieldElement>(
analyzed: &Analyzed<T>,
) -> HashMap<(String, PolyID), VariablySizedColumn<T>> {
let fun_map = match powdr_jit_compiler::compile(analyzed, &symbols_to_compile(analyzed)) {
Err(err) => {
log::error!("Failed to compile some constant columns: {}", err);
return HashMap::new();
}
Ok(fun_map) => fun_map,
};

analyzed
.constant_polys_in_source_order()
.into_iter()
.filter_map(|(symbol, _)| {
let fun = fun_map.get(symbol.absolute_name.as_str())?;
Some((symbol, fun))
})
.map(|(symbol, fun)| {
let column_values: Vec<Vec<T>> = symbol
.degree
.unwrap()
.iter()
.map(|degree| {
(0..degree)
.into_par_iter()
.map(|i| {
let result = fun.call(i);
T::from(result)
})
.collect()
})
.collect();

(
(symbol.absolute_name.clone(), symbol.into()),
column_values.into(),
)
})
.collect()
}

fn symbols_to_compile<T>(analyzed: &Analyzed<T>) -> Vec<&str> {
analyzed
.constant_polys_in_source_order()
.into_iter()
.filter_map(|(symbol, value)| {
(!symbol.is_array() && value.is_some()).then_some(symbol.absolute_name.as_str())
})
.collect()
}
Loading