@@ -10,11 +10,11 @@ use rand::Rng;
1010pub const ELABORATE_TESTING : bool = false ;
1111
1212pub fn test_save_path ( name : & str ) -> String {
13- return if ELABORATE_TESTING {
13+ if ELABORATE_TESTING {
1414 format ! ( "/dev/shm/{}_egraph.json" , name)
1515 } else {
1616 "" . to_string ( )
17- } ;
17+ }
1818}
1919
2020// generates a float between 0 and 1
@@ -38,12 +38,12 @@ pub fn generate_random_egraph() -> EGraph {
3838 let get_semi_random_cost = |nodes : & Vec < Node > | -> Cost {
3939 let mut rng = rand:: thread_rng ( ) ;
4040
41- if nodes. len ( ) > 0 && rng. gen_bool ( 0.1 ) {
42- return nodes[ rng. gen_range ( 0 ..nodes. len ( ) ) ] . cost ;
41+ if ! nodes. is_empty ( ) && rng. gen_bool ( 0.1 ) {
42+ nodes[ rng. gen_range ( 0 ..nodes. len ( ) ) ] . cost
4343 } else if rng. gen_bool ( 0.05 ) {
44- return Cost :: default ( ) ;
44+ Cost :: default ( )
4545 } else {
46- return generate_random_not_nan ( ) * 100.0 ;
46+ generate_random_not_nan ( ) * 100.0
4747 }
4848 } ;
4949
@@ -56,7 +56,7 @@ pub fn generate_random_egraph() -> EGraph {
5656
5757 nodes. push ( Node {
5858 op : "operation" . to_string ( ) ,
59- children : children ,
59+ children,
6060 eclass : eclass. to_string ( ) . clone ( ) . into ( ) ,
6161 cost : get_semi_random_cost ( & nodes) ,
6262 } ) ;
@@ -83,8 +83,8 @@ pub fn generate_random_egraph() -> EGraph {
8383
8484 let mut egraph = EGraph :: default ( ) ;
8585
86- for i in 0 .. nodes. len ( ) {
87- egraph. add_node ( id2nid ( i) , nodes [ i ] . clone ( ) ) ;
86+ for ( i , node ) in nodes. iter ( ) . enumerate ( ) {
87+ egraph. add_node ( id2nid ( i) , node . clone ( ) ) ;
8888 }
8989
9090 // Set roots
@@ -106,42 +106,65 @@ pub fn generate_random_egraph() -> EGraph {
106106 * Checks that the extractions are valid.
107107 */
108108
109+ #[ cfg( feature = "ilp-cbc" ) ]
110+ fn check_dag_optimal (
111+ egraph : & EGraph ,
112+ optimal_dag : & [ Box < dyn Extractor > ] ,
113+ others : & [ Box < dyn Extractor > ] ,
114+ optimal_tree_cost : Option < Cost > ,
115+ ) {
116+ let mut optimal_dag_cost: Option < Cost > = None ;
117+
118+ for e in optimal_dag {
119+ let extract = e. extract ( egraph, & egraph. root_eclasses ) ;
120+ extract. check ( egraph) ;
121+ let dag_cost = extract. dag_cost ( egraph, & egraph. root_eclasses ) ;
122+ let tree_cost = extract. tree_cost ( egraph, & egraph. root_eclasses ) ;
123+ if optimal_dag_cost. is_none ( ) {
124+ optimal_dag_cost = Some ( dag_cost) ;
125+ continue ;
126+ }
127+
128+ assert ! (
129+ ( dag_cost. into_inner( ) - optimal_dag_cost. unwrap( ) . into_inner( ) ) . abs( )
130+ < EPSILON_ALLOWANCE
131+ ) ;
132+
133+ assert ! (
134+ tree_cost. into_inner( ) + EPSILON_ALLOWANCE > optimal_dag_cost. unwrap( ) . into_inner( )
135+ ) ;
136+ }
137+
138+ if let ( Some ( dag_cost) , Some ( tree_cost) ) = ( optimal_dag_cost, optimal_tree_cost) {
139+ assert ! ( dag_cost < tree_cost + EPSILON_ALLOWANCE ) ;
140+ }
141+
142+ if let Some ( optimal_dag_cost) = optimal_dag_cost {
143+ for e in others {
144+ let extract = e. extract ( egraph, & egraph. root_eclasses ) ;
145+ let dag_cost = extract. dag_cost ( egraph, & egraph. root_eclasses ) ;
146+ // The optimal dag should be <= any extractor's dag cost
147+ assert ! ( optimal_dag_cost <= dag_cost + EPSILON_ALLOWANCE ) ;
148+ }
149+ }
150+ }
151+
109152fn check_optimal_results < I : Iterator < Item = EGraph > > ( egraphs : I ) {
153+ #[ cfg( feature = "ilp-cbc" ) ]
110154 let mut optimal_dag: Vec < Box < dyn Extractor > > = Default :: default ( ) ;
111155 let mut optimal_tree: Vec < Box < dyn Extractor > > = Default :: default ( ) ;
112156 let mut others: Vec < Box < dyn Extractor > > = Default :: default ( ) ;
113157
114158 for ( _, ed) in extractors ( ) . into_iter ( ) {
115159 match ed. optimal {
116- Optimal :: DAG => optimal_dag. push ( ed. extractor ) ,
160+ #[ cfg( feature = "ilp-cbc" ) ]
161+ Optimal :: Dag => optimal_dag. push ( ed. extractor ) ,
117162 Optimal :: Tree => optimal_tree. push ( ed. extractor ) ,
118163 Optimal :: Neither => others. push ( ed. extractor ) ,
119164 }
120165 }
121166
122167 for egraph in egraphs {
123- let mut optimal_dag_cost: Option < Cost > = None ;
124-
125- for e in & optimal_dag {
126- let extract = e. extract ( & egraph, & egraph. root_eclasses ) ;
127- extract. check ( & egraph) ;
128- let dag_cost = extract. dag_cost ( & egraph, & egraph. root_eclasses ) ;
129- let tree_cost = extract. tree_cost ( & egraph, & egraph. root_eclasses ) ;
130- if optimal_dag_cost. is_none ( ) {
131- optimal_dag_cost = Some ( dag_cost) ;
132- continue ;
133- }
134-
135- assert ! (
136- ( dag_cost. into_inner( ) - optimal_dag_cost. unwrap( ) . into_inner( ) ) . abs( )
137- < EPSILON_ALLOWANCE
138- ) ;
139-
140- assert ! (
141- tree_cost. into_inner( ) + EPSILON_ALLOWANCE > optimal_dag_cost. unwrap( ) . into_inner( )
142- ) ;
143- }
144-
145168 let mut optimal_tree_cost: Option < Cost > = None ;
146169
147170 for e in & optimal_tree {
@@ -159,26 +182,19 @@ fn check_optimal_results<I: Iterator<Item = EGraph>>(egraphs: I) {
159182 ) ;
160183 }
161184
162- if optimal_dag_cost. is_some ( ) && optimal_tree_cost. is_some ( ) {
163- assert ! ( optimal_dag_cost. unwrap( ) < optimal_tree_cost. unwrap( ) + EPSILON_ALLOWANCE ) ;
164- }
165-
166185 for e in & others {
167186 let extract = e. extract ( & egraph, & egraph. root_eclasses ) ;
168187 extract. check ( & egraph) ;
169188 let tree_cost = extract. tree_cost ( & egraph, & egraph. root_eclasses ) ;
170- let dag_cost = extract. dag_cost ( & egraph, & egraph. root_eclasses ) ;
171189
172190 // The optimal tree cost should be <= any extractor's tree cost.
173- if optimal_tree_cost. is_some ( ) {
174- assert ! ( optimal_tree_cost. unwrap( ) <= tree_cost + EPSILON_ALLOWANCE ) ;
175- }
176-
177- if optimal_dag_cost. is_some ( ) {
178- // The optimal dag should be less <= any extractor's dag cost
179- assert ! ( optimal_dag_cost. unwrap( ) <= dag_cost + EPSILON_ALLOWANCE ) ;
191+ if let Some ( optimal_tree_cost) = optimal_tree_cost {
192+ assert ! ( optimal_tree_cost <= tree_cost + EPSILON_ALLOWANCE ) ;
180193 }
181194 }
195+
196+ #[ cfg( feature = "ilp-cbc" ) ]
197+ check_dag_optimal ( & egraph, & optimal_dag, & others, optimal_tree_cost) ;
182198 }
183199}
184200
@@ -201,6 +217,7 @@ fn run_on_test_egraphs() {
201217
202218#[ test]
203219#[ should_panic]
220+ #[ allow( clippy:: assertions_on_constants) ]
204221fn check_assert_enabled ( ) {
205222 assert ! ( false ) ;
206223}
@@ -210,8 +227,8 @@ macro_rules! create_optimal_check_tests {
210227 $(
211228 #[ test]
212229 fn $name( ) {
213- let optimal_dag_found = extractors ( ) . into_iter ( ) . any ( | ( _ , ed ) | ed . optimal == Optimal :: DAG ) ;
214- let iterations = if optimal_dag_found { 100 } else { 10000 } ;
230+ // Fewer iterations when ilp-cbc is enabled since it's slow
231+ let iterations = if cfg! ( feature = "ilp-cbc" ) { 100 } else { 10000 } ;
215232 let egraphs = ( 0 ..iterations) . map( |_| generate_random_egraph( ) ) ;
216233 check_optimal_results( egraphs) ;
217234 }
0 commit comments