diff --git a/atpg b/atpg index 41737ba..77fcaa4 100755 Binary files a/atpg and b/atpg differ diff --git a/src/checker.cpp b/src/checker.cpp index 4e4fdd9..670d6e4 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -12,25 +12,40 @@ int Circuit::check_circuit() { 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) { + 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->fault_detected[0]) sum_fault_detected_weight += g->fault_detected_weight[0]; diff --git a/src/circuit.cpp b/src/circuit.cpp index ac466fe..e90a47f 100644 --- a/src/circuit.cpp +++ b/src/circuit.cpp @@ -109,6 +109,42 @@ void Circuit::init_reigons() { std::sort(g->reigon.begin(), g->reigon.end()); g->reigon.erase(unique(g->reigon.begin(), g->reigon.end()), g->reigon.end()); } + + std::unordered_set 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() { diff --git a/src/circuit.h b/src/circuit.h index 72b618c..a5e702f 100644 --- a/src/circuit.h +++ b/src/circuit.h @@ -8,9 +8,14 @@ using ll = long long; + +class Circuit; + class Gate { public: + Gate(Circuit* C):C(C) {} + // gate basic info int id; @@ -24,6 +29,7 @@ public: std::vector fanouts; std::vector fanins; std::vector reigon; + std::vector score_reigon; // circuit-ls info int value_satisfied; @@ -40,6 +46,9 @@ public: int fault_detected_satisfied[2]; int fault_detected_unsatisfied_cost[2]; + + int good_var_index; + int unsatisfied_var_index; int CC; @@ -77,7 +86,7 @@ public: // score calculation function - int cal_score(int debug=0); + void cal_score(int debug=0); int cal_value_unsatisfied_cost(); @@ -88,6 +97,10 @@ public: int cal_score_fault_detected_weight(int sa); int cal_score_fault_detected_unsatisfied_cost(int sa); + + +private: + Circuit* C; }; class Fault { @@ -118,6 +131,15 @@ void parse_from_file(const char *filename); void print_gates(); // local search + +std::vector good_vars; +std::unordered_set value_unsatisfied_vars; +std::unordered_set value_satisfied_vars; +std::unordered_set propagated_unsatisfied_vars; +std::unordered_set propagated_satisfied_vars; +std::unordered_set detected_unsatisfied_vars; +std::unordered_set detected_satisfied_vars; + bool local_search(std::unordered_set &faults); void ls_init_circuit(std::unordered_set &faults); diff --git a/src/gate.cpp b/src/gate.cpp index b1a0326..655fe46 100644 --- a/src/gate.cpp +++ b/src/gate.cpp @@ -12,10 +12,35 @@ void Gate::update_gate_property() { void Gate::update_gate_statistics() { 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[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[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) { diff --git a/src/ls.cpp b/src/ls.cpp index 76706ae..6c86f5c 100644 --- a/src/ls.cpp +++ b/src/ls.cpp @@ -16,22 +16,24 @@ bool Circuit::local_search(std::unordered_set &faults) { // print_gates(); printf("generate random circuit done!\n"); - - srand(19260817); - int T = 10000000; + + int iter = 0; 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(); - - int i = rand()%gates.size(); - Gate* flip_gate = gates[i]; - - int dert = flip_gate->score; + Gate* gate = ls_pick(); + ls_flip(gate); // printf("svuc: %d, sfpw: %d, sfpuc: %d, sfdw: %d, sfduc: %d <<<\n", // flip_gate->score_value_unsatisfied_cost, @@ -40,7 +42,7 @@ bool Circuit::local_search(std::unordered_set &faults) { // 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); @@ -49,15 +51,9 @@ bool Circuit::local_search(std::unordered_set &faults) { // printf("i: %s\n", flip_gate->name.c_str()); } - exit(0); - - //printf("local search!\n"); - - while(true) { - Gate* gate = ls_pick(); - if(gate == nullptr) { - break; - } + // execute simulation + for(Gate* g : rtopo_gates) { + g->update_gate_statistics(); } static int original_faults = -1; @@ -78,22 +74,85 @@ bool Circuit::local_search(std::unordered_set &faults) { 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; return true; } Gate* Circuit::ls_pick() { - return nullptr; + static int focus = 1; + + double SP = 0.1; + + if(rand() % 1000 <= 500 * SP) { + std::vector 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 tmp; + for(Gate* g : value_unsatisfied_vars) { + tmp.push_back(g); + } + + return tmp[rand()%tmp.size()]; +} + +void Circuit::ls_update_weight() { + + std::unordered_set 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) { - printf("flip: %s\n", gate->name.c_str()); + // printf("flip: %s\n", gate->name.c_str()); gate->value ^= 1; gate->update_gate_property(); - gate->update_gate_statistics(); for(Gate* g : gate->fanouts) { @@ -107,76 +166,37 @@ void Circuit::ls_flip(Gate* gate) { // g->score = g->cal_score(); // } - gate->score = gate->cal_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->score_reigon) { + g->cal_score(); } - 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 r_set: %d\n", t.size(), cal_cnt, gate->score_reigon.size()); - 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); - } - } + // 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(Gate* stem) { - - -} - void Circuit::ls_init_circuit(std::unordered_set &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 for(Gate* g : gates) { g->value = rand() % 2; @@ -185,6 +205,8 @@ void Circuit::ls_init_circuit(std::unordered_set &faults) { 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_unsatisfied_cost[0] = g->fault_detected_unsatisfied_cost[1] = 1; + g->good_var_index = -1; + g->unsatisfied_var_index = -1; } for(Fault* f : faults) { @@ -202,7 +224,7 @@ void Circuit::ls_init_circuit(std::unordered_set &faults) { // cal score for(Gate* g : gates) { - g->score = g->cal_score(); + g->cal_score(); printf("%d ", g->score); } diff --git a/src/main.cpp b/src/main.cpp index 0186fb6..b09cc1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,12 +42,9 @@ int main(int args, char* argv[]) { bool is_valid = circuit->check_circuit(); printf("checking valid circuit ..."); printf(" result: %d.\n", is_valid); - if(!ls) break; - if(!is_valid) break; + // if(!ls) break; + // if(!is_valid) 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); diff --git a/src/options.h b/src/options.h index 1996ed8..9a3748c 100644 --- a/src/options.h +++ b/src/options.h @@ -1,3 +1,8 @@ +#define DEBUG 1 + + + + const double SP = 0.01; const int STEM_INC = 0; diff --git a/src/parser.cpp b/src/parser.cpp index 6de1483..241d100 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -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->isPI = false; gate->isPO = false; @@ -108,7 +108,7 @@ void Circuit::parse_from_file(const char *filename) { } // input 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->type = Gate::INPUT; gate->isPI = true; diff --git a/src/score.cpp b/src/score.cpp index c6389f3..28c1160 100644 --- a/src/score.cpp +++ b/src/score.cpp @@ -1,7 +1,7 @@ #include "circuit.h" -int Gate::cal_score(int debug) { +void Gate::cal_score(int debug) { value ^= 1; @@ -33,11 +33,29 @@ int Gate::cal_score(int debug) { 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_unsatisfied_cost[0] - score_fault_propagated_unsatisfied_cost[1] + score_fault_detected_weight[0] + score_fault_detected_weight[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() {