diff --git a/src/sat/sat_clause.cpp b/src/sat/sat_clause.cpp index f9caffe94..78d62bac0 100644 --- a/src/sat/sat_clause.cpp +++ b/src/sat/sat_clause.cpp @@ -95,7 +95,6 @@ namespace sat { } } - bool clause::satisfied_by(model const & m) const { for (literal l : *this) { if (l.sign()) { @@ -110,6 +109,23 @@ namespace sat { return false; } + clause_offset clause::get_new_offset() const { + unsigned o1 = m_lits[0].index(); + if (sizeof(clause_offset) == 8) { + unsigned o2 = m_lits[1].index(); + return (clause_offset)o1 + (((clause_offset)o2) << 32); + } + return (clause_offset)o1; + } + + void clause::set_new_offset(clause_offset offset) { + m_lits[0] = to_literal(static_cast(offset)); + if (sizeof(offset) == 8) { + m_lits[1] = to_literal(static_cast(offset >> 32)); + } + } + + void tmp_clause::set(unsigned num_lits, literal const * lits, bool learned) { if (m_clause && m_clause->m_capacity < num_lits) { dealloc_svect(m_clause); diff --git a/src/sat/sat_clause.h b/src/sat/sat_clause.h index c42427afb..8b2d113c8 100644 --- a/src/sat/sat_clause.h +++ b/src/sat/sat_clause.h @@ -98,6 +98,8 @@ namespace sat { unsigned glue() const { return m_glue; } void set_psm(unsigned psm) { m_psm = psm > 255 ? 255 : psm; } unsigned psm() const { return m_psm; } + clause_offset get_new_offset() const; + void set_new_offset(clause_offset off); bool on_reinit_stack() const { return m_reinit_stack; } void set_reinit_stack(bool f) { m_reinit_stack = f; } diff --git a/src/sat/sat_local_search.cpp b/src/sat/sat_local_search.cpp index 35e371a9c..e02560e5f 100644 --- a/src/sat/sat_local_search.cpp +++ b/src/sat/sat_local_search.cpp @@ -79,11 +79,13 @@ namespace sat { void local_search::init_cur_solution() { for (var_info& vi : m_vars) { // use bias with a small probability - if (m_rand() % 10 < 5 || m_config.phase_sticky()) { - vi.m_value = ((unsigned)(m_rand() % 100) < vi.m_bias); - } - else { - vi.m_value = (m_rand() % 2) == 0; + if (!vi.m_unit) { + if (m_rand() % 10 < 5 || m_config.phase_sticky()) { + vi.m_value = ((unsigned)(m_rand() % 100) < vi.m_bias); + } + else { + vi.m_value = (m_rand() % 2) == 0; + } } } } @@ -149,7 +151,7 @@ namespace sat { void local_search::reinit() { - IF_VERBOSE(0, verbose_stream() << "(sat-local-search reinit)\n";); + IF_VERBOSE(1, verbose_stream() << "(sat-local-search reinit)\n";); if (true || !m_is_pb) { // // the following methods does NOT converge for pseudo-boolean @@ -216,13 +218,15 @@ namespace sat { for (unsigned i = 0; i < m_prop_queue.size() && i < m_vars.size(); ++i) { literal lit2 = m_prop_queue[i]; if (!is_true(lit2)) { - if (is_unit(lit2)) return false; + if (is_unit(lit2)) { + return false; + } flip_walksat(lit2.var()); add_propagation(lit2); } } if (m_prop_queue.size() >= m_vars.size()) { - IF_VERBOSE(0, verbose_stream() << "failed literal\n"); + IF_VERBOSE(0, verbose_stream() << "propagation loop\n"); return false; } if (unit) { @@ -328,6 +332,7 @@ namespace sat { return; } if (k == 1 && sz == 2) { + // IF_VERBOSE(0, verbose_stream() << "bin: " << ~c[0] << " + " << ~c[1] << " <= 1\n"); for (unsigned i = 0; i < 2; ++i) { literal t(c[i]), s(c[1-i]); m_vars.reserve(t.var() + 1); @@ -750,11 +755,12 @@ namespace sat { IF_VERBOSE(1, verbose_stream() << "(sat.local_search :unsat)\n"); return; } - + if (is_unit(best_var)) { + goto reflip; + } flip_walksat(best_var); literal lit(best_var, !cur_solution(best_var)); if (!propagate(lit)) { - IF_VERBOSE(0, verbose_stream() << "failed literal " << lit << "\n"); if (is_true(lit)) { flip_walksat(best_var); } @@ -774,6 +780,7 @@ namespace sat { } void local_search::flip_walksat(bool_var flipvar) { + VERIFY(!is_unit(flipvar)); m_vars[flipvar].m_value = !cur_solution(flipvar); bool flip_is_true = cur_solution(flipvar); diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 792883977..90ac876d2 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -529,26 +529,26 @@ namespace sat { IF_VERBOSE(1, verbose_stream() << "(sat-defrag)\n"); clause_allocator& alloc = m_cls_allocator[!m_cls_allocator_idx]; ptr_vector new_clauses, new_learned; - ptr_addr_map cls2offset; for (clause* c : m_clauses) c->unmark_used(); for (clause* c : m_learned) c->unmark_used(); +#if 0 svector vars; for (unsigned i = 0; i < num_vars(); ++i) vars.push_back(i); std::stable_sort(vars.begin(), vars.end(), cmp_activity(*this)); literal_vector lits; for (bool_var v : vars) lits.push_back(to_literal(v)), lits.push_back(~to_literal(v)); - // walk clauses, reallocate them in an order that defragments memory and creates locality. //for (literal lit : lits) { //watch_list& wlist = m_watches[lit.index()]; +#endif for (watch_list& wlist : m_watches) { for (watched& w : wlist) { if (w.is_clause()) { clause& c1 = get_clause(w); clause_offset offset; if (c1.was_used()) { - offset = cls2offset[&c1]; + offset = c1.get_new_offset(); } else { clause* c2 = alloc.copy_clause(c1); @@ -560,7 +560,7 @@ namespace sat { new_clauses.push_back(c2); } offset = get_offset(*c2); - cls2offset.insert(&c1, offset); + c1.set_new_offset(offset); } w = watched(w.get_blocked_literal(), offset); } diff --git a/src/solver/parallel_params.pyg b/src/solver/parallel_params.pyg index 58c00aa97..2d58cbb81 100644 --- a/src/solver/parallel_params.pyg +++ b/src/solver/parallel_params.pyg @@ -5,7 +5,7 @@ def_module_params('parallel', params=( ('enable', BOOL, False, 'enable parallel solver by default on selected tactics (for QF_BV)'), ('threads.max', UINT, 10000, 'caps maximal number of threads below the number of processors'), - ('conquer.batch_size', UINT, 1000, 'number of cubes to batch together for fast conquer'), + ('conquer.batch_size', UINT, 100, 'number of cubes to batch together for fast conquer'), ('conquer.restart.max', UINT, 5, 'maximal number of restarts during conquer phase'), ('conquer.delay', UINT, 10, 'delay of cubes until applying conquer'), ('conquer.backtrack_frequency', UINT, 10, 'frequency to apply core minimization during conquer'), diff --git a/src/solver/parallel_tactic.cpp b/src/solver/parallel_tactic.cpp index 748ee5d64..ac147672e 100644 --- a/src/solver/parallel_tactic.cpp +++ b/src/solver/parallel_tactic.cpp @@ -99,6 +99,8 @@ class parallel_tactic : public tactic { } } + bool in_shutdown() const { return m_shutdown; } + void add_task(solver_state* task) { std::lock_guard lock(m_mutex); m_tasks.push_back(task); @@ -285,6 +287,7 @@ class parallel_tactic : public tactic { p.set_uint("restart.max", pp.simplify_restart_max() * mult); p.set_bool("lookahead_simplify", true); p.set_bool("retain_blocked_clauses", retain_blocked); + if (m_depth > 1) p.set_uint("bce_delay", 0); get_solver().updt_params(p); } @@ -479,8 +482,8 @@ private: break; } - if (cubes.size() >= conquer_batch_size() || (!cubes.empty() && m_queue.is_idle())) { - spawn_cubes(s, std::max(2u, width), cubes); + if (cubes.size() >= conquer_batch_size()) { + spawn_cubes(s, 10*width, cubes); first = false; cubes.reset(); } @@ -575,6 +578,7 @@ private: } catch (z3_exception& ex) { IF_VERBOSE(1, verbose_stream() << ex.msg() << "\n";); + if (m_queue.in_shutdown()) return; m_queue.shutdown(); std::lock_guard lock(m_mutex); if (ex.has_error_code()) {