没有问题的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",
"request": "launch",
"program": "${workspaceFolder}/atpg",
"args": ["c432.bench"],
"args": ["${workspaceFolder}/benchmark/c432.bench"],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"MIMode": "lldb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",

29
.vscode/settings.json vendored
View File

@ -1,5 +1,6 @@
{
"files.associations": {
"*.ejs": "html",
"array": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
@ -53,6 +54,32 @@
"regex": "cpp",
"fstream": "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
echo "compile failed."
else
clear
echo "========================"
time ./atpg $1
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 stem_total_weight = 0;
@ -204,7 +221,7 @@ bool Circuit::is_valid_circuit() {
// printf("%lld %lld\n", 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;
std::vector<Gate*> fanouts;
std::vector<Gate*> fanins;
std::vector<Gate*> reigon;
// circuit-ls info
int value_satisfied;
@ -52,6 +53,9 @@ public:
int cal_propagate_len(bool x);
void update_gate_property();
void update_gate_statistics();
// ( partical ) score
// 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
int cal_score();
int cal_score(int debug=0);
int cal_value_unsatisfied_cost();
@ -100,7 +104,6 @@ std::vector<Gate*> POs;
std::vector<Gate*> gates;
std::vector<Gate*> rtopo_gates;
std::unordered_map<std::string, Gate*> name2gate;
// std::queue<Gate*> tmp;
@ -109,12 +112,11 @@ std::unordered_map<std::string, Gate*> name2gate;
void init_topo_index();
int MAX_GATE_LEVEL;
void init_gate_level();
void init_reigons();
void parse_from_file(const char *filename);
void print_gates();
bool is_valid_circuit();
// local search
bool local_search(std::unordered_set<Fault*> &faults);
@ -125,4 +127,8 @@ Gate* ls_pick();
void ls_flip(Gate* stem);
void ls_update(Gate* stem);
// checker
int check_circuit();
};

View File

@ -2,6 +2,22 @@
#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 fpl[2];
@ -11,6 +27,7 @@ int Gate::cal_propagate_len(bool x) {
if(!out->is_detected(this)) continue;
fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1);
}
return fpl[x];
}

View File

@ -13,7 +13,42 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
// 随机生成初始电路
ls_init_circuit(faults);
// print_gates();
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);
//printf("local search!\n");
@ -54,14 +89,80 @@ Gate* Circuit::ls_pick() {
void Circuit::ls_flip(Gate* gate) {
printf("flip: %s\n", gate->name.c_str());
gate->value ^= 1;
gate->update_gate_property();
gate->update_gate_statistics();
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() {
@ -92,11 +193,11 @@ void Circuit::ls_init_circuit(std::unordered_set<Fault*> &faults) {
}
for(Gate* g : rtopo_gates) {
g->value_satisfied = ( g->cal_value() == g->value );
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;
g->fault_detected_satisfied[0] = g->fault_detected_satisfied[1] = 0;
g->update_gate_property();
}
for(Gate* g : rtopo_gates) {
g->update_gate_statistics();
}
// cal score

View File

@ -19,6 +19,7 @@ int main(int args, char* argv[]) {
circuit->parse_from_file(argv[1]);
circuit->init_topo_index();
circuit->init_gate_level();
circuit->init_reigons();
printf(" Done.\n");
printf("====== Circuit Statistics ====== \n");
@ -38,7 +39,7 @@ int main(int args, char* argv[]) {
while(true) {
bool ls = circuit->local_search(faults);
bool is_valid = circuit->is_valid_circuit();
bool is_valid = circuit->check_circuit();
printf("checking valid circuit ...");
printf(" result: %d.\n", is_valid);
if(!ls) break;

View File

@ -1,7 +1,23 @@
#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_fault_propagated_weight[0] = cal_score_fault_propagated_weight(0);
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[1] = cal_score_fault_detected_unsatisfied_cost(1);
value ^= 1;
return - score_value_unsatisfied_cost
+ score_fault_propagated_weight[0] + score_fault_propagated_weight[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 res = 0;
value ^= 1;
for(Gate* g : fanouts) {
if(g->value_satisfied && g->cal_value() != g->value) {
res += g->value_unsatisfied_cost;
@ -33,44 +50,34 @@ int Gate::cal_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;
} else {
}
if(!this->value_satisfied && this->cal_value() == this->value) {
res -= this->value_unsatisfied_cost;
}
value ^= 1;
return res;
}
int Gate::cal_score_fault_propagated_weight(int sa) {
int res = 0;
value ^= 1;
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;
res += (this->cal_propagate_len(sa) - this->fault_propagated_len[sa] ) * this->fault_propagated_weight[sa];
return res;
}
int Gate::cal_score_fault_propagated_unsatisfied_cost(int sa) {
int res = 0;
value ^= 1;
int origin_fault_propagated_len = this->fault_propagated_len[sa];
this->fault_propagated_len[sa] = this->cal_propagate_len(sa);
int origin_fault_propagated_len[2];
origin_fault_propagated_len[0] = this->fault_propagated_len[0];
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]) {
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]) {
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;
value ^= 1;
this->fault_propagated_len[0] = origin_fault_propagated_len[0];
this->fault_propagated_len[1] = origin_fault_propagated_len[1];
return res;
}
int Gate::cal_score_fault_detected_weight(int sa) {
int res = 0;
value ^= 1;
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;
res += ( this->cal_fault_detected(sa) - this->fault_detected[sa] ) * this->fault_detected_weight[sa];
return res;
}
int Gate::cal_score_fault_detected_unsatisfied_cost(int sa) {
int res = 0;
value ^= 1;
int origin_fault_detected = this->fault_detected[sa];
this->fault_detected[sa] = this->cal_fault_detected(sa);
int origin_fault_detected[2];
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];
}
for(Gate* g : fanins) {
for(Gate* g : this->reigon) {
if(g->fault_detected_satisfied[sa] && g->cal_fault_detected(sa) != g->fault_detected[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;
}