diff --git a/.vscode/launch.json b/.vscode/launch.json index e958803..99d6a2b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -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 启用整齐打印", diff --git a/.vscode/settings.json b/.vscode/settings.json index 60c8f0e..a7cc3c8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" } } \ No newline at end of file diff --git a/atpg b/atpg index 66d1f2a..41737ba 100755 Binary files a/atpg and b/atpg differ diff --git a/crun b/crun index 7adf915..f51e9a7 100755 --- a/crun +++ b/crun @@ -7,6 +7,7 @@ make -j if [ $? -ne 0 ]; then echo "compile failed." else + clear echo "========================" time ./atpg $1 fi diff --git a/src/checker.cpp b/src/checker.cpp new file mode 100644 index 0000000..4e4fdd9 --- /dev/null +++ b/src/checker.cpp @@ -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; +} \ No newline at end of file diff --git a/src/circuit.cpp b/src/circuit.cpp index f67abe8..ac466fe 100644 --- a/src/circuit.cpp +++ b/src/circuit.cpp @@ -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; +// } diff --git a/src/circuit.h b/src/circuit.h index 682fa32..72b618c 100644 --- a/src/circuit.h +++ b/src/circuit.h @@ -23,6 +23,7 @@ public: bool isPO; std::vector fanouts; std::vector fanins; + std::vector 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 POs; std::vector gates; std::vector rtopo_gates; - std::unordered_map name2gate; // std::queue tmp; @@ -109,12 +112,11 @@ std::unordered_map 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 &faults); @@ -125,4 +127,8 @@ Gate* ls_pick(); void ls_flip(Gate* stem); void ls_update(Gate* stem); +// checker + +int check_circuit(); + }; \ No newline at end of file diff --git a/src/gate.cpp b/src/gate.cpp index 269ae3a..b1a0326 100644 --- a/src/gate.cpp +++ b/src/gate.cpp @@ -2,8 +2,24 @@ #include "assert.h" -int Gate::cal_propagate_len(bool x) { +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]; fpl[0] = fpl[1] = 0; @@ -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]; } diff --git a/src/ls.cpp b/src/ls.cpp index 52530d9..76706ae 100644 --- a/src/ls.cpp +++ b/src/ls.cpp @@ -13,7 +13,42 @@ bool Circuit::local_search(std::unordered_set &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 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 &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 diff --git a/src/main.cpp b/src/main.cpp index 314c401..0186fb6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; diff --git a/src/score.cpp b/src/score.cpp index 09046e8..c6389f3 100644 --- a/src/score.cpp +++ b/src/score.cpp @@ -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; } \ No newline at end of file