完整流程跑通,但效果很差

This commit is contained in:
YuhangQ 2023-05-10 21:42:30 +08:00
parent 85cd5aa62b
commit 268b2b2c80
10 changed files with 244 additions and 104 deletions

BIN
atpg

Binary file not shown.

View File

@ -12,25 +12,40 @@ int Circuit::check_circuit() {
for(Gate* g : gates) { for(Gate* g : gates) {
// assert(g->fault_detected[0] == g->cal_fault_detected(0));
// assert(g->fault_detected[1] == g->cal_fault_detected(1));
// assert(g->fault_propagated_len[0] == g->fault_propagated_len[0]);
// assert(g->fault_propagated_len[1] == g->fault_propagated_len[1]);
assert(g->value_satisfied == ( g->cal_value() == g->value )); assert(g->value_satisfied == ( g->cal_value() == g->value ));
assert(g->fault_detected_satisfied[0] == ( g->cal_fault_detected(0) == g->fault_detected[0] )); assert(g->fault_detected_satisfied[0] == ( g->cal_fault_detected(0) == g->fault_detected[0] ));
assert(g->fault_detected_satisfied[1] == ( g->cal_fault_detected(1) == g->fault_detected[1] )); assert(g->fault_detected_satisfied[1] == ( g->cal_fault_detected(1) == g->fault_detected[1] ));
assert(g->fault_propagated_satisfied[0] == ( g->cal_propagate_len(0) == g->fault_propagated_len[0])); assert(g->fault_propagated_satisfied[0] == ( g->cal_propagate_len(0) == g->fault_propagated_len[0]));
// if(g->fault_propagated_satisfied[1] != ( g->cal_propagate_len(1) == g->fault_propagated_len[1])) {
// printf("pl: %s\n", g->name.c_str());
// print_gates();
// }
assert(g->fault_propagated_satisfied[1] == ( g->cal_propagate_len(1) == g->fault_propagated_len[1])); assert(g->fault_propagated_satisfied[1] == ( g->cal_propagate_len(1) == g->fault_propagated_len[1]));
if(g->value_satisfied) {
assert(value_satisfied_vars.count(g));
assert(!value_unsatisfied_vars.count(g));
} else {
assert(value_unsatisfied_vars.count(g));
assert(!value_satisfied_vars.count(g));
}
if(g->fault_detected_satisfied[0] && g->fault_detected_satisfied[1]) {
assert(detected_satisfied_vars.count(g));
assert(!detected_unsatisfied_vars.count(g));
} else {
assert(detected_unsatisfied_vars.count(g));
assert(!detected_satisfied_vars.count(g));
}
if(g->fault_propagated_satisfied[0] && g->fault_propagated_satisfied[1]) {
assert(propagated_satisfied_vars.count(g));
assert(!propagated_unsatisfied_vars.count(g));
} else {
assert(propagated_unsatisfied_vars.count(g));
assert(!propagated_satisfied_vars.count(g));
}
if(!g->value_satisfied) sum_value_unsatisfied_cost += g->value_unsatisfied_cost; if(!g->value_satisfied) sum_value_unsatisfied_cost += g->value_unsatisfied_cost;
if(g->fault_detected[0]) sum_fault_detected_weight += g->fault_detected_weight[0]; if(g->fault_detected[0]) sum_fault_detected_weight += g->fault_detected_weight[0];

View File

@ -109,6 +109,42 @@ void Circuit::init_reigons() {
std::sort(g->reigon.begin(), g->reigon.end()); std::sort(g->reigon.begin(), g->reigon.end());
g->reigon.erase(unique(g->reigon.begin(), g->reigon.end()), g->reigon.end()); g->reigon.erase(unique(g->reigon.begin(), g->reigon.end()), g->reigon.end());
} }
std::unordered_set<Gate*> r_set;
// score reigon
for(Gate* gate : gates) {
r_set.clear();
for(Gate* out : gate->fanouts) {
r_set.insert(out);
for(Gate* in : out->fanins) {
r_set.insert(in);
for(Gate *out : in->fanouts) {
r_set.insert(out);
for(Gate *in : out->fanins) {
r_set.insert(in);
}
}
}
}
for(Gate* in : gate->fanins) {
r_set.insert(in);
for(Gate* out : in->fanouts) {
r_set.insert(out);
for(Gate* in : out->fanins) {
r_set.insert(in);
}
}
}
r_set.erase(gate);
for(Gate* g : r_set) {
gate->score_reigon.push_back(g);
}
}
} }
// bool Circuit::is_valid_circuit() { // bool Circuit::is_valid_circuit() {

View File

@ -8,9 +8,14 @@
using ll = long long; using ll = long long;
class Circuit;
class Gate { class Gate {
public: public:
Gate(Circuit* C):C(C) {}
// gate basic info // gate basic info
int id; int id;
@ -24,6 +29,7 @@ public:
std::vector<Gate*> fanouts; std::vector<Gate*> fanouts;
std::vector<Gate*> fanins; std::vector<Gate*> fanins;
std::vector<Gate*> reigon; std::vector<Gate*> reigon;
std::vector<Gate*> score_reigon;
// circuit-ls info // circuit-ls info
int value_satisfied; int value_satisfied;
@ -41,6 +47,9 @@ public:
int fault_detected_satisfied[2]; int fault_detected_satisfied[2];
int fault_detected_unsatisfied_cost[2]; int fault_detected_unsatisfied_cost[2];
int good_var_index;
int unsatisfied_var_index;
int CC; int CC;
bool is_propagated(); bool is_propagated();
@ -77,7 +86,7 @@ public:
// score calculation function // score calculation function
int cal_score(int debug=0); void cal_score(int debug=0);
int cal_value_unsatisfied_cost(); int cal_value_unsatisfied_cost();
@ -88,6 +97,10 @@ public:
int cal_score_fault_detected_weight(int sa); int cal_score_fault_detected_weight(int sa);
int cal_score_fault_detected_unsatisfied_cost(int sa); int cal_score_fault_detected_unsatisfied_cost(int sa);
private:
Circuit* C;
}; };
class Fault { class Fault {
@ -118,6 +131,15 @@ void parse_from_file(const char *filename);
void print_gates(); void print_gates();
// local search // local search
std::vector<Gate*> good_vars;
std::unordered_set<Gate*> value_unsatisfied_vars;
std::unordered_set<Gate*> value_satisfied_vars;
std::unordered_set<Gate*> propagated_unsatisfied_vars;
std::unordered_set<Gate*> propagated_satisfied_vars;
std::unordered_set<Gate*> detected_unsatisfied_vars;
std::unordered_set<Gate*> detected_satisfied_vars;
bool local_search(std::unordered_set<Fault*> &faults); bool local_search(std::unordered_set<Fault*> &faults);
void ls_init_circuit(std::unordered_set<Fault*> &faults); void ls_init_circuit(std::unordered_set<Fault*> &faults);

View File

@ -12,10 +12,35 @@ void Gate::update_gate_property() {
void Gate::update_gate_statistics() { void Gate::update_gate_statistics() {
value_satisfied = ( cal_value() == value ); value_satisfied = ( cal_value() == value );
if(value_satisfied) {
C->value_satisfied_vars.insert(this);
C->value_unsatisfied_vars.erase(this);
} else {
C->value_satisfied_vars.erase(this);
C->value_unsatisfied_vars.insert(this);
}
fault_detected_satisfied[0] = ( cal_fault_detected(0) == fault_detected[0] ); fault_detected_satisfied[0] = ( cal_fault_detected(0) == fault_detected[0] );
fault_detected_satisfied[1] = ( cal_fault_detected(1) == fault_detected[1] ); fault_detected_satisfied[1] = ( cal_fault_detected(1) == fault_detected[1] );
if(fault_detected_satisfied[0] && fault_detected_satisfied[1]) {
C->detected_satisfied_vars.insert(this);
C->detected_unsatisfied_vars.erase(this);
} else {
C->detected_unsatisfied_vars.insert(this);
C->detected_satisfied_vars.erase(this);
}
fault_propagated_satisfied[0] = ( cal_propagate_len(0) == fault_propagated_len[0] ); fault_propagated_satisfied[0] = ( cal_propagate_len(0) == fault_propagated_len[0] );
fault_propagated_satisfied[1] = ( cal_propagate_len(1) == fault_propagated_len[1] ); fault_propagated_satisfied[1] = ( cal_propagate_len(1) == fault_propagated_len[1] );
if(fault_propagated_satisfied[0] && fault_propagated_satisfied[1]) {
C->propagated_satisfied_vars.insert(this);
C->propagated_unsatisfied_vars.erase(this);
} else {
C->propagated_unsatisfied_vars.insert(this);
C->propagated_satisfied_vars.erase(this);
}
} }
int Gate::cal_propagate_len(bool x) { int Gate::cal_propagate_len(bool x) {

View File

@ -16,22 +16,24 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
// print_gates(); // print_gates();
printf("generate random circuit done!\n"); printf("generate random circuit done!\n");
srand(19260817);
int T = 10000000; int T = 10000000;
int iter = 0;
while(T--) { while(T--) {
printf("%d\n", T); iter++;
if(iter % 1000 == 0) {
printf("iter: %d\n", iter);
check_circuit();
}
// print_gates(); if(value_unsatisfied_vars.empty()) {
printf("Get Solution!\n");
break;
}
// int score_1 = check_circuit(); Gate* gate = ls_pick();
ls_flip(gate);
int i = rand()%gates.size();
Gate* flip_gate = gates[i];
int dert = flip_gate->score;
// printf("svuc: %d, sfpw: %d, sfpuc: %d, sfdw: %d, sfduc: %d <<<\n", // printf("svuc: %d, sfpw: %d, sfpuc: %d, sfdw: %d, sfduc: %d <<<\n",
// flip_gate->score_value_unsatisfied_cost, // flip_gate->score_value_unsatisfied_cost,
@ -40,7 +42,7 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
// flip_gate->score_fault_detected_weight[0] + flip_gate->score_fault_detected_weight[1], // flip_gate->score_fault_detected_weight[0] + flip_gate->score_fault_detected_weight[1],
// flip_gate->score_fault_detected_unsatisfied_cost[0] + flip_gate->score_fault_detected_unsatisfied_cost[1]); // flip_gate->score_fault_detected_unsatisfied_cost[0] + flip_gate->score_fault_detected_unsatisfied_cost[1]);
ls_flip(flip_gate);
// int score_2 = check_circuit(); // int score_2 = check_circuit();
// printf("checking circuit: %d %d\n", score_2 - score_1, dert); // printf("checking circuit: %d %d\n", score_2 - score_1, dert);
@ -49,15 +51,9 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
// printf("i: %s\n", flip_gate->name.c_str()); // printf("i: %s\n", flip_gate->name.c_str());
} }
exit(0); // execute simulation
for(Gate* g : rtopo_gates) {
//printf("local search!\n"); g->update_gate_statistics();
while(true) {
Gate* gate = ls_pick();
if(gate == nullptr) {
break;
}
} }
static int original_faults = -1; static int original_faults = -1;
@ -78,22 +74,85 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
printf("coverage: %.3f%%\tpattern: %d\tbefore: %d\tnow: %d\n", (double)(original_faults - faults.size()) / (original_faults) * 100, ++pattern, tmp.size(), faults.size()); printf("coverage: %.3f%%\tpattern: %d\tbefore: %d\tnow: %d\n", (double)(original_faults - faults.size()) / (original_faults) * 100, ++pattern, tmp.size(), faults.size());
exit(0);
if(tmp.size() == faults.size()) return false; if(tmp.size() == faults.size()) return false;
return true; return true;
} }
Gate* Circuit::ls_pick() { Gate* Circuit::ls_pick() {
return nullptr; static int focus = 1;
double SP = 0.1;
if(rand() % 1000 <= 500 * SP) {
std::vector<Gate*> tmp;
for(Gate* g : value_unsatisfied_vars) {
tmp.push_back(g);
}
return tmp[rand()%tmp.size()];
}
if(good_vars.size()) {
return good_vars[rand()%good_vars.size()];
}
// printf("update weight\n");
ls_update_weight();
std::vector<Gate*> tmp;
for(Gate* g : value_unsatisfied_vars) {
tmp.push_back(g);
}
return tmp[rand()%tmp.size()];
}
void Circuit::ls_update_weight() {
std::unordered_set<Gate*> gates_need_recal_score;
for(Gate* g : value_unsatisfied_vars) {
g->value_unsatisfied_cost += 1;
for(Gate *in : g->fanins) {
gates_need_recal_score.insert(in);
}
for(Gate *out : g->fanouts) {
gates_need_recal_score.insert(out);
}
}
for(Gate* g : detected_unsatisfied_vars) {
g->fault_detected_unsatisfied_cost[0] += g->level;
g->fault_detected_unsatisfied_cost[1] += g->level;
for(Gate* r : g->score_reigon) {
gates_need_recal_score.insert(r);
}
}
for(Gate* g : propagated_unsatisfied_vars) {
g->fault_propagated_unsatisfied_cost[0] += g->level;
g->fault_propagated_unsatisfied_cost[1] += g->level;
for(Gate* r : g->score_reigon) {
gates_need_recal_score.insert(r);
}
}
for(Gate *g : gates_need_recal_score) {
g->cal_score();
}
// check_circuit();
} }
void Circuit::ls_flip(Gate* gate) { void Circuit::ls_flip(Gate* gate) {
printf("flip: %s\n", gate->name.c_str()); // printf("flip: %s\n", gate->name.c_str());
gate->value ^= 1; gate->value ^= 1;
gate->update_gate_property(); gate->update_gate_property();
gate->update_gate_statistics(); gate->update_gate_statistics();
for(Gate* g : gate->fanouts) { for(Gate* g : gate->fanouts) {
@ -107,76 +166,37 @@ void Circuit::ls_flip(Gate* gate) {
// g->score = g->cal_score(); // g->score = g->cal_score();
// } // }
gate->score = gate->cal_score(); gate->cal_score();
std::unordered_set<Gate*> t; for(Gate* g : gate->score_reigon) {
int cal_cnt = 0; g->cal_score();
for(Gate* g : gate->fanouts) {
// printf("cal2: %s\n", g->name.c_str());
t.insert(g);
g->score = g->cal_score();
cal_cnt++;
for(Gate* in : g->fanins) {
t.insert(in);
in->score = in->cal_score();
cal_cnt++;
for(Gate *out : in->fanouts) {
t.insert(out);
out->score = out->cal_score();
cal_cnt++;
for(Gate *in : out->fanins) {
t.insert(in);
in->score = in->cal_score();
cal_cnt++;
}
}
}
} }
for(Gate* g : gate->fanins) { // printf("t: %d cal_cnt: %d r_set: %d\n", t.size(), cal_cnt, gate->score_reigon.size());
t.insert(g);
g->score = g->cal_score();
cal_cnt++;
for(Gate* out : g->fanouts) {
t.insert(out);
out->score = out->cal_score();
cal_cnt++;
for(Gate* in : out->fanins) {
t.insert(in);
in->score = in->cal_score();
cal_cnt++;
}
}
}
printf("t: %d cal_cnt: %d\n", t.size(), cal_cnt); // for(Gate* g : gates) {
// if(g->score != g->cal_score(true) ){
for(Gate* g : gates) { // printf("bug3: %s\n", g->name.c_str());
if(g->score != g->cal_score(true) ){ // // print_gates();
printf("bug3: %s\n", g->name.c_str()); // exit(0);
// print_gates(); // }
exit(0); // }
}
}
// exit(0); // exit(0);
// printf("bug %s: cal_len:%d len:%d\n", gate->name.c_str(), gate->cal_propagate_len(1), gate->fault_propagated_len[1]); // printf("bug %s: cal_len:%d len:%d\n", gate->name.c_str(), gate->cal_propagate_len(1), gate->fault_propagated_len[1]);
} }
void Circuit::ls_update_weight() {
}
void Circuit::ls_update(Gate* stem) {
}
void Circuit::ls_init_circuit(std::unordered_set<Fault*> &faults) { void Circuit::ls_init_circuit(std::unordered_set<Fault*> &faults) {
good_vars.clear();
value_unsatisfied_vars.clear();
value_satisfied_vars.clear();
propagated_unsatisfied_vars.clear();
propagated_satisfied_vars.clear();
detected_unsatisfied_vars.clear();
detected_satisfied_vars.clear();
// init value, weight and cost // init value, weight and cost
for(Gate* g : gates) { for(Gate* g : gates) {
g->value = rand() % 2; g->value = rand() % 2;
@ -185,6 +205,8 @@ void Circuit::ls_init_circuit(std::unordered_set<Fault*> &faults) {
g->fault_propagated_unsatisfied_cost[0] = g->fault_propagated_unsatisfied_cost[1] = 1; g->fault_propagated_unsatisfied_cost[0] = g->fault_propagated_unsatisfied_cost[1] = 1;
g->fault_detected_weight[0] = g->fault_detected_weight[1] = 0; g->fault_detected_weight[0] = g->fault_detected_weight[1] = 0;
g->fault_detected_unsatisfied_cost[0] = g->fault_detected_unsatisfied_cost[1] = 1; g->fault_detected_unsatisfied_cost[0] = g->fault_detected_unsatisfied_cost[1] = 1;
g->good_var_index = -1;
g->unsatisfied_var_index = -1;
} }
for(Fault* f : faults) { for(Fault* f : faults) {
@ -202,7 +224,7 @@ void Circuit::ls_init_circuit(std::unordered_set<Fault*> &faults) {
// cal score // cal score
for(Gate* g : gates) { for(Gate* g : gates) {
g->score = g->cal_score(); g->cal_score();
printf("%d ", g->score); printf("%d ", g->score);
} }

View File

@ -42,12 +42,9 @@ int main(int args, char* argv[]) {
bool is_valid = circuit->check_circuit(); bool is_valid = circuit->check_circuit();
printf("checking valid circuit ..."); printf("checking valid circuit ...");
printf(" result: %d.\n", is_valid); printf(" result: %d.\n", is_valid);
if(!ls) break; // if(!ls) break;
if(!is_valid) break; // if(!is_valid) break;
if(faults.size() == 0) break; if(faults.size() == 0) break;
//circuit->print_gates();
//break;
} }
//printf("[final] flip: %d, stem: %d, fault:%d\n", circuit->flip_total_weight, circuit->stem_total_weight, circuit->fault_total_weight); //printf("[final] flip: %d, stem: %d, fault:%d\n", circuit->flip_total_weight, circuit->stem_total_weight, circuit->fault_total_weight);

View File

@ -1,3 +1,8 @@
#define DEBUG 1
const double SP = 0.01; const double SP = 0.01;
const int STEM_INC = 0; const int STEM_INC = 0;

View File

@ -71,7 +71,7 @@ void Circuit::parse_from_file(const char *filename) {
} }
} }
Gate* gate = new Gate(); Gate* gate = new Gate(this);
gate->name = tokens[0]; gate->name = tokens[0];
gate->isPI = false; gate->isPI = false;
gate->isPO = false; gate->isPO = false;
@ -108,7 +108,7 @@ void Circuit::parse_from_file(const char *filename) {
} }
// input // input
else if(tokens.size() == 4 && tokens[0] == "INPUT" && tokens[1] == "(" && tokens[3] == ")") { else if(tokens.size() == 4 && tokens[0] == "INPUT" && tokens[1] == "(" && tokens[3] == ")") {
Gate* gate = new Gate(); Gate* gate = new Gate(this);
gate->name = tokens[2]; gate->name = tokens[2];
gate->type = Gate::INPUT; gate->type = Gate::INPUT;
gate->isPI = true; gate->isPI = true;

View File

@ -1,7 +1,7 @@
#include "circuit.h" #include "circuit.h"
int Gate::cal_score(int debug) { void Gate::cal_score(int debug) {
value ^= 1; value ^= 1;
@ -33,11 +33,29 @@ int Gate::cal_score(int debug) {
value ^= 1; value ^= 1;
return - score_value_unsatisfied_cost score = - score_value_unsatisfied_cost
+ score_fault_propagated_weight[0] + score_fault_propagated_weight[1] + score_fault_propagated_weight[0] + score_fault_propagated_weight[1]
- score_fault_propagated_unsatisfied_cost[0] - score_fault_propagated_unsatisfied_cost[1] - score_fault_propagated_unsatisfied_cost[0] - score_fault_propagated_unsatisfied_cost[1]
+ score_fault_detected_weight[0] + score_fault_detected_weight[1] + score_fault_detected_weight[0] + score_fault_detected_weight[1]
- score_fault_detected_unsatisfied_cost[0] - score_fault_detected_unsatisfied_cost[1]; - score_fault_detected_unsatisfied_cost[0] - score_fault_detected_unsatisfied_cost[1];
if(score > 0 && good_var_index == -1) {
good_var_index = C->good_vars.size();
C->good_vars.push_back(this);
}
if(score <= 0 && good_var_index != -1) {
C->good_vars[C->good_vars.size()-1]->good_var_index = good_var_index;
std::swap(C->good_vars[good_var_index], C->good_vars[C->good_vars.size()-1]);
C->good_vars.pop_back();
good_var_index = -1;
}
for(Gate* g : C->good_vars) {
assert(g->score > 0);
}
return;
} }
int Gate::cal_value_unsatisfied_cost() { int Gate::cal_value_unsatisfied_cost() {