没有问题的good_var,但是巨慢

This commit is contained in:
YuhangQ 2023-05-09 23:14:22 +08:00
parent cc370586ae
commit 85cd5aa62b
11 changed files with 287 additions and 63 deletions

4
.vscode/launch.json vendored
View File

@ -9,12 +9,12 @@
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/atpg", "program": "${workspaceFolder}/atpg",
"args": ["c432.bench"], "args": ["${workspaceFolder}/benchmark/c432.bench"],
"stopAtEntry": false, "stopAtEntry": false,
"cwd": "${fileDirname}", "cwd": "${fileDirname}",
"environment": [], "environment": [],
"externalConsole": false, "externalConsole": false,
"MIMode": "gdb", "MIMode": "lldb",
"setupCommands": [ "setupCommands": [
{ {
"description": "为 gdb 启用整齐打印", "description": "为 gdb 启用整齐打印",

29
.vscode/settings.json vendored
View File

@ -1,5 +1,6 @@
{ {
"files.associations": { "files.associations": {
"*.ejs": "html",
"array": "cpp", "array": "cpp",
"*.tcc": "cpp", "*.tcc": "cpp",
"cctype": "cpp", "cctype": "cpp",
@ -53,6 +54,32 @@
"regex": "cpp", "regex": "cpp",
"fstream": "cpp", "fstream": "cpp",
"iostream": "cpp", "iostream": "cpp",
"cinttypes": "cpp" "cinttypes": "cpp",
"__bit_reference": "cpp",
"__bits": "cpp",
"__config": "cpp",
"__debug": "cpp",
"__errc": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__mutex_base": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__tree": "cpp",
"__tuple": "cpp",
"__verbose_abort": "cpp",
"complex": "cpp",
"cstring": "cpp",
"iomanip": "cpp",
"ios": "cpp",
"locale": "cpp",
"mutex": "cpp",
"optional": "cpp",
"queue": "cpp",
"stack": "cpp",
"variant": "cpp",
"__nullptr": "cpp",
"__string": "cpp"
} }
} }

BIN
atpg

Binary file not shown.

1
crun
View File

@ -7,6 +7,7 @@ make -j
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "compile failed." echo "compile failed."
else else
clear
echo "========================" echo "========================"
time ./atpg $1 time ./atpg $1
fi fi

57
src/checker.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "circuit.h"
int Circuit::check_circuit() {
int sum_value_unsatisfied_cost = 0;
int sum_fault_propagated_weight = 0;
int sum_fault_propagated_unsatisfied_cost = 0;
int sum_fault_detected_weight = 0;
int sum_fault_detected_unsatisfied_cost = 0;
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->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_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]));
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[1]) sum_fault_detected_weight += g->fault_detected_weight[1];
if(!g->fault_detected_satisfied[0]) sum_fault_detected_unsatisfied_cost += g->fault_detected_unsatisfied_cost[0];
if(!g->fault_detected_satisfied[1]) sum_fault_detected_unsatisfied_cost += g->fault_detected_unsatisfied_cost[1];
sum_fault_propagated_weight += g->fault_propagated_len[0] * g->fault_propagated_weight[0];
sum_fault_propagated_weight += g->fault_propagated_len[1] * g->fault_propagated_weight[1];
if(!g->fault_propagated_satisfied[0]) sum_fault_propagated_unsatisfied_cost += g->fault_propagated_unsatisfied_cost[0];
if(!g->fault_propagated_satisfied[1]) sum_fault_propagated_unsatisfied_cost += g->fault_propagated_unsatisfied_cost[1];
}
int circuit_score = sum_fault_propagated_weight + sum_fault_detected_weight
- sum_fault_propagated_unsatisfied_cost - sum_fault_detected_unsatisfied_cost - sum_value_unsatisfied_cost;
printf("svuc: %d, sfpw: %d, sfpuc: %d, sfdw: %d, sfduc: %d\n",
sum_value_unsatisfied_cost, sum_fault_propagated_weight, sum_fault_propagated_unsatisfied_cost,
sum_fault_detected_weight, sum_fault_detected_unsatisfied_cost);
return circuit_score;
}

View File

@ -94,7 +94,24 @@ void Circuit::print_gates() {
} }
} }
bool Circuit::is_valid_circuit() {
void Circuit::init_reigons() {
for(Gate* g : gates) {
for(Gate* in : g->fanins) {
g->reigon.push_back(in);
}
for(Gate* out : g->fanouts) {
for(Gate* in : out->fanins) {
if(in == g) continue;
g->reigon.push_back(in);
}
}
std::sort(g->reigon.begin(), g->reigon.end());
g->reigon.erase(unique(g->reigon.begin(), g->reigon.end()), g->reigon.end());
}
}
// bool Circuit::is_valid_circuit() {
// ll flip_total_weight = 0; // ll flip_total_weight = 0;
// ll stem_total_weight = 0; // ll stem_total_weight = 0;
@ -204,7 +221,7 @@ bool Circuit::is_valid_circuit() {
// printf("%lld %lld\n", fault_propagate_score , this->fault_propagate_score); // printf("%lld %lld\n", fault_propagate_score , this->fault_propagate_score);
// assert(fault_propagate_score == this->fault_propagate_score); // assert(fault_propagate_score == this->fault_propagate_score);
return true; // return true;
} // }

View File

@ -23,6 +23,7 @@ public:
bool isPO; bool isPO;
std::vector<Gate*> fanouts; std::vector<Gate*> fanouts;
std::vector<Gate*> fanins; std::vector<Gate*> fanins;
std::vector<Gate*> reigon;
// circuit-ls info // circuit-ls info
int value_satisfied; int value_satisfied;
@ -52,6 +53,9 @@ public:
int cal_propagate_len(bool x); int cal_propagate_len(bool x);
void update_gate_property();
void update_gate_statistics();
// ( partical ) score // ( partical ) score
// score(x) = for y in neibor(x) { ~V_x,V_y make - ~V_x,V_y break } // score(x) = for y in neibor(x) { ~V_x,V_y make - ~V_x,V_y break }
@ -73,7 +77,7 @@ public:
// score calculation function // score calculation function
int cal_score(); int cal_score(int debug=0);
int cal_value_unsatisfied_cost(); int cal_value_unsatisfied_cost();
@ -100,7 +104,6 @@ std::vector<Gate*> POs;
std::vector<Gate*> gates; std::vector<Gate*> gates;
std::vector<Gate*> rtopo_gates; std::vector<Gate*> rtopo_gates;
std::unordered_map<std::string, Gate*> name2gate; std::unordered_map<std::string, Gate*> name2gate;
// std::queue<Gate*> tmp; // std::queue<Gate*> tmp;
@ -109,12 +112,11 @@ std::unordered_map<std::string, Gate*> name2gate;
void init_topo_index(); void init_topo_index();
int MAX_GATE_LEVEL; int MAX_GATE_LEVEL;
void init_gate_level(); void init_gate_level();
void init_reigons();
void parse_from_file(const char *filename); void parse_from_file(const char *filename);
void print_gates(); void print_gates();
bool is_valid_circuit();
// local search // local search
bool local_search(std::unordered_set<Fault*> &faults); bool local_search(std::unordered_set<Fault*> &faults);
@ -125,4 +127,8 @@ Gate* ls_pick();
void ls_flip(Gate* stem); void ls_flip(Gate* stem);
void ls_update(Gate* stem); void ls_update(Gate* stem);
// checker
int check_circuit();
}; };

View File

@ -2,6 +2,22 @@
#include "assert.h" #include "assert.h"
void Gate::update_gate_property() {
fault_detected[0] = cal_fault_detected(0);
fault_detected[1] = cal_fault_detected(1);
fault_propagated_len[0] = cal_propagate_len(0);
fault_propagated_len[1] = cal_propagate_len(1);
}
void Gate::update_gate_statistics() {
value_satisfied = ( cal_value() == value );
fault_detected_satisfied[0] = ( cal_fault_detected(0) == fault_detected[0] );
fault_detected_satisfied[1] = ( cal_fault_detected(1) == fault_detected[1] );
fault_propagated_satisfied[0] = ( cal_propagate_len(0) == fault_propagated_len[0] );
fault_propagated_satisfied[1] = ( cal_propagate_len(1) == fault_propagated_len[1] );
}
int Gate::cal_propagate_len(bool x) { int Gate::cal_propagate_len(bool x) {
int fpl[2]; int fpl[2];
@ -11,6 +27,7 @@ int Gate::cal_propagate_len(bool x) {
if(!out->is_detected(this)) continue; if(!out->is_detected(this)) continue;
fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1); fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1);
} }
return fpl[x]; return fpl[x];
} }

View File

@ -13,7 +13,42 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
// 随机生成初始电路 // 随机生成初始电路
ls_init_circuit(faults); ls_init_circuit(faults);
// print_gates();
printf("generate random circuit done!\n"); printf("generate random circuit done!\n");
srand(19260817);
int T = 10000000;
while(T--) {
printf("%d\n", T);
// print_gates();
// int score_1 = check_circuit();
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",
// flip_gate->score_value_unsatisfied_cost,
// flip_gate->score_fault_propagated_weight[0] + flip_gate->score_fault_propagated_weight[1],
// flip_gate->score_fault_propagated_unsatisfied_cost[0] + flip_gate->score_fault_propagated_unsatisfied_cost[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]);
ls_flip(flip_gate);
// int score_2 = check_circuit();
// printf("checking circuit: %d %d\n", score_2 - score_1, dert);
// assert((score_2 - score_1) == dert);
// printf("i: %s\n", flip_gate->name.c_str());
}
exit(0); exit(0);
//printf("local search!\n"); //printf("local search!\n");
@ -54,14 +89,80 @@ Gate* Circuit::ls_pick() {
void Circuit::ls_flip(Gate* gate) { void Circuit::ls_flip(Gate* gate) {
printf("flip: %s\n", gate->name.c_str());
gate->value ^= 1; gate->value ^= 1;
gate->update_gate_property();
gate->update_gate_statistics();
for(Gate* g : gate->fanouts) { for(Gate* g : gate->fanouts) {
g->value_satisfied = ( g->cal_value() == g->value ); g->update_gate_statistics();
}
for(Gate* g : gate->reigon) {
g->update_gate_statistics();
} }
// for(Gate *g : gates) {
// g->score = g->cal_score();
// }
gate->score = gate->cal_score();
std::unordered_set<Gate*> t;
int cal_cnt = 0;
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) {
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) ){
printf("bug3: %s\n", g->name.c_str());
// print_gates();
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]);
} }
void Circuit::ls_update_weight() { void Circuit::ls_update_weight() {
@ -92,11 +193,11 @@ void Circuit::ls_init_circuit(std::unordered_set<Fault*> &faults) {
} }
for(Gate* g : rtopo_gates) { for(Gate* g : rtopo_gates) {
g->value_satisfied = ( g->cal_value() == g->value ); g->update_gate_property();
g->fault_propagated_len[0] = g->cal_propagate_len(0); }
g->fault_propagated_len[1] = g->cal_propagate_len(1);
g->fault_propagated_satisfied[0] = g->fault_propagated_satisfied[1] = 0; for(Gate* g : rtopo_gates) {
g->fault_detected_satisfied[0] = g->fault_detected_satisfied[1] = 0; g->update_gate_statistics();
} }
// cal score // cal score

View File

@ -19,6 +19,7 @@ int main(int args, char* argv[]) {
circuit->parse_from_file(argv[1]); circuit->parse_from_file(argv[1]);
circuit->init_topo_index(); circuit->init_topo_index();
circuit->init_gate_level(); circuit->init_gate_level();
circuit->init_reigons();
printf(" Done.\n"); printf(" Done.\n");
printf("====== Circuit Statistics ====== \n"); printf("====== Circuit Statistics ====== \n");
@ -38,7 +39,7 @@ int main(int args, char* argv[]) {
while(true) { while(true) {
bool ls = circuit->local_search(faults); bool ls = circuit->local_search(faults);
bool is_valid = circuit->is_valid_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;

View File

@ -1,7 +1,23 @@
#include "circuit.h" #include "circuit.h"
int Gate::cal_score() { int Gate::cal_score(int debug) {
value ^= 1;
if(debug) {
// printf("lala: %s\n", this->name.c_str());
assert(score_value_unsatisfied_cost == cal_value_unsatisfied_cost());
assert(score_fault_propagated_weight[0] == cal_score_fault_propagated_weight(0));
assert(score_fault_propagated_weight[1] == cal_score_fault_propagated_weight(1));
assert(score_fault_propagated_unsatisfied_cost[0] == cal_score_fault_propagated_unsatisfied_cost(0));
assert(score_fault_propagated_unsatisfied_cost[1] == cal_score_fault_propagated_unsatisfied_cost(1));
assert(score_fault_detected_weight[0] == cal_score_fault_detected_weight(0));
assert(score_fault_detected_weight[1] == cal_score_fault_detected_weight(1));
assert(score_fault_detected_unsatisfied_cost[0] == cal_score_fault_detected_unsatisfied_cost(0));
assert(score_fault_detected_unsatisfied_cost[1] == cal_score_fault_detected_unsatisfied_cost(1));
}
score_value_unsatisfied_cost = cal_value_unsatisfied_cost(); score_value_unsatisfied_cost = cal_value_unsatisfied_cost();
score_fault_propagated_weight[0] = cal_score_fault_propagated_weight(0); score_fault_propagated_weight[0] = cal_score_fault_propagated_weight(0);
score_fault_propagated_weight[1] = cal_score_fault_propagated_weight(1); score_fault_propagated_weight[1] = cal_score_fault_propagated_weight(1);
@ -15,6 +31,8 @@ int Gate::cal_score() {
score_fault_detected_unsatisfied_cost[0] = cal_score_fault_detected_unsatisfied_cost(0); score_fault_detected_unsatisfied_cost[0] = cal_score_fault_detected_unsatisfied_cost(0);
score_fault_detected_unsatisfied_cost[1] = cal_score_fault_detected_unsatisfied_cost(1); score_fault_detected_unsatisfied_cost[1] = cal_score_fault_detected_unsatisfied_cost(1);
value ^= 1;
return - score_value_unsatisfied_cost return - 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]
@ -24,7 +42,6 @@ int Gate::cal_score() {
int Gate::cal_value_unsatisfied_cost() { int Gate::cal_value_unsatisfied_cost() {
int res = 0; int res = 0;
value ^= 1;
for(Gate* g : fanouts) { for(Gate* g : fanouts) {
if(g->value_satisfied && g->cal_value() != g->value) { if(g->value_satisfied && g->cal_value() != g->value) {
res += g->value_unsatisfied_cost; res += g->value_unsatisfied_cost;
@ -33,44 +50,34 @@ int Gate::cal_value_unsatisfied_cost() {
res -= g->value_unsatisfied_cost; res -= g->value_unsatisfied_cost;
} }
} }
if(this->value_satisfied) { if(this->value_satisfied && this->cal_value() != this->value) {
res += this->value_unsatisfied_cost; res += this->value_unsatisfied_cost;
} else { }
if(!this->value_satisfied && this->cal_value() == this->value) {
res -= this->value_unsatisfied_cost; res -= this->value_unsatisfied_cost;
} }
value ^= 1;
return res; return res;
} }
int Gate::cal_score_fault_propagated_weight(int sa) { int Gate::cal_score_fault_propagated_weight(int sa) {
int res = 0; int res = 0;
value ^= 1; res += (this->cal_propagate_len(sa) - this->fault_propagated_len[sa] ) * this->fault_propagated_weight[sa];
int origin_fault_propagated_len = this->fault_propagated_len[sa];
this->fault_propagated_len[sa] = this->cal_propagate_len(sa);
res += (this->fault_propagated_len[sa] - origin_fault_propagated_len ) * this->fault_propagated_weight[sa];
for(Gate* g : fanins) {
res += ( g->cal_propagate_len(sa) - g->fault_propagated_len[sa] ) * g->fault_propagated_weight[sa];
}
this->fault_propagated_len[sa] = origin_fault_propagated_len;
value ^= 1;
return res; return res;
} }
int Gate::cal_score_fault_propagated_unsatisfied_cost(int sa) { int Gate::cal_score_fault_propagated_unsatisfied_cost(int sa) {
int res = 0; int res = 0;
value ^= 1; int origin_fault_propagated_len[2];
int origin_fault_propagated_len = this->fault_propagated_len[sa]; origin_fault_propagated_len[0] = this->fault_propagated_len[0];
this->fault_propagated_len[sa] = this->cal_propagate_len(sa); origin_fault_propagated_len[1] = this->fault_propagated_len[1];
this->fault_propagated_len[0] = this->cal_propagate_len(0);
this->fault_propagated_len[1] = this->cal_propagate_len(1);
if(!this->fault_propagated_satisfied[sa]) { if(!this->fault_propagated_satisfied[sa]) {
res -= this->fault_propagated_unsatisfied_cost[res]; res -= this->fault_propagated_unsatisfied_cost[sa];
} }
for(Gate* g : fanins) { for(Gate* g : this->reigon) {
if(g->fault_propagated_satisfied[sa] && g->cal_propagate_len(sa) != g->fault_propagated_len[sa]) { if(g->fault_propagated_satisfied[sa] && g->cal_propagate_len(sa) != g->fault_propagated_len[sa]) {
res += g->fault_propagated_unsatisfied_cost[sa]; res += g->fault_propagated_unsatisfied_cost[sa];
} }
@ -79,41 +86,31 @@ int Gate::cal_score_fault_propagated_unsatisfied_cost(int sa) {
} }
} }
this->fault_propagated_len[sa] = origin_fault_propagated_len; this->fault_propagated_len[0] = origin_fault_propagated_len[0];
value ^= 1; this->fault_propagated_len[1] = origin_fault_propagated_len[1];
return res; return res;
} }
int Gate::cal_score_fault_detected_weight(int sa) { int Gate::cal_score_fault_detected_weight(int sa) {
int res = 0; int res = 0;
value ^= 1; res += ( this->cal_fault_detected(sa) - this->fault_detected[sa] ) * this->fault_detected_weight[sa];
int origin_fault_detected = this->fault_detected[sa];
this->fault_detected[sa] = this->cal_fault_detected(sa);
res += ( this->fault_detected[sa] - origin_fault_detected ) * this->fault_detected_weight[sa];
for(Gate* g : fanins) {
res += ( g->cal_fault_detected(sa) - g->fault_detected[sa] ) * this->fault_detected_weight[sa];
}
this->fault_detected[sa] = origin_fault_detected;
value ^= 1;
return res; return res;
} }
int Gate::cal_score_fault_detected_unsatisfied_cost(int sa) { int Gate::cal_score_fault_detected_unsatisfied_cost(int sa) {
int res = 0; int res = 0;
value ^= 1;
int origin_fault_detected = this->fault_detected[sa]; int origin_fault_detected[2];
this->fault_detected[sa] = this->cal_fault_detected(sa); origin_fault_detected[0] = this->fault_detected[0];
origin_fault_detected[1] = this->fault_detected[1];
this->fault_detected[0] = this->cal_fault_detected(0);
this->fault_detected[1] = this->cal_fault_detected(1);
if(!this->fault_detected_satisfied[sa]) { if(!fault_detected_satisfied[sa]) {
res -= this->fault_detected_unsatisfied_cost[sa]; res -= this->fault_detected_unsatisfied_cost[sa];
} }
for(Gate* g : fanins) { for(Gate* g : this->reigon) {
if(g->fault_detected_satisfied[sa] && g->cal_fault_detected(sa) != g->fault_detected[sa]) { if(g->fault_detected_satisfied[sa] && g->cal_fault_detected(sa) != g->fault_detected[sa]) {
res += g->fault_detected_unsatisfied_cost[sa]; res += g->fault_detected_unsatisfied_cost[sa];
} }
@ -122,8 +119,8 @@ int Gate::cal_score_fault_detected_unsatisfied_cost(int sa) {
} }
} }
this->fault_detected[sa] = origin_fault_detected; this->fault_detected[0] = origin_fault_detected[0];
this->fault_detected[1] = origin_fault_detected[1];
value ^= 1;
return res; return res;
} }