mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
fixes to sat-par
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
7aeaf11ee4
commit
fe105d94a0
5 changed files with 78 additions and 51 deletions
|
@ -352,9 +352,6 @@ public:
|
|||
while (is_sat == l_false) {
|
||||
core.reset();
|
||||
s().get_unsat_core(core);
|
||||
expr_ref_vector core1(m);
|
||||
core1.append(core.size(), core.c_ptr());
|
||||
std::cout << core1 << "\n";
|
||||
// verify_core(core);
|
||||
model_ref mdl;
|
||||
get_mus_model(mdl);
|
||||
|
|
|
@ -378,7 +378,7 @@ namespace sat {
|
|||
if (offset > m_bound) {
|
||||
m_coeffs[v] = (get_coeff(v) < 0) ? -m_bound : m_bound;
|
||||
offset = m_bound;
|
||||
// TBD: also adjust coefficient in m_A.
|
||||
DEBUG_CODE(active2pb(m_A););
|
||||
}
|
||||
SASSERT(value(consequent) == l_true);
|
||||
|
||||
|
@ -424,7 +424,7 @@ namespace sat {
|
|||
m_lemma.push_back(~lit);
|
||||
if (lvl(lit) == m_conflict_lvl) {
|
||||
TRACE("sat", tout << "Bail out on no progress " << lit << "\n";);
|
||||
IF_VERBOSE(1, verbose_stream() << "bail cardinality lemma\n";);
|
||||
IF_VERBOSE(3, verbose_stream() << "(sat.card bail resolve)\n";);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,12 @@ namespace sat {
|
|||
if (m_tail >= m_size) {
|
||||
// move tail to the front.
|
||||
for (unsigned i = 0; i < m_heads.size(); ++i) {
|
||||
// the tail could potentially loop around full circle before one of the heads picks up anything.
|
||||
// in this case the we miss the newly inserted record.
|
||||
while (m_heads[i] < capacity) {
|
||||
next(m_heads[i]);
|
||||
}
|
||||
IF_VERBOSE(3, verbose_stream() << owner << ": head: " << m_heads[i] << "\n";);
|
||||
IF_VERBOSE(3, verbose_stream() << owner << ": head: " << m_heads[i] << "\n";);
|
||||
}
|
||||
m_tail = 0;
|
||||
}
|
||||
|
@ -75,8 +77,8 @@ namespace sat {
|
|||
|
||||
bool par::vector_pool::get_vector(unsigned owner, unsigned& n, unsigned const*& ptr) {
|
||||
unsigned head = m_heads[owner];
|
||||
SASSERT(head < m_size);
|
||||
while (head != m_tail) {
|
||||
SASSERT(head < m_size);
|
||||
IF_VERBOSE(3, verbose_stream() << owner << ": head: " << head << " tail: " << m_tail << "\n";);
|
||||
bool is_self = owner == get_owner(head);
|
||||
next(m_heads[owner]);
|
||||
|
@ -86,11 +88,40 @@ namespace sat {
|
|||
return true;
|
||||
}
|
||||
head = m_heads[owner];
|
||||
if (head == 0 && m_tail >= m_size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
par::par() {}
|
||||
par::par(solver& s): m_scoped_rlimit(s.rlimit()) {}
|
||||
|
||||
par::~par() {
|
||||
for (unsigned i = 0; i < m_solvers.size(); ++i) {
|
||||
dealloc(m_solvers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void par::init_solvers(solver& s, unsigned num_extra_solvers) {
|
||||
unsigned num_threads = num_extra_solvers + 1;
|
||||
m_solvers.resize(num_extra_solvers, 0);
|
||||
symbol saved_phase = s.m_params.get_sym("phase", symbol("caching"));
|
||||
for (unsigned i = 0; i < num_extra_solvers; ++i) {
|
||||
m_limits.push_back(reslimit());
|
||||
s.m_params.set_uint("random_seed", s.m_rand());
|
||||
if (i == 1 + num_threads/2) {
|
||||
s.m_params.set_sym("phase", symbol("random"));
|
||||
}
|
||||
m_solvers[i] = alloc(sat::solver, s.m_params, m_limits[i], 0);
|
||||
m_solvers[i]->copy(s);
|
||||
m_solvers[i]->set_par(this, i);
|
||||
m_scoped_rlimit.push_child(&m_solvers[i]->rlimit());
|
||||
}
|
||||
s.set_par(this, num_extra_solvers);
|
||||
s.m_params.set_sym("phase", saved_phase);
|
||||
}
|
||||
|
||||
|
||||
void par::exchange(solver& s, literal_vector const& in, unsigned& limit, literal_vector& out) {
|
||||
if (s.m_par_syncing_clauses) return;
|
||||
|
@ -125,18 +156,16 @@ namespace sat {
|
|||
}
|
||||
|
||||
void par::share_clause(solver& s, clause const& c) {
|
||||
if (s.m_par_syncing_clauses) return;
|
||||
if (!enable_add(c) || s.m_par_syncing_clauses) return;
|
||||
flet<bool> _disable_sync_clause(s.m_par_syncing_clauses, true);
|
||||
unsigned n = c.size();
|
||||
unsigned owner = s.m_par_id;
|
||||
#pragma omp critical (par_solver)
|
||||
{
|
||||
if (enable_add(c)) {
|
||||
IF_VERBOSE(3, verbose_stream() << owner << ": share " << c << "\n";);
|
||||
m_pool.begin_add_vector(owner, n);
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
m_pool.add_vector_elem(c[i].index());
|
||||
}
|
||||
IF_VERBOSE(3, verbose_stream() << owner << ": share " << c << "\n";);
|
||||
m_pool.begin_add_vector(owner, n);
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
m_pool.add_vector_elem(c[i].index());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ Revision History:
|
|||
#include"sat_types.h"
|
||||
#include"hashtable.h"
|
||||
#include"map.h"
|
||||
#include"rlimit.h"
|
||||
|
||||
namespace sat {
|
||||
|
||||
|
@ -53,13 +54,26 @@ namespace sat {
|
|||
index_set m_unit_set;
|
||||
literal_vector m_lits;
|
||||
vector_pool m_pool;
|
||||
|
||||
scoped_limits m_scoped_rlimit;
|
||||
vector<reslimit> m_limits;
|
||||
ptr_vector<solver> m_solvers;
|
||||
|
||||
public:
|
||||
|
||||
par();
|
||||
par(solver& s);
|
||||
|
||||
~par();
|
||||
|
||||
void init_solvers(solver& s, unsigned num_extra_solvers);
|
||||
|
||||
// reserve space
|
||||
void reserve(unsigned num_owners, unsigned sz) { m_pool.reserve(num_owners, sz); }
|
||||
|
||||
solver& get_solver(unsigned i) { return *m_solvers[i]; }
|
||||
|
||||
void cancel_solver(unsigned i) { m_limits[i].cancel(); }
|
||||
|
||||
// exchange unit literals
|
||||
void exchange(solver& s, literal_vector const& in, unsigned& limit, literal_vector& out);
|
||||
|
||||
|
|
|
@ -835,35 +835,21 @@ namespace sat {
|
|||
lbool solver::check_par(unsigned num_lits, literal const* lits) {
|
||||
int num_threads = static_cast<int>(m_config.m_num_parallel);
|
||||
int num_extra_solvers = num_threads - 1;
|
||||
scoped_limits scoped_rlimit(rlimit());
|
||||
vector<reslimit> rlims(num_extra_solvers);
|
||||
ptr_vector<sat::solver> solvers(num_extra_solvers);
|
||||
sat::par par;
|
||||
par.reserve(num_threads, 1 << 9);
|
||||
symbol saved_phase = m_params.get_sym("phase", symbol("caching"));
|
||||
for (int i = 0; i < num_extra_solvers; ++i) {
|
||||
m_params.set_uint("random_seed", m_rand());
|
||||
if (i == 1 + num_threads/2) {
|
||||
m_params.set_sym("phase", symbol("random"));
|
||||
}
|
||||
solvers[i] = alloc(sat::solver, m_params, rlims[i], 0);
|
||||
solvers[i]->copy(*this);
|
||||
solvers[i]->set_par(&par, i);
|
||||
scoped_rlimit.push_child(&solvers[i]->rlimit());
|
||||
}
|
||||
set_par(&par, num_extra_solvers);
|
||||
m_params.set_sym("phase", saved_phase);
|
||||
sat::par par(*this);
|
||||
par.reserve(num_threads, 1 << 16);
|
||||
par.init_solvers(*this, num_extra_solvers);
|
||||
int finished_id = -1;
|
||||
std::string ex_msg;
|
||||
par_exception_kind ex_kind;
|
||||
unsigned error_code = 0;
|
||||
lbool result = l_undef;
|
||||
bool canceled = false;
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < num_threads; ++i) {
|
||||
try {
|
||||
lbool r = l_undef;
|
||||
if (i < num_extra_solvers) {
|
||||
r = solvers[i]->check(num_lits, lits);
|
||||
r = par.get_solver(i).check(num_lits, lits);
|
||||
}
|
||||
else {
|
||||
r = check(num_lits, lits);
|
||||
|
@ -879,40 +865,40 @@ namespace sat {
|
|||
}
|
||||
if (first) {
|
||||
if (r == l_true && i < num_extra_solvers) {
|
||||
set_model(solvers[i]->get_model());
|
||||
set_model(par.get_solver(i).get_model());
|
||||
}
|
||||
else if (r == l_false && i < num_extra_solvers) {
|
||||
m_core.reset();
|
||||
m_core.append(solvers[i]->get_core());
|
||||
m_core.append(par.get_solver(i).get_core());
|
||||
}
|
||||
for (int j = 0; j < num_extra_solvers; ++j) {
|
||||
if (i != j) {
|
||||
rlims[j].cancel();
|
||||
par.cancel_solver(j);
|
||||
}
|
||||
}
|
||||
if (i != num_extra_solvers) {
|
||||
canceled = rlimit().inc();
|
||||
rlimit().cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (z3_error & err) {
|
||||
if (i == 0) {
|
||||
error_code = err.error_code();
|
||||
ex_kind = ERROR_EX;
|
||||
}
|
||||
error_code = err.error_code();
|
||||
ex_kind = ERROR_EX;
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
if (i == 0) {
|
||||
ex_msg = ex.msg();
|
||||
ex_kind = DEFAULT_EX;
|
||||
}
|
||||
ex_msg = ex.msg();
|
||||
ex_kind = DEFAULT_EX;
|
||||
}
|
||||
}
|
||||
set_par(0, 0);
|
||||
if (finished_id != -1 && finished_id < num_extra_solvers) {
|
||||
m_stats = solvers[finished_id]->m_stats;
|
||||
m_stats = par.get_solver(finished_id).m_stats;
|
||||
}
|
||||
if (!canceled) {
|
||||
rlimit().reset_cancel();
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_extra_solvers; ++i) {
|
||||
dealloc(solvers[i]);
|
||||
}
|
||||
if (finished_id == -1) {
|
||||
switch (ex_kind) {
|
||||
case ERROR_EX: throw z3_error(error_code);
|
||||
|
@ -1728,10 +1714,10 @@ namespace sat {
|
|||
|
||||
bool solver::resolve_conflict_core() {
|
||||
|
||||
m_stats.m_conflict++;
|
||||
m_conflicts++;
|
||||
m_conflicts_since_restart++;
|
||||
m_conflicts_since_gc++;
|
||||
m_stats.m_conflict++;
|
||||
|
||||
m_conflict_lvl = get_max_lvl(m_not_l, m_conflict);
|
||||
TRACE("sat", tout << "conflict detected at level " << m_conflict_lvl << " for ";
|
||||
|
@ -1751,6 +1737,7 @@ namespace sat {
|
|||
|
||||
if (m_ext && m_ext->resolve_conflict()) {
|
||||
learn_lemma_and_backjump();
|
||||
m_stats.m_conflict--;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue