@@ -63,6 +63,48 @@ impl PerfStats {
6363 pub fn iterations ( & self ) -> u64 {
6464 self . iterations . get ( )
6565 }
66+
67+ fn add_time_normalize ( & self , dt : f64 ) {
68+ self . time_normalize . set ( self . time_normalize . get ( ) + dt) ;
69+ }
70+
71+ fn add_time_encode ( & self , dt : f64 ) {
72+ self . time_encode . set ( self . time_encode . get ( ) + dt) ;
73+ }
74+
75+ fn add_time_sat_solver ( & self , dt : f64 ) {
76+ self . time_sat_solver . set ( self . time_sat_solver . get ( ) + dt) ;
77+ }
78+
79+ fn update_solver_stats ( & self , stats : & crate :: sat:: SATSolverStats ) {
80+ if let Some ( decisions) = stats. decisions {
81+ self . decisions . set ( decisions) ;
82+ }
83+ if let Some ( propagations) = stats. propagations {
84+ self . propagations . set ( propagations) ;
85+ }
86+ if let Some ( conflicts) = stats. conflicts {
87+ self . conflicts . set ( conflicts) ;
88+ }
89+ }
90+ }
91+
92+ thread_local ! {
93+ static THREAD_LOCAL_PERF_STATS : std:: cell:: RefCell <PerfStats > =
94+ std:: cell:: RefCell :: new( PerfStats :: new( ) ) ;
95+ }
96+
97+ /// Returns a clone of the `PerfStats` accumulated in thread-local storage.
98+ ///
99+ /// This is populated only for solvers created with `Config::record_perf_stats_thread_local`
100+ /// set to `true`; otherwise it stays at its initial (zero) values.
101+ pub fn thread_local_perf_stats ( ) -> PerfStats {
102+ THREAD_LOCAL_PERF_STATS . with ( |stats| stats. borrow ( ) . clone ( ) )
103+ }
104+
105+ /// Resets the `PerfStats` accumulated in thread-local storage to their initial values.
106+ pub fn reset_thread_local_perf_stats ( ) {
107+ THREAD_LOCAL_PERF_STATS . with ( |stats| * stats. borrow_mut ( ) = PerfStats :: new ( ) ) ;
66108}
67109
68110pub struct IntegratedSolver < ' a > {
@@ -129,6 +171,15 @@ impl<'a> IntegratedSolver<'a> {
129171 self . add_constraint ( Stmt :: Expr ( expr) )
130172 }
131173
174+ fn record_perf_stats ( & self , f : impl Fn ( & PerfStats ) ) {
175+ if let Some ( perf_stats) = self . perf_stats {
176+ f ( perf_stats) ;
177+ }
178+ if self . config . record_perf_stats_thread_local {
179+ THREAD_LOCAL_PERF_STATS . with ( |stats| f ( & stats. borrow ( ) ) ) ;
180+ }
181+ }
182+
132183 pub fn encode ( & mut self ) -> bool {
133184 let is_first = !self . already_used ;
134185 self . already_used = true ;
@@ -151,11 +202,8 @@ impl<'a> IntegratedSolver<'a> {
151202 & mut self . normalize_map ,
152203 & self . config ,
153204 ) ;
154- if let Some ( perf_stats) = self . perf_stats {
155- perf_stats
156- . time_normalize
157- . set ( perf_stats. time_normalize ( ) + start. elapsed ( ) . as_secs_f64 ( ) ) ;
158- }
205+ let dt = start. elapsed ( ) . as_secs_f64 ( ) ;
206+ self . record_perf_stats ( |perf_stats| perf_stats. add_time_normalize ( dt) ) ;
159207
160208 if is_first && self . config . use_norm_domain_refinement {
161209 self . norm . refine_domain ( ) ;
@@ -171,23 +219,10 @@ impl<'a> IntegratedSolver<'a> {
171219 & mut self . encode_map ,
172220 & self . config ,
173221 ) ;
174- if let Some ( perf_stats) = self . perf_stats {
175- perf_stats
176- . time_encode
177- . set ( perf_stats. time_encode ( ) + start. elapsed ( ) . as_secs_f64 ( ) ) ;
178- }
222+ let dt = start. elapsed ( ) . as_secs_f64 ( ) ;
223+ self . record_perf_stats ( |perf_stats| perf_stats. add_time_encode ( dt) ) ;
179224 let solver_stats = self . sat . stats ( ) ;
180- if let Some ( perf_stats) = self . perf_stats {
181- if let Some ( decisions) = solver_stats. decisions {
182- perf_stats. decisions . set ( decisions) ;
183- }
184- if let Some ( propagations) = solver_stats. propagations {
185- perf_stats. propagations . set ( propagations) ;
186- }
187- if let Some ( conflicts) = solver_stats. conflicts {
188- perf_stats. conflicts . set ( conflicts) ;
189- }
190- }
225+ self . record_perf_stats ( |perf_stats| perf_stats. update_solver_stats ( & solver_stats) ) ;
191226 true
192227 }
193228
@@ -201,23 +236,10 @@ impl<'a> IntegratedSolver<'a> {
201236 } else {
202237 None
203238 } ;
204- if let Some ( perf_stats) = self . perf_stats {
205- perf_stats
206- . time_sat_solver
207- . set ( perf_stats. time_sat_solver ( ) + start. elapsed ( ) . as_secs_f64 ( ) ) ;
208- }
239+ let dt = start. elapsed ( ) . as_secs_f64 ( ) ;
240+ self . record_perf_stats ( |perf_stats| perf_stats. add_time_sat_solver ( dt) ) ;
209241 let solver_stats = self . sat . stats ( ) ;
210- if let Some ( perf_stats) = self . perf_stats {
211- if let Some ( decisions) = solver_stats. decisions {
212- perf_stats. decisions . set ( decisions) ;
213- }
214- if let Some ( propagations) = solver_stats. propagations {
215- perf_stats. propagations . set ( propagations) ;
216- }
217- if let Some ( conflicts) = solver_stats. conflicts {
218- perf_stats. conflicts . set ( conflicts) ;
219- }
220- }
242+ self . record_perf_stats ( |perf_stats| perf_stats. update_solver_stats ( & solver_stats) ) ;
221243
222244 match solver_result {
223245 Some ( model) => Some ( Model {
@@ -330,9 +352,7 @@ impl<'a> IntegratedSolver<'a> {
330352 }
331353 }
332354
333- if let Some ( perf_stats) = self . perf_stats {
334- perf_stats. iterations . set ( iterations) ;
335- }
355+ self . record_perf_stats ( |perf_stats| perf_stats. iterations . set ( iterations) ) ;
336356
337357 Some ( assignment)
338358 }
0 commit comments