egg_sketches/
util.rs

1use crate::*;
2use memory_stats::memory_stats;
3
4pub fn grow_egraph_until<L, A, S>(
5  search_name: &str,
6  egraph: EGraph<L, A>,
7  rules: &[Rewrite<L, A>],
8  mut satisfied: S
9) -> EGraph<L, A>
10where S: FnMut(&mut Runner<L, A>) -> bool + 'static,
11      L: Language, A: Analysis<L>, A: Default
12{
13  let search_name_hook = search_name.to_owned();
14  let runner = egg::Runner::default()
15      .with_scheduler(egg::SimpleScheduler)
16      .with_iter_limit(100)
17      .with_node_limit(100_000_000)
18      .with_time_limit(std::time::Duration::from_secs(5 * 60))
19      .with_hook(move |runner| {
20        let mut out_of_memory = false;
21        // hook 0 <- nothing
22        // iteration 0
23        // hook 1 <- #0 size etc after iteration 0 + memory after iteration 0
24        if let Some(it) = runner.iterations.last() {
25          out_of_memory = iteration_stats(&search_name_hook, it, runner.iterations.len());
26        }
27
28        if satisfied(runner) {
29          Err(String::from("Satisfied"))
30        } else if out_of_memory {
31          Err(String::from("Out of Memory"))
32        } else {
33          Ok(())
34        }
35      })
36      .with_egraph(egraph)
37      .run(&rules[..]);
38  iteration_stats(search_name, runner.iterations.last().unwrap(), runner.iterations.len());
39  runner.print_report();
40  runner.egraph
41}
42
43// search name,
44// iteration number,
45// physical memory,
46// virtual memory,
47// e-graph nodes,
48// e-graph classes,
49// applied rules,
50// total time,
51// hook time,
52// search time,
53// apply time,
54// rebuild time
55fn iteration_stats(search_name: &str, it: &egg::Iteration<()>, it_number: usize) -> bool {
56  let memory = memory_stats().expect("could not get current memory usage");
57  let out_of_memory = memory.virtual_mem > 8_000_000_000;
58  let found = match &it.stop_reason {
59      Some(egg::StopReason::Other(s)) => s == "Satisfied",
60      _ => false,
61  };
62  eprintln!("{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}",
63      search_name,
64      it_number,
65      memory.physical_mem,
66      memory.virtual_mem,
67      it.egraph_nodes,
68      it.egraph_classes,
69      it.applied.iter().map(|(_, &n)| n).sum::<usize>(),
70      it.total_time,
71      it.hook_time,
72      it.search_time,
73      it.apply_time,
74      it.rebuild_time,
75      found);
76  out_of_memory
77}
78
79pub fn comparing_eclass_extract_sketch<L, A, CF>(
80  s: &Sketch<L>,
81  cost_f1: CF,
82  cost_f2: CF,
83  egraph: &EGraph<L, A>,
84  id: Id,
85) -> Option<(CF::Cost, RecExpr<L>)>
86where
87  L: Language + std::fmt::Display,
88  A: Analysis<L>,
89  CF: CostFunction<L>,
90  CF::Cost: 'static + Ord,
91{
92  use std::time::Instant;
93  let t1 = Instant::now();
94  println!("extract");
95  let res1 = eclass_extract_sketch(s, cost_f1, egraph, id);
96  let t2 = Instant::now();
97  println!("recursive extract");
98  let res2 = recursive_extract::eclass_extract_sketch(s, cost_f2, egraph, id);
99  let t3 = Instant::now();
100  assert_eq!(res1.is_some(), res2.is_some());
101  if let (Some((c1, t1)), Some((c2, t2))) = (&res1, &res2) {
102    println!("{}", t1);
103    println!("{}", t2);
104    assert_eq!(c1, c2);
105  };
106  println!("e-class analysis extraction took: {:?}", t2.duration_since(t1));
107  println!("recursive descent extraction took: {:?}", t3.duration_since(t2));
108  println!("");
109  return res1;
110}