mirror of
https://github.com/Z3Prover/z3
synced 2026-04-15 16:54:11 +00:00
SMTS tree algorithms (#9250)
* Refactor parallel search tree to use global node selection (SMTS-style) instead of DFS traversal. Introduce effort-based prioritization, allow activation of any open node, and add controlled/gated expansion to prevent over-partitioning and improve load balancing. * clean up code * ablations * ablations2: effort * ablations2: activation * ablations3: more activations * ablations4: visit all nodes before splitting * throttle tree size min is based on workers not activated nodes * ablate random throttling * ablate nonlinear effort * clean up code * ablate throttle * ablate where add_effort is * reset * clean up a function and add comment --------- Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MBP.localdomain> Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MacBook-Pro.local> Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MBP.lan1>
This commit is contained in:
parent
c7879ed5ad
commit
ceb363d35d
3 changed files with 199 additions and 83 deletions
|
|
@ -140,7 +140,7 @@ namespace smt {
|
|||
auto atom = get_split_atom();
|
||||
if (!atom)
|
||||
goto check_cube_start;
|
||||
b.split(m_l2g, id, node, atom);
|
||||
b.try_split(m_l2g, id, node, atom, m_config.m_threads_max_conflicts);
|
||||
simplify();
|
||||
break;
|
||||
}
|
||||
|
|
@ -338,22 +338,23 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
void parallel::batch_manager::split(ast_translation &l2g, unsigned source_worker_id,
|
||||
search_tree::node<cube_config> *node, expr *atom) {
|
||||
void parallel::batch_manager::try_split(ast_translation &l2g, unsigned source_worker_id,
|
||||
search_tree::node<cube_config> *node, expr *atom, unsigned effort) {
|
||||
std::scoped_lock lock(mux);
|
||||
expr_ref lit(m), nlit(m);
|
||||
lit = l2g(atom);
|
||||
nlit = mk_not(m, lit);
|
||||
IF_VERBOSE(1, verbose_stream() << "Batch manager splitting on literal: " << mk_bounded_pp(lit, m, 3) << "\n");
|
||||
|
||||
if (m_state != state::is_running)
|
||||
return;
|
||||
// optional heuristic:
|
||||
// node->get_status() == status::active
|
||||
// and depth is 'high' enough
|
||||
// then ignore split, and instead set the status of node to open.
|
||||
++m_stats.m_num_cubes;
|
||||
m_stats.m_max_cube_depth = std::max(m_stats.m_max_cube_depth, node->depth() + 1);
|
||||
m_search_tree.split(node, lit, nlit);
|
||||
|
||||
bool did_split = m_search_tree.try_split(node, lit, nlit, effort);
|
||||
|
||||
if (did_split) {
|
||||
++m_stats.m_num_cubes;
|
||||
m_stats.m_max_cube_depth = std::max(m_stats.m_max_cube_depth, node->depth() + 1);
|
||||
IF_VERBOSE(1, verbose_stream() << "Batch manager splitting on literal: " << mk_bounded_pp(lit, m, 3) << "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void parallel::batch_manager::collect_clause(ast_translation &l2g, unsigned source_worker_id, expr *clause) {
|
||||
|
|
@ -512,8 +513,6 @@ namespace smt {
|
|||
return false;
|
||||
}
|
||||
node *t = m_search_tree.activate_node(n);
|
||||
if (!t)
|
||||
t = m_search_tree.find_active_node();
|
||||
if (!t)
|
||||
return false;
|
||||
IF_VERBOSE(1, m_search_tree.display(verbose_stream()); verbose_stream() << "\n";);
|
||||
|
|
@ -529,9 +528,10 @@ namespace smt {
|
|||
return true;
|
||||
}
|
||||
|
||||
void parallel::batch_manager::initialize() {
|
||||
void parallel::batch_manager::initialize(unsigned initial_max_thread_conflicts) {
|
||||
m_state = state::is_running;
|
||||
m_search_tree.reset();
|
||||
m_search_tree.set_effort_unit(initial_max_thread_conflicts);
|
||||
}
|
||||
|
||||
void parallel::batch_manager::collect_statistics(::statistics &st) const {
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ namespace smt {
|
|||
public:
|
||||
batch_manager(ast_manager& m, parallel& p) : m(m), p(p), m_search_tree(expr_ref(m)) { }
|
||||
|
||||
void initialize();
|
||||
void initialize(unsigned initial_max_thread_conflicts = 1000); // TODO: pass in from worker defaults
|
||||
|
||||
void set_unsat(ast_translation& l2g, expr_ref_vector const& unsat_core);
|
||||
void set_sat(ast_translation& l2g, model& m);
|
||||
|
|
@ -106,7 +106,7 @@ namespace smt {
|
|||
|
||||
bool get_cube(ast_translation& g2l, unsigned id, expr_ref_vector& cube, node*& n);
|
||||
void backtrack(ast_translation& l2g, expr_ref_vector const& core, node* n);
|
||||
void split(ast_translation& l2g, unsigned id, node* n, expr* atom);
|
||||
void try_split(ast_translation& l2g, unsigned id, node* n, expr* atom, unsigned effort);
|
||||
|
||||
void collect_clause(ast_translation& l2g, unsigned source_worker_id, expr* clause);
|
||||
expr_ref_vector return_shared_clauses(ast_translation& g2l, unsigned& worker_limit, unsigned worker_id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue