@@ -48,6 +48,12 @@ pub struct TuneGroup<K> {
4848 pub ( crate ) priority : PriorityFunc < K > ,
4949}
5050
51+ impl < K > core:: fmt:: Debug for TuneGroup < K > {
52+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
53+ f. debug_struct ( "TuneGroup" ) . field ( "id" , & self . id ) . finish ( )
54+ }
55+ }
56+
5157impl < K > Clone for TuneGroup < K > {
5258 fn clone ( & self ) -> Self {
5359 Self {
@@ -83,9 +89,12 @@ struct GroupPlan {
8389 indices : HashMap < i8 , Vec < usize > > ,
8490}
8591
92+ #[ derive( Debug ) ]
8693struct Cleanup {
8794 groups : Vec < i8 > ,
8895 tunables : Vec < ( i8 , i8 ) > ,
96+ /// Within group priority is too low to even try.
97+ skipped : bool ,
8998}
9099
91100impl TunePlan {
@@ -154,13 +163,22 @@ impl TunePlan {
154163 } ;
155164
156165 let ( mut group_indices, cleanup) = self . group_plan_next ( priority) ;
166+ // Some entries are skipped for this round of prioritizing.
167+ let skipped = cleanup. skipped || priority < 0 ;
168+
157169 self . cleanup ( cleanup) ;
158170
159171 if priority >= 0 {
160172 indices. append ( & mut group_indices) ;
161173 }
162174
163- indices
175+ // The indices list is empty, but it doesn't mean we should stop
176+ // autotuning, since some entries were skipped.
177+ if indices. is_empty ( ) && skipped {
178+ self . next ( )
179+ } else {
180+ indices
181+ }
164182 }
165183
166184 fn cleanup ( & mut self , cleanup : Cleanup ) {
@@ -231,6 +249,7 @@ impl TunePlan {
231249 Cleanup {
232250 groups : cleanup_groups,
233251 tunables : cleanup_tunables,
252+ skipped : within_group_prio < 0 ,
234253 } ,
235254 )
236255 }
@@ -320,6 +339,24 @@ mod tests {
320339 assert ! ( plan. next( ) . is_empty( ) ) ;
321340 }
322341
342+ #[ test]
343+ fn test_plan_negative_priority ( ) {
344+ let group0 = TuneGroup :: < FakeAutotuneKey > :: new ( |_| 2 ) ;
345+ let group1 = TuneGroup :: < FakeAutotuneKey > :: new ( |_| 1 ) ;
346+
347+ let tunable0 = Tunable :: < FakeAutotuneKey , ( ) , ( ) > :: new ( fake_kernel) ;
348+ let tunable1 = Tunable :: < FakeAutotuneKey , ( ) , ( ) > :: new ( fake_kernel) . group ( & group0, |_| -1 ) ;
349+ let tunable2 = Tunable :: < FakeAutotuneKey , ( ) , ( ) > :: new ( fake_kernel) . group ( & group0, |_| 2 ) ;
350+ let tunable3 = Tunable :: < FakeAutotuneKey , ( ) , ( ) > :: new ( fake_kernel) . group ( & group1, |_| 2 ) ;
351+
352+ let key = FakeAutotuneKey ;
353+ let mut plan = TunePlan :: new ( & key, & [ tunable0, tunable1, tunable2, tunable3] ) ;
354+
355+ assert_eq ! ( plan. next( ) , vec![ 0 , 2 ] ) ;
356+ assert_eq ! ( plan. next( ) , vec![ 3 ] ) ;
357+ assert ! ( plan. next( ) . is_empty( ) ) ;
358+ }
359+
323360 #[ test]
324361 fn test_plan_no_group ( ) {
325362 let tunable0 = Tunable :: < FakeAutotuneKey , ( ) , ( ) > :: new ( fake_kernel) ;
0 commit comments