最初版本完工

This commit is contained in:
YuhangQ 2023-02-23 11:00:24 +08:00
parent 94224308de
commit acfeb1be4b
10 changed files with 11419 additions and 75 deletions

8829
_c6288.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
atpg

Binary file not shown.

2484
c6288.bench Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,12 @@
void Circuit::init_stems() {
for(auto& gate: gates) {
if(gate->outputs.size() >= 2) {
if(rand() % 10 <= 2) {
gate->stem = true;
}
// if(gate->outputs.size() >= 3) {
// }
if(gate->stem) {
stems.push_back(gate);
}
@ -116,29 +119,35 @@ bool Circuit::is_valid_circuit() {
flip_total_cnt++;
}
if(g->stem && g->cal_value() == g->value) {
if(g->stem && g->cal_value() != g->value) {
stem_total_weight += stem_weight[g->id];
}
if(g->stem && g->cal_value() == g->value) {
stem_total_cnt++;
}
if(g->sa[0]) {
fault_total_weight += fault_weight[g->id][0];
fault_total_cnt++;
fault_total_cnt += 1;
}
if(g->sa[1]) {
fault_total_weight += fault_weight[g->id][1];
fault_total_cnt++;
fault_total_cnt += 1;
}
// 检查门的赋值情况
if(!g->stem && g->cal_value() != g->value) {
if(g->cal_value() != g->value) {
printf("WRONG-ASSGIN: %s \n", g->name.c_str());
return false;
}
// 检查 PO 的传播设定是否正确
if(g->isPO) {
if(g->sa[g->value] != 0 || g->sa[!g->value] == 0 ) return false;
if(g->sa[g->value] != 0 || g->sa[!g->value] == 0 ) {
printf("WRONG-PO: %s \n", g->name.c_str());
}
continue;
}
@ -164,22 +173,23 @@ bool Circuit::is_valid_circuit() {
}
if(sa0 != g->sa[0] || sa1 != g->sa[1]) {
printf("---- %s \n", g->name.c_str());
exit(-1);
printf("WRONG-SA: %s \n", g->name.c_str());
return false;
}
}
if(this->flip_total_weight != flip_total_weight || this->stem_total_weight != stem_total_weight || this->fault_total_weight != fault_total_weight) {
printf("CIRCUIT CHECK FAILED!\n");
printf("[wrong] flip: %d, stem: %d, fault:%d\n", this->flip_total_weight, this->stem_total_weight, this->fault_total_weight);
printf("[right] flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight);
return false;
}
if(this->flip_total_cnt != flip_total_cnt || this->stem_total_cnt != stem_total_cnt || this->fault_total_cnt != fault_total_cnt) {
printf("CIRCUIT CHECK FAILED!\n");
printf("[wrong] flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", this->flip_total_cnt, this->stem_total_cnt, this->fault_total_cnt);
printf("[right] flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", flip_total_cnt, stem_total_cnt, fault_total_weight);
return false;
}
return true;

View File

@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
using ll = long long;
@ -23,8 +24,6 @@ public:
std::vector<Gate*> pre_stems;
std::vector<Gate*> suc_stems;
std::vector<Gate*> block;
std::vector<Gate*> outputs;
std::vector<Gate*> inputs;
@ -61,11 +60,11 @@ void init_stems();
// local search
std::vector<int> local_search(const std::vector<Fault*> &faults);
bool local_search(std::unordered_set<Fault*> &faults);
// incremental flip struct
const double SP = 0.05;
const double SP = 0.01;
const int FLIP_INC = 1;
const int FLIP_WEIGHT_MAX = 1e9;
@ -79,7 +78,7 @@ int* flip_need_update;
std::vector<Gate*> flip_update_queue;
// incremental stem struct
const int STEM_INC = 10;
const int STEM_INC = 100;
const int STEM_WEIGHT_MAX = 1e9;
ll stem_total_weight;
int stem_total_cnt;
@ -87,14 +86,14 @@ int* stem_weight;
int* stem_satisfied;
const int FAULT_INC = 1;
const int FAULT_WEIGHT_MAX = 100;
const int FAULT_WEIGHT_MAX = 20;
ll fault_total_weight;
int fault_total_cnt;
int** fault_weight;
int** fault_detected;
void ls_init_circuit();
void ls_init_weight(const std::vector<Fault*> &faults);
void ls_init_weight(const std::unordered_set<Fault*> &faults);
void ls_update_weight();
void ls_init_data_structs();

111
ls.cpp
View File

@ -6,7 +6,7 @@
#include <algorithm>
#include "assert.h"
std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
// 初始化并重置所有 ls 数据结构
ls_init_data_structs();
@ -21,12 +21,6 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
while(true) {
if(stem_total_cnt == stems.size() && flip_total_cnt == 0) {
printf("FIND SOLUTION!\n");
printf("[SOL] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %lld, stem_cnt: %lld, fault_cnt:%lld\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
break;
}
Gate* stem = nullptr;
ll max_score = 0;
@ -57,8 +51,8 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
}
if(max_score > 0) {
printf("FLIP: %s\n", stem->name.c_str());
printf("[LS] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %lld, stem_cnt: %lld, fault_cnt:%lld\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
// printf("FLIP: %s\n", stem->name.c_str());
printf("[LS] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
ls_flip(stem);
CC[stem->id] = 0;
@ -84,19 +78,12 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
ls_update(g);
}
std::queue<Gate*> q;
std::unordered_map<Gate*, bool> used;
for(Gate* pi : PIs) {
used[pi] = true;
q.push(pi);
if(stem_total_cnt == stems.size() && flip_total_cnt == 0) {
printf("FIND SOLUTION!\n");
printf("[SOL] flip: %lld, stem: %lld, fault:%lld. flip_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", flip_total_weight, stem_total_weight, fault_total_weight, flip_total_cnt, stem_total_cnt, fault_total_cnt);
break;
}
// while(!q.empty()) {
// }
// assert(flip_total_cnt == 0);
std::vector<Gate*> candidates;
for(Gate *g : stems) {
if(g->isPO) continue;
@ -136,29 +123,45 @@ std::vector<int> Circuit::local_search(const std::vector<Fault*> &faults) {
ls_update(g);
}
//print_gates();
return std::vector<int>();
static int original_faults = -1;
if(original_faults == - 1) {
original_faults = faults.size();
}
static int pattern = 0;
std::unordered_set<Fault*> tmp = faults;
for(Fault* f : tmp) {
if(f->gate->sa[f->type]) {
faults.erase(f);
}
}
if(tmp.size() == faults.size()) pattern--;
printf("coverage: %.4f\tpattern: %d\tbefore: %d\tnow: %d\n", (double)(original_faults - faults.size()) / (original_faults), ++pattern, tmp.size(), faults.size());
//if(tmp.size() == faults.size()) return false;
return true;
}
void Circuit::ls_update_weight() {
if(rand() % 10 < 3) {
for(Gate* g : gates) {
if(g->stem && stem_satisfied[g->id] && (stem_weight[g->id] - STEM_INC > 1)) {
stem_weight[g->id] -= STEM_INC;
stem_total_weight -= STEM_INC;
for(Gate* suc : g->suc_stems) {
if(!stem_satisfied[suc->id]) {
stem_weight[suc->id] += STEM_INC;
}
}
//stem_total_weight += STEM_INC;
}
}
if(rand() % 10000 <= SP * 10000) {
// for(Gate* g : gates) {
// if(g->stem && stem_satisfied[g->id] && (stem_weight[g->id] - STEM_INC >= 1)) {
// stem_weight[g->id] -= STEM_INC;
// for(Gate* suc : g->suc_stems) {
// if(stem_weight[suc->id] + STEM_INC <= STEM_WEIGHT_MAX) {
// stem_weight[suc->id] += STEM_INC;
// if(!stem_satisfied[suc->id]) {
// stem_total_weight += STEM_INC;
// }
// }
// }
// }
// }
} else {
for(Gate* g : gates) {
if(flip_need_update[g->id] && (flip_weight[g->id] + FLIP_INC < FLIP_WEIGHT_MAX)) {
@ -168,15 +171,25 @@ void Circuit::ls_update_weight() {
if(g->stem && !stem_satisfied[g->id] && (stem_weight[g->id] + STEM_INC < STEM_WEIGHT_MAX)) {
stem_weight[g->id] += STEM_INC;
stem_total_weight += STEM_INC;
for(Gate* suc : g->suc_stems) {
if(stem_weight[suc->id] - STEM_INC > 1) {
stem_weight[suc->id] -= STEM_INC;
if(stem_satisfied[suc->id]) {
if(!stem_satisfied[suc->id]) {
stem_total_weight -= STEM_INC;
}
}
}
for(Gate* pre : g->pre_stems) {
if(stem_weight[pre->id] + STEM_INC < STEM_WEIGHT_MAX) {
stem_weight[pre->id] += STEM_INC;
if(!stem_satisfied[pre->id]) {
stem_total_weight += STEM_INC;
}
}
}
}
if(!g->sa[0] && fault_weight[g->id][0] > 0 && (fault_weight[g->id][0] + FAULT_INC < FAULT_WEIGHT_MAX)) {
@ -216,7 +229,7 @@ ll Circuit::ls_pick_score(Gate* stem) {
}
ll Circuit::ls_score() {
ll score = - flip_total_weight + stem_total_weight + fault_total_weight;
ll score = -flip_total_weight -stem_total_weight + fault_total_weight;
return score;
}
@ -230,13 +243,13 @@ void Circuit::ls_block_recal(Gate* stem) {
if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){
stem_satisfied[stem->id] = true;
stem_total_weight += stem_weight[stem->id];
stem_total_weight -= stem_weight[stem->id];
stem_total_cnt += 1;
}
if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) {
stem_satisfied[stem->id] = false;
stem_total_weight -= stem_weight[stem->id];
stem_total_weight += stem_weight[stem->id];
stem_total_cnt -= 1;
}
@ -296,13 +309,13 @@ void Circuit::ls_block_recal(Gate* stem) {
if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){
stem_satisfied[stem->id] = true;
stem_total_weight += stem_weight[stem->id];
stem_total_weight -= stem_weight[stem->id];
stem_total_cnt += 1;
}
if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) {
stem_satisfied[stem->id] = false;
stem_total_weight -= stem_weight[stem->id];
stem_total_weight += stem_weight[stem->id];
stem_total_cnt -= 1;
}
}
@ -381,9 +394,10 @@ void Circuit::ls_block_recal(Gate* stem) {
}
}
void Circuit::ls_init_weight(const std::vector<Fault*> &faults) {
void Circuit::ls_init_weight(const std::unordered_set<Fault*> &faults) {
for(Gate* s : stems) {
stem_weight[s->id] = 1;
stem_total_weight += stem_weight[s->id];
}
for(Fault* f : faults) {
fault_weight[f->gate->id][f->type] = 1;
@ -398,6 +412,11 @@ void Circuit::ls_init_circuit() {
// pi->value = rand() % 2;
// }
for(Gate* g : gates) {
g->sa[0] = 0;
g->sa[1] = 0;
}
for(Gate* s : stems) {
s->value = rand() % 2;
}

View File

@ -28,20 +28,25 @@ int main(int args, char* argv[]) {
printf("Stem:\t%ld\n", circuit->stems.size());
printf("================================ \n");
std::vector<Fault*> faults;
std::unordered_set<Fault*> faults;
// init faults
for(auto stem : circuit->stems) {
faults.push_back(new Fault(stem, Fault::SA0));
faults.push_back(new Fault(stem, Fault::SA1));
for(auto g : circuit->gates) {
faults.insert(new Fault(g, Fault::SA0));
faults.insert(new Fault(g, Fault::SA1));
}
auto pattern = circuit->local_search(faults);
while(true) {
bool ls = circuit->local_search(faults);
bool is_valid = circuit->is_valid_circuit();
printf("checking valid circuit ...");
printf(" result: %d.\n", is_valid);
if(!ls) break;
if(!is_valid) break;
if(faults.size() == 0) break;
}
printf("checking valid circuit ...");
printf(" result: %d.\n", circuit->is_valid_circuit());
printf("[final] flip: %d, stem: %d, fault:%d\n", circuit->flip_total_weight, circuit->stem_total_weight, circuit->fault_total_weight);
//printf("[final] flip: %d, stem: %d, fault:%d\n", circuit->flip_total_weight, circuit->stem_total_weight, circuit->fault_total_weight);
return 0;
}

View File

@ -7,7 +7,7 @@
#编译工具用g++以同时支持C和C++程序,以及二者的混合编译
CC=g++
CPPFLAGS=-O3 -std=c++17 -g
CPPFLAGS=-O3 -std=c++17
#使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表
#sources:=main.cpp command.c

View File

@ -1,2 +0,0 @@
set -e; rm -f ls.d; g++ -MM -O3 -std=c++17 -g ls.cpp > ls.d.$$; sed 's,\(ls\)\.o[ :]*,\1.o ls.d : ,g' < ls.d.$$ > ls.d; rm -f ls.d.$$
g++ -O3 -std=c++17 -g -c ls.cpp -o ls.o

View File

@ -34,7 +34,7 @@ void Circuit::parse_from_file(const char *filename) {
}
// buf 10MB
file.rdbuf()->pubsetbuf(0, 10 *1024 * 1024);
file.rdbuf()->pubsetbuf(0, 10 * 1024 * 1024);
std::vector<std::string> bufPO;