更新了flip

This commit is contained in:
YuhangQ 2023-02-20 13:08:25 +08:00
parent 87b8d2ab6c
commit 6861108609
6 changed files with 319 additions and 40271 deletions

BIN
atpg

Binary file not shown.

View File

@ -48,7 +48,7 @@ void Circuit::init_topo_index() {
} }
for(auto in : PIs) { for(auto in : PIs) {
in->topo = topo++; in->id = topo++;
q.push(in); q.push(in);
} }
@ -57,7 +57,7 @@ void Circuit::init_topo_index() {
for(Gate* out : g->outputs) { for(Gate* out : g->outputs) {
ins[out]--; ins[out]--;
if(ins[out] == 0) { if(ins[out] == 0) {
out->topo = topo++; out->id = topo++;
q.push(out); q.push(out);
} }
} }
@ -113,12 +113,10 @@ bool Circuit::is_valid_circuit() {
if(sa0 != g->sa[0] || sa1 != g->sa[1]) { if(sa0 != g->sa[0] || sa1 != g->sa[1]) {
printf("---- %s \n", g->name.c_str()); printf("---- %s \n", g->name.c_str());
//return false; exit(-1);
} }
} }
return true; return true;
} }

View File

@ -5,9 +5,11 @@
#include <unordered_map> #include <unordered_map>
#include <queue> #include <queue>
using ll = long long;
class Gate { class Gate {
public: public:
int topo; int id;
std::string name; std::string name;
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type; enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type;
int value; int value;
@ -33,8 +35,7 @@ class Fault {
public: public:
Gate* gate; Gate* gate;
enum Type { SA0, SA1 } type; enum Type { SA0, SA1 } type;
bool detected; Fault(Gate* gate, Type type):gate(gate),type(type) {}
Fault(Gate* gate, Type type):gate(gate),type(type),detected(0) {}
}; };
class Circuit { class Circuit {
@ -57,13 +58,28 @@ bool is_valid_circuit();
void init_topo_index(); void init_topo_index();
void init_stems(); void init_stems();
// local search // local search
std::vector<int> local_search(const std::vector<Fault*> &faults); std::vector<int> local_search(const std::vector<Fault*> &faults);
// incremental flip struct
ll flip_total_weight;
int* flip_weight;
int* flip_need_update;
std::vector<Gate*> flip_update_queue;
// incremental stem struct
ll stem_total_weight;
int* stem_weight;
int* stem_satisfied;
ll fault_total_weight;
int** fault_weight;
int** fault_detected;
void ls_init_circuit(); void ls_init_circuit();
void ls_init_vector(std::vector<Gate*> *vec); void ls_init_weight(const std::vector<Fault*> &faults);
void ls_init_data_structs();
void ls_flip(Gate* stem); void ls_flip(Gate* stem);
}; };

96
ls.cpp
View File

@ -7,25 +7,36 @@
std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) { std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
// local search vector // 初始化并清零所有 ls 数据结构
ls_init_data_structs();
// 赋值初始权重
ls_init_weight(faults);
// 随机生成初始电路
ls_init_circuit(); ls_init_circuit();
printf("local search!\n"); printf("local search!\n");
//ls_flip(PIs[0]); //ls_flip(PIs[0]);
print_gates(); //print_gates();
return std::vector<int>(); return std::vector<int>();
} }
bool cmp(Gate* a, Gate *b) { bool cmp(Gate* a, Gate *b) {
return a->topo > b->topo; return a->id > b->id;
} }
void Circuit::ls_flip(Gate* stem) { void Circuit::ls_flip(Gate* stem) {
printf("flip: %s\n", stem->name.c_str()); if(flip_need_update[stem->id]) {
flip_need_update[stem->id] = false;
flip_total_weight -= flip_weight[stem->id];
}
//printf("flip: %s\n", stem->name.c_str());
//stem->value = !stem->value; //stem->value = !stem->value;
@ -60,13 +71,8 @@ void Circuit::ls_flip(Gate* stem) {
assert(q.empty()); assert(q.empty());
used.clear(); used.clear();
// update path info
std::vector<Gate*> update_list;
for(Gate* stem : suc_stems) { for(Gate* stem : suc_stems) {
q.push(stem); q.push(stem);
//printf("suc: %s\n", stem->name.c_str());
} }
while(!q.empty()) { while(!q.empty()) {
@ -100,13 +106,22 @@ void Circuit::ls_flip(Gate* stem) {
in->sa[1] |= p.second; in->sa[1] |= p.second;
} }
if(in->stem && (in->sa[0] != old_sa[0] || in->sa[0] != old_sa[0])) { if(in->stem && !in->isPI && (in->sa[0] != old_sa[0] || in->sa[1] != old_sa[1])) {
bool exist = false;
for(Gate* pre : in->pre_stems) { for(Gate* pre : in->pre_stems) {
if(!tmp_used[pre]) { if(flip_need_update[pre->id]) {
tmp_used[pre] = true; exist = true;
tmp.push(pre);
} }
} }
if(!exist) {
Gate* pre = in->pre_stems[0];
flip_need_update[pre->id] = true;
flip_update_queue.push_back(pre);
flip_total_weight += flip_weight[pre->id];
}
} }
//printf("gate: %s -> %s rv: %d id: %d p:%d sa0: %d sa1: %d\n", in->name.c_str(), g->name.c_str(), right_value, input_detected, g->is_propagated(), in->sa[0], in->sa[1]); //printf("gate: %s -> %s rv: %d id: %d p:%d sa0: %d sa1: %d\n", in->name.c_str(), g->name.c_str(), right_value, input_detected, g->is_propagated(), in->sa[0], in->sa[1]);
@ -119,6 +134,18 @@ void Circuit::ls_flip(Gate* stem) {
} }
} }
void Circuit::ls_init_weight(const std::vector<Fault*> &faults) {
for(Gate* s : stems) {
stem_weight[s->id] = 1;
}
for(Fault* f : faults) {
fault_weight[f->gate->id][f->type] = 1;
}
for(Gate* s: stems) {
flip_weight[s->id] = 1;
}
}
void Circuit::ls_init_circuit() { void Circuit::ls_init_circuit() {
// for(auto pi : PIs) { // for(auto pi : PIs) {
// pi->value = rand() % 2; // pi->value = rand() % 2;
@ -129,15 +156,46 @@ void Circuit::ls_init_circuit() {
} }
for(int i=stems.size()-1; i>=0; i--) { for(int i=stems.size()-1; i>=0; i--) {
stems[i]->value = !stems[i]->value;
ls_flip(stems[i]); ls_flip(stems[i]);
} }
while(!flip_update_queue.empty()) {
while(!tmp.empty()) { Gate* g = flip_update_queue.back();
Gate* g = tmp.front(); flip_update_queue.pop_back();
tmp.pop(); flip_need_update[g->id] = false;
tmp_used[g] = false;
ls_flip(g); ls_flip(g);
} }
} }
void Circuit::ls_init_data_structs() {
const int MAX_LEN = gates.size() + 1;
if(flip_weight == nullptr) {
flip_weight = new int[MAX_LEN];
flip_need_update = new int[MAX_LEN];
stem_weight = new int[MAX_LEN];
stem_satisfied = new int[MAX_LEN];
fault_weight = new int*[MAX_LEN];
for(int i=0; i<MAX_LEN; i++) {
fault_weight[i] = new int[2];
}
fault_detected = new int*[MAX_LEN];
for(int i=0; i<MAX_LEN; i++) {
fault_detected[i] = new int[2];
}
} else {
for(int i=0; i<MAX_LEN; i++) {
flip_weight[i] = 0;
flip_need_update[i] = 0;
stem_weight[i] = 0;
stem_satisfied[i] = 0;
fault_weight[i][0] = 0;
fault_weight[i][1] = 0;
fault_detected[i][0] = 0;
fault_detected[i][1] = 0;
}
}
}

View File

@ -13,33 +13,33 @@ int main(int args, char* argv[]) {
srand(19260817); srand(19260817);
Circuit circuit; Circuit* circuit = new Circuit();
printf("parsing file %s ...", argv[1]); printf("parsing file %s ...", argv[1]);
circuit.parse_from_file(argv[1]); circuit->parse_from_file(argv[1]);
circuit.init_stems(); circuit->init_stems();
circuit.init_topo_index(); circuit->init_topo_index();
printf(" Done.\n"); printf(" Done.\n");
printf("====== Circuit Statistics ====== \n"); printf("====== Circuit Statistics ====== \n");
printf("PI:\t%ld\n", circuit.PIs.size()); printf("PI:\t%ld\n", circuit->PIs.size());
printf("PO:\t%ld\n", circuit.POs.size()); printf("PO:\t%ld\n", circuit->POs.size());
printf("Gate:\t%ld\n", circuit.name2gate.size()); printf("Gate:\t%ld\n", circuit->name2gate.size());
printf("Stem:\t%ld\n", circuit.stems.size()); printf("Stem:\t%ld\n", circuit->stems.size());
printf("================================ \n"); printf("================================ \n");
std::vector<Fault*> faults; std::vector<Fault*> faults;
// init faults // init faults
for(auto stem : circuit.stems) { for(auto stem : circuit->stems) {
faults.push_back(new Fault(stem, Fault::SA0)); faults.push_back(new Fault(stem, Fault::SA0));
faults.push_back(new Fault(stem, Fault::SA1)); faults.push_back(new Fault(stem, Fault::SA1));
} }
auto pattern = circuit.local_search(faults); auto pattern = circuit->local_search(faults);
printf("checking valid circuit ..."); printf("checking valid circuit ...");
printf(" result: %d.\n", circuit.is_valid_circuit()); printf(" result: %d.\n", circuit->is_valid_circuit());

40438
output.txt

File diff suppressed because it is too large Load Diff