cloud-sat/solve.cpp

226 lines
7.2 KiB
C++
Raw Normal View History

2022-08-30 15:42:35 +08:00
#include "light.hpp"
#include "workers/basekissat.hpp"
2022-12-04 23:30:36 +08:00
#include "workers/sharer.hpp"
2022-08-30 15:42:35 +08:00
#include <unistd.h>
#include <chrono>
2022-08-31 09:16:12 +00:00
#include <algorithm>
2022-12-04 23:30:36 +08:00
#include <mutex>
2022-09-08 13:54:29 +08:00
auto clk_st = std::chrono::high_resolution_clock::now();
2022-08-30 15:42:35 +08:00
char* worker_sign = "";
2023-03-15 14:15:44 +08:00
2022-09-15 10:31:41 +08:00
std::atomic<int> terminated;
2022-08-30 15:42:35 +08:00
int result = 0;
2023-03-20 21:40:19 +08:00
int winner_conf;
2022-08-30 15:42:35 +08:00
vec<int> model;
void * read_worker(void *arg) {
basesolver * sq = (basesolver *)arg;
if (worker_sign == "")
2023-02-28 15:14:04 +08:00
sq->parse_from_PAR(sq->controller->pre);
2022-08-30 15:42:35 +08:00
else
2023-02-28 15:14:04 +08:00
sq->parse_from_CNF(worker_sign);
2022-08-30 15:42:35 +08:00
return NULL;
}
void * solve_worker(void *arg) {
basesolver * sq = (basesolver *)arg;
while (!terminated) {
int res = sq->solve();
2023-03-20 21:40:19 +08:00
if (sq->controller->opt->DPS) {
2023-03-15 14:15:44 +08:00
printf("c %d solved, res is %d\n", sq->id, res);
if (res) {
terminated = 1;
result = res;
printf("c %d solved 1\n", sq->id);
2023-03-20 21:40:19 +08:00
sq->internal_terminate();
2023-03-15 14:15:44 +08:00
printf("c %d solved 2\n", sq->id);
sq->controller->update_winner(sq->id, sq->period);
printf("c %d solved 3\n", sq->id);
if (res == 10) sq->get_model(sq->model);
}
printf("c %d really solved, period is %d\n", sq->id, sq->period);
2022-08-30 15:42:35 +08:00
}
2023-03-15 14:15:44 +08:00
else {
if (res && !terminated) {
printf("c result: %d, winner is %d, winner run %d confs\n", res, sq->id, sq->get_conflicts());
terminated = 1;
sq->controller->terminate_workers();
result = res;
2023-03-20 21:40:19 +08:00
sq->controller->update_winner(sq->id, 0);
2023-03-15 14:15:44 +08:00
winner_conf = sq->get_conflicts();
2023-03-20 21:40:19 +08:00
if (res == 10) sq->get_model(sq->model);
2023-03-15 14:15:44 +08:00
}
printf("get result %d with res %d\n", sq->id, res);
2022-08-30 15:42:35 +08:00
}
}
return NULL;
}
2022-08-31 09:16:12 +00:00
void light::init_workers() {
2022-09-15 10:31:41 +08:00
terminated = 0;
2022-08-30 15:42:35 +08:00
for (int i = 0; i < OPT(threads); i++) {
basekissat* kissat = new basekissat(i, this);
2022-08-31 09:16:12 +00:00
workers.push(kissat);
2022-08-30 15:42:35 +08:00
}
}
2022-08-31 09:16:12 +00:00
void light::diversity_workers() {
2022-08-30 15:42:35 +08:00
for (int i = 0; i < OPT(threads); i++) {
2023-03-01 22:05:44 +08:00
if (OPT(shuffle)) {
if (i) workers[i]->configure("order_reset", i);
}
if (OPT(pakis)) {
if (i == 13 || i == 14 || i == 20 || i == 21)
workers[i]->configure("tier1", 3);
else
workers[i]->configure("tier1", 2);
if (i == 3 || i == 4 || i == 6 || i == 8 || i == 11 || i == 12 || i == 13 || i == 14 || i == 16 || i == 18 || i == 23)
workers[i]->configure("chrono", 0);
else
workers[i]->configure("chrono", 1);
if (i == 2 || i == 23)
workers[i]->configure("stable", 0);
else if (i == 6 || i == 16)
workers[i]->configure("stable", 2);
else
workers[i]->configure("stable", 1);
if (i == 10 || i == 22)
workers[i]->configure("walkinitially", 1);
else
workers[i]->configure("walkinitially", 0);
if (i == 7 || i == 8 || i == 9 || i == 17 || i == 18 || i == 19 || i == 20)
workers[i]->configure("target", 0);
else if (i == 0 || i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 10 || i == 23)
workers[i]->configure("target", 1);
else
workers[i]->configure("target", 2);
if (i == 4 || i == 5 || i == 8 || i == 9 || i == 12 || i == 13 || i == 15 || i == 18 || i == 19)
workers[i]->configure("phase", 0);
else
workers[i]->configure("phase", 1);
}
2023-03-20 21:40:19 +08:00
for (int j = 0; j < configure_name[i].size(); j++) {
workers[i]->configure(configure_name[i][j], configure_val[i][j]);
}
2022-08-30 15:42:35 +08:00
}
}
2022-08-31 09:16:12 +00:00
void light::terminate_workers() {
2023-03-15 14:15:44 +08:00
printf("c controller reach limit\n");
2022-08-30 15:42:35 +08:00
for (int i = 0; i < OPT(threads); i++) {
2023-03-20 21:40:19 +08:00
if (OPT(share) == 1 && OPT(DPS) == 1)
workers[i]->external_terminate();
2023-03-15 14:15:44 +08:00
else
workers[i]->terminate();
2022-08-30 15:42:35 +08:00
}
2022-12-04 23:30:36 +08:00
for (int i = 0; i < sharers.size(); i++) {
sharers[i]->set_terminated();
}
2022-08-30 15:42:35 +08:00
}
void light::parse_input() {
pthread_t *ptr = new pthread_t[OPT(threads)];
for (int i = 0; i < OPT(threads); i++) {
2022-08-31 09:16:12 +00:00
pthread_create(&ptr[i], NULL, read_worker, workers[i]);
2022-08-30 15:42:35 +08:00
}
for (int i = 0; i < OPT(threads); i++) {
pthread_join(ptr[i], NULL);
}
delete []ptr;
}
int light::solve() {
printf("c -----------------solve start----------------------\n");
pthread_t *ptr = new pthread_t[OPT(threads)];
for (int i = 0; i < OPT(threads); i++) {
2022-08-31 09:16:12 +00:00
pthread_create(&ptr[i], NULL, solve_worker, workers[i]);
}
thread_inf unimprove[OPT(threads)];
auto clk_sol_st = std::chrono::high_resolution_clock::now();
int pre_time = std::chrono::duration_cast<std::chrono::seconds>(clk_sol_st - clk_st).count();
int sol_thd = 0, intv_time = OPT(reset_time);
2022-08-30 15:42:35 +08:00
while (!terminated) {
usleep(100000);
auto clk_now = std::chrono::high_resolution_clock::now();
int solve_time = std::chrono::duration_cast<std::chrono::seconds>(clk_now - clk_st).count();
if (solve_time >= OPT(times)) {
terminated = 1;
2022-08-31 09:16:12 +00:00
terminate_workers();
}
2022-08-30 15:42:35 +08:00
}
2023-03-20 21:40:19 +08:00
printf("ending solve\n");
2023-03-15 14:15:44 +08:00
// terminate_workers(); //important, need combine nps/dps !!!!!!!!!!!!!!!!
2022-08-31 09:16:12 +00:00
2022-08-30 15:42:35 +08:00
for (int i = 0; i < OPT(threads); i++) {
pthread_join(ptr[i], NULL);
2023-03-01 22:05:44 +08:00
}
2023-03-15 14:15:44 +08:00
printf("ending join\n");
if (result == 10)
workers[winner_id]->model.copyTo(model);
2023-03-01 22:05:44 +08:00
auto clk_now = std::chrono::high_resolution_clock::now();
double solve_time = std::chrono::duration_cast<std::chrono::milliseconds>(clk_now - clk_sol_st).count();
solve_time = 0.001 * solve_time;
2023-03-15 14:15:44 +08:00
printf("c solve time: %.2lf\nwinner is %d, period is %d\n", solve_time, winner_id, winner_period);
2023-03-01 22:05:44 +08:00
for (int i = 0; i < OPT(threads); i++) {
printf("c thread %d waiting time: %.2lf\n", i, workers[i]->get_waiting_time());
}
2022-08-31 09:16:12 +00:00
delete []ptr;
return result;
2022-08-30 15:42:35 +08:00
}
int light::run() {
2022-08-31 09:16:12 +00:00
init_workers();
diversity_workers();
2022-08-30 15:42:35 +08:00
if (OPT(simplify)) {
pre = new preprocess();
int res = pre->do_preprocess(filename);
if (!res) return 20;
}
else worker_sign = filename;
parse_input();
2022-12-04 23:30:36 +08:00
if (OPT(share)) share();
2022-08-30 15:42:35 +08:00
int res = solve();
if (res == 10 && OPT(simplify)) {
for (int i = 1; i <= pre->orivars; i++)
if (pre->mapto[i]) pre->mapval[i] = (model[abs(pre->mapto[i])-1] > 0 ? 1 : -1) * (pre->mapto[i] > 0 ? 1 : -1);
pre->get_complete_model();
model.clear();
for (int i = 1; i <= pre->orivars; i++) {
model.push(i * pre->mapval[i]);
}
}
return res;
}
void print_model(vec<int> &model) {
printf("v");
for (int i = 0; i < model.size(); i++) {
printf(" %d", model[i]);
}
puts(" 0");
}
void solve(int argc, char **argv) {
light* S = new light();
S->arg_parse(argc, argv);
int res = S->run();
if (res == 10) {
printf("s SATISFIABLE\n");
2023-03-15 14:15:44 +08:00
// print_model(model);
2022-08-30 15:42:35 +08:00
}
else if (res == 20) {
printf("s UNSATISFIABLE\n");
}
else {
printf("s UNKNOWN\n");
}
delete(S);
return;
}