#ifndef QUIET #include "internal.h" #include "resources.h" #include "sort.h" #include #include void kissat_init_profiles (profiles * profiles) { #define PROF(NAME,LEVEL) \ profiles->NAME = (profile) { LEVEL, #NAME, 0, 0 }; PROFS #undef PROF } #define SIZE_PROFS (sizeof (profiles) / sizeof (profile)) static inline bool less_profile (profile * p, profile * q) { if (p->time > q->time) return true; if (p->time < q->time) return false; return strcmp (p->name, q->name) < 0; } static void print_profile (profile * p, double total) { printf ("c %14.2f %7.2f %% %s\n", p->time, kissat_percent (p->time, total), p->name); } static double flush_profile (profile * profile, double now) { const double delta = now - profile->entered; profile->time += delta; profile->entered = now; return delta; } static void flush_profiles (profiles * profiles, const double now) { for (all_pointers (profile, p, profiles->stack)) flush_profile (p, now); } static void push_profile (kissat * solver, profile * profile, double now) { profile->entered = now; PUSH_STACK (solver->profiles.stack, profile); } void kissat_profiles_print (kissat * solver) { profiles *named = &solver->profiles; double now = kissat_process_time (); flush_profiles (named, now); profile *unsorted = (profile *) named; profile *sorted[SIZE_PROFS]; const profile *end = unsorted + SIZE_PROFS; size_t size = 0; for (profile * p = unsorted; p != end; p++) if (p->level <= GET_OPTION (profile) && (p == &named->search || p == &named->simplify || (p != &named->total && p->time))) sorted[size++] = p; INSERTION_SORT (profile *, size, sorted, less_profile); const double total = named->total.time; for (size_t i = 0; i < size; i++) print_profile (sorted[i], total); printf ("c =============================================\n"); print_profile (&named->total, total); } void kissat_start (kissat * solver, profile * profile) { const double now = kissat_process_time (); push_profile (solver, profile, now); } void kissat_stop (kissat * solver, profile * profile) { assert (TOP_STACK (solver->profiles.stack) == profile); (void) POP_STACK (solver->profiles.stack); const double now = kissat_process_time (); flush_profile (profile, now); } void kissat_stop_search_and_start_simplifier (kissat * solver, profile * profile) { struct profile *search = &PROFILE (search); assert (search->level <= GET_OPTION (profile)); const double now = kissat_process_time (); while (TOP_STACK (solver->profiles.stack) != search) { struct profile *mode = POP_STACK (solver->profiles.stack); assert (search->level <= mode->level); #ifndef NDEBUG if (solver->stable) assert (mode == &PROFILE (stable)); else assert (mode == &PROFILE (focused)); #endif flush_profile (mode, now); } (void) POP_STACK (solver->profiles.stack); struct profile *simplify = &PROFILE (simplify); assert (search->level == simplify->level); assert (simplify->level <= profile->level); flush_profile (search, now); push_profile (solver, simplify, now); if (profile->level <= GET_OPTION (profile)) push_profile (solver, profile, now); } void kissat_stop_simplifier_and_resume_search (kissat * solver, profile * profile) { struct profile *simplify = &PROFILE (simplify); struct profile *top = POP_STACK (solver->profiles.stack); const double now = kissat_process_time (); const double delta = flush_profile (simplify, now); #ifndef NDEBUG const double entered = now - delta; assert (solver->mode.entered <= entered); #endif solver->mode.entered += delta; if (top == profile) { flush_profile (profile, now); assert (TOP_STACK (solver->profiles.stack) == simplify); (void) POP_STACK (solver->profiles.stack); } else { assert (simplify == top); assert (profile->level > GET_OPTION (profile)); } #ifndef NDEBUG struct profile *search = &PROFILE (search); assert (search->level == simplify->level); #endif assert (simplify->level <= profile->level); push_profile (solver, &PROFILE (search), now); struct profile *mode = solver->stable ? &PROFILE (stable) : &PROFILE (focused); assert (search->level <= mode->level); if (mode->level <= GET_OPTION (profile)) push_profile (solver, mode, now); } double kissat_time (kissat * solver) { const double now = kissat_process_time (); flush_profiles (&solver->profiles, now); return PROFILE (total).time; } #else int kissat_profile_dummy_to_avoid_warning; #endif