-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
If I understand correctly, ascent is't a 'differential datalog'-style implementation, but is optimized for batch processing.
The API does however allow .run() to be called multiple times, so users will eventually do it.
I did a little experiment:
use std::time::Instant;
use ascent::ascent;
fn main() {
ascent!{
#![measure_rule_times]
relation x(u64,u64);
relation y(u64,u64);
y(i,n) <-- x(i,n), x(i,n+100);
x(i,n+200) <-- y(i,n), if *n < 400000;
}
let mut prog = AscentProgram::default();
fn time(prog: &mut AscentProgram, title: &str) {
let start = Instant::now();
prog.run();
println!("{:?} {:?}", prog.x.len(), prog.y.len());
println!("{}", prog.scc_times_summary());
println!("{}: {:?}",title, start.elapsed());
}
prog.x = vec![(0, 1,), (0, 101,)];
time(&mut prog, "Initial run");
prog.x.push((1,1,));
time(&mut prog,"Add of non-consequential fact");
prog.x.push((1,101,));
time(&mut prog,"Add of consequential fact");
let mut prog = AscentProgram::default();
prog.x = vec![(0, 1,), (0, 101,), (1,1,), (1,101)];
time(&mut prog,"Full rerun");
}The output is:
4002 4001
scc 0 time: 1.436391002s
some of rule times: 1.42136186s
rule x <-- y_indices_none_delta, if ⋯
time: 4.024887ms
rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
time: 2.227919ms
rule y <-- x_indices_none_total, x_indices_0_1_delta
time: 1.415109054s
-----------------------------------------
Initial run: 1.436422348s
4003 4001
scc 0 time: 1.443135223s
some of rule times: 1.42810157s
rule x <-- y_indices_none_delta, if ⋯
time: 5.573965ms
rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
time: 7.418424ms
rule y <-- x_indices_none_total, x_indices_0_1_delta
time: 1.415109181s
-----------------------------------------
Add of non-consequential fact: 9.375828ms
8004 8002
scc 0 time: 11.459918911s
some of rule times: 11.423892339s
rule x <-- y_indices_none_delta, if ⋯
time: 12.857089ms
rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
time: 17.993869ms
rule y <-- x_indices_none_total, x_indices_0_1_delta
time: 11.393041381s
-----------------------------------------
Add of consequential fact: 10.019436059s
8004 8002
scc 0 time: 3.073175727s
some of rule times: 3.047507618s
rule x <-- y_indices_none_delta, if ⋯
time: 7.811237ms
rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
time: 4.606486ms
rule y <-- x_indices_none_total, x_indices_0_1_delta
time: 3.035089895s
-----------------------------------------
Full rerun: 3.073211278s
It seems to me that:
- running after adding to the input relation sometimes (my second run), does a lot less work than a full rerun.
- at other times, when a lot of new facts were implied by the new fact, it does more work than a full rerun.
While (as I expected), removing facts from relations isn't supported.
ascent!{
struct A;
relation x(u64);
relation y(u64);
y(n) <-- x(n);
}
let mut prog = A::default();
prog.x = vec![(1,), (2,)];
prog.run();
println!("{:?}", prog.y);
prog.x = vec![(1,)];
prog.run();
println!("{:?}", prog.y)produces
[(1,), (2,)]
[(1,), (2,)]
My question is, would it be possible to either:
- add some support for incrmentalized computation, so that you could indicate 'I've added facts to this relation' and 'I've removed facts from this relation', causing some of the indices to be recomputed?
- prevent the user from calling .run() multiple times, by making run take ownership of the program instead of taking it by mutable reference
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels