cloud-sat/workers/basesolver.cpp
2023-03-20 21:40:19 +08:00

156 lines
4.7 KiB
C++

#include "basesolver.hpp"
#include "sharer.hpp"
int basesolver::get_period() {
boost::mutex::scoped_lock lock(mtx);
return period;
};
void basesolver::inc_period() {
boost::mutex::scoped_lock lock(mtx);
period++;
if (period % 100 == 0) printf("c %d reach period %d\n", id, period);
cond.notify_all();
};
void basesolver::internal_terminate() {
boost::mutex::scoped_lock lock(mtx);
terminate_period = period;
cond.notify_all();
}
void basesolver::external_terminate() {
{
boost::mutex::scoped_lock lock(mtx);
terminated = 1;
cond.notify_all();
// printf("c thread %d terminated\n", id);
}
terminate();
}
void basesolver::broaden_export_limit() {
++good_clause_lbd;
}
void basesolver::restrict_export_limit() {
if (good_clause_lbd > 2)
--good_clause_lbd;
}
double basesolver::get_waiting_time() {
return waiting_time;
}
void basesolver::export_clauses_to(vec<clause_store *> &clauses) {
clause_store *cls;
while (export_clause.pop(cls)) {
clauses.push(cls);
}
}
void basesolver::import_clauses_from(vec<clause_store *> &clauses) {
for (int i = 0; i < clauses.size(); i++) {
import_clause.push(clauses[i]);
}
}
void basesolver::select_clauses() {
sharer *share = in_sharer;
cls.clear();
export_clauses_to(cls);
for (int i = 0; i < cls.size(); i++) {
int sz = cls[i]->size;
while (sz > bucket.size()) bucket.push();
if (sz * (bucket[sz - 1].size() + 1) <= share->share_lits)
bucket[sz - 1].push(cls[i]);
}
period_clauses *pcls = new period_clauses(period);
int space = share->share_lits;
for (int i = 0; i < bucket.size(); i++) {
int clause_num = space / (i + 1);
if (!clause_num) break;
if (clause_num >= bucket[i].size()) {
space -= bucket[i].size() * (i + 1);
for (int j = 0; j < bucket[i].size(); j++)
pcls->push(bucket[i][j]);
bucket[i].clear();
}
else {
space -= clause_num * (i + 1);
for (int j = 0; j < clause_num; j++) {
pcls->push(bucket[i].last());
bucket[i].pop();
}
}
}
int percent = (share->share_lits - space) * 100 / share->share_lits;
if (percent < 75) broaden_export_limit();
if (percent > 98) restrict_export_limit();
//sort finish
pcls->increase_refs(share->producers.size() - 1);
pq.push(pcls);
}
void basesolver::get_model(vec<int> &model) {
model.clear();
for (int i = 1; i <= maxvar; i++) {
model.push(val(i));
}
}
void cbk_start_new_period(void *solver) {
auto clk_st = std::chrono::high_resolution_clock::now();
basesolver* S = (basesolver *) solver;
sharer *share = S->in_sharer;
int should_free = 1;
if (S->period >= S->controller->get_winner_period()) {
S->internal_terminate();
S->terminate();
return;
}
printf("c thread %d into select %d\n", S->id, S->period);
S->select_clauses();
// printf("c %d now finish period %d\n", S->id, S->get_period());
S->inc_period();
// printf("c thread %d start import at %d\n", S->id, S->period);
should_free = share->import_clauses(S->id);
printf("c thread %d finish import at %d\n", S->id, S->period);
if (should_free == -1) {
S->internal_terminate();
S->terminate();
}
auto clk_now = std::chrono::high_resolution_clock::now();
int solve_time = std::chrono::duration_cast<std::chrono::milliseconds>(clk_now - clk_st).count();
S->waiting_time += 0.001 * solve_time;
// printf("c %d wait for %d.%03ds\n", S->id, solve_time / 1000, solve_time % 1000);
// printf("c %d finish sharing\n", S->id);
}
void cbk_free_clauses(void *solver) {
basesolver* S = (basesolver *) solver;
sharer *share = S->in_sharer;
if (S->unfree.size()) printf("free %d period\n", S->unfree.size());
for (int id = 0; id < S->unfree.size(); id++) {
int import_period = S->unfree[id];
// int current_period = S->get_period() - 1, import_period = current_period - share->margin;
// if (import_period < 0) return;
for (int i = 0; i < share->producers.size(); i++) {
if (i == S->id) continue;
basesolver *s = share->producers[i];
period_clauses *pc = s->pq.find(import_period);
if (pc->period != import_period)
puts("*******************************************************");
if (pc->free_clause()) {
s->pq.pop(import_period);
// printf("thread %d enter, %d is free\n", S->id, i);
}
}
}
S->unfree.clear();
}