diff --git a/.gitignore b/.gitignore index 311e9bd..2d1b1b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ *.o *.d -.vscode output.txt diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..cd3d381 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.makefile-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e958803 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,34 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) 启动", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/atpg", + "args": ["c432.bench"], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "为 gdb 启用整齐打印", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "将反汇编风格设置为 Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ], + "preLaunchTask": "build" + } + + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..1e38ab0 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,12 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "make -j 8" + } + ] +} \ No newline at end of file diff --git a/atpg b/atpg index 8ca5c14..1f210c7 100755 Binary files a/atpg and b/atpg differ diff --git a/circuit.cpp b/circuit.cpp index 3b7d3be..4376100 100644 --- a/circuit.cpp +++ b/circuit.cpp @@ -10,6 +10,10 @@ void Circuit::init_stems() { if(gate->outputs.size() >= 2) { gate->stem = true; } + // gate->stem = true; + // if(rand() % 1000 <= 100) { + // gate->stem = true; + // } if(gate->stem) { stems.push_back(gate); } @@ -137,10 +141,15 @@ bool Circuit::is_valid_circuit() { int stem_total_cnt = 0; int fault_total_cnt = 0; + ll fault_propagate_score = 0; + //printf("flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight); for(Gate* g : gates) { + fault_propagate_score += g->fault_propagate_len[0] * fault_weight[g->id][0]; + fault_propagate_score += g->fault_propagate_len[1] * fault_weight[g->id][1]; + if(flip_need_update[g->id]) { flip_total_weight += flip_weight[g->id]; flip_total_cnt++; @@ -225,6 +234,9 @@ bool Circuit::is_valid_circuit() { return false; } + printf("%lld %lld\n", fault_propagate_score , this->fault_propagate_score); + assert(fault_propagate_score == this->fault_propagate_score); + return true; } diff --git a/circuit.h b/circuit.h index 1239b43..d883458 100644 --- a/circuit.h +++ b/circuit.h @@ -61,7 +61,6 @@ bool is_valid_circuit(); void init_topo_index(); - int MAX_GATE_LEVEL; void init_gate_level(); void init_stems(); @@ -94,7 +93,7 @@ int* stem_weight; int* stem_satisfied; int fault_propagate_tatal_len; -int fault_propagate_score; +ll fault_propagate_score; const int FAULT_INC = 1; const int FAULT_WEIGHT_MAX = 20; @@ -118,4 +117,13 @@ ll ls_score(); int** simulate(); + +// time status + +int flip_cnt = 0; +double flip_time = 0; + +int update_cnt = 0; +double update_time = 0; + }; \ No newline at end of file diff --git a/fault-simulator b/fault-simulator new file mode 160000 index 0000000..54d48b9 --- /dev/null +++ b/fault-simulator @@ -0,0 +1 @@ +Subproject commit 54d48b917c1f5ab7a9ea4c8de2573b649dd73575 diff --git a/ls.cpp b/ls.cpp index 5ca1487..4757042 100644 --- a/ls.cpp +++ b/ls.cpp @@ -5,6 +5,9 @@ #include #include #include "assert.h" +#include + + bool Circuit::local_search(std::unordered_set &faults) { @@ -21,6 +24,8 @@ bool Circuit::local_search(std::unordered_set &faults) { while(true) { + auto start = std::chrono::system_clock::now(); + Gate* stem = nullptr; ll max_score = 0; @@ -36,7 +41,7 @@ bool Circuit::local_search(std::unordered_set &faults) { std::swap(stems_random[i], stems_random[rand()%stems_random.size()]); } - const int T = 25; + const int T = 50; int t = 0; for(int i=0; i &faults) { CC[suc->id] = 1; } + auto end = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = end - start; + flip_cnt++; + flip_time += elapsed_seconds.count(); + } else { ls_update_weight(); @@ -109,6 +119,11 @@ bool Circuit::local_search(std::unordered_set &faults) { CC[suc->id] = 1; } + auto end = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = end - start; + update_cnt++; + update_time += elapsed_seconds.count(); + //printf("[UP] 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); } } @@ -131,6 +146,9 @@ 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()); + printf("flip-cnt: %d flip-time: %.3fs update-cnt: %d update-time: %.3fs\n", flip_cnt, flip_time, update_cnt, update_time); + printf("time-per-flip: %.2fms time-per-update: %.2fms\n", flip_time / flip_cnt * 1000, update_time / update_cnt * 1000); + //if(tmp.size() == faults.size()) return false; return true; @@ -177,10 +195,12 @@ void Circuit::ls_update_weight() { if(!g->sa[0] && fault_weight[g->id][0] > 0 && (fault_weight[g->id][0] + FAULT_INC < FAULT_WEIGHT_MAX)) { fault_weight[g->id][0] += FAULT_INC; + fault_propagate_score += FAULT_INC * (g->fault_propagate_len[0]); } if(!g->sa[1] && fault_weight[g->id][1] > 0 && (fault_weight[g->id][1] + FAULT_INC < FAULT_WEIGHT_MAX)) { fault_weight[g->id][1] += FAULT_INC; + fault_propagate_score += FAULT_INC * (g->fault_propagate_len[1]); } } } @@ -195,9 +215,11 @@ void Circuit::ls_flip(Gate* stem) { stem->value = !stem->value; ls_block_recal(stem); } + void Circuit::ls_update(Gate* stem) { ls_block_recal(stem); } + ll Circuit::ls_pick_score(Gate* stem) { ll old_score = ls_score(); @@ -215,7 +237,7 @@ ll Circuit::ls_pick_score(Gate* stem) { ll Circuit::ls_score() { //ll score = - flip_total_weight - stem_total_weight + fault_total_weight + fault_propagate_tatal_len; - ll score = - flip_total_weight - stem_total_weight + 10 * fault_propagate_tatal_len; + ll score = - flip_total_weight - stem_total_weight + fault_propagate_score; return score; } @@ -224,9 +246,17 @@ void Circuit::ls_init_weight(const std::unordered_set &faults) { stem_weight[s->id] = 1; stem_total_weight += stem_weight[s->id]; } + for(Fault* f : faults) { fault_weight[f->gate->id][f->type] = 1; } + + int r = rand() % faults.size(); + auto it = faults.begin(); + std::advance(it, r); + + fault_weight[(*it)->gate->id][(*it)->type] = 1000000; + for(Gate* s: stems) { flip_weight[s->id] = 1; } @@ -280,7 +310,7 @@ void Circuit::ls_init_data_structs() { } } - STEM_INC = 0; + STEM_INC = 1; fault_propagate_score = 0; @@ -385,9 +415,10 @@ void Circuit::ls_block_recal(Gate* stem) { } } - std::queue q; - std::unordered_map used; - std::vector suc_stems; + static std::queue q; + static std::unordered_map used; + assert(q.empty()); + used.clear(); q.push(stem); @@ -397,7 +428,6 @@ void Circuit::ls_block_recal(Gate* stem) { used[g] = false; for(Gate* out : g->outputs) { if(out->stem) { - suc_stems.push_back(out); continue; } out->value = out->cal_value(); @@ -411,19 +441,22 @@ void Circuit::ls_block_recal(Gate* stem) { assert(q.empty()); used.clear(); - for(Gate* stem : suc_stems) { + for(Gate* stem : stem->suc_stems) { q.push(stem); int fpl0 = stem->cal_propagate_len(0); int fpl1 = stem->cal_propagate_len(1); if(fault_weight[stem->id][0]) { - fault_propagate_tatal_len += fpl0 - stem->fault_propagate_len[0]; + fault_propagate_tatal_len += (fpl0 - stem->fault_propagate_len[0]); } if(fault_weight[stem->id][1]) { - fault_propagate_tatal_len += fpl1 - stem->fault_propagate_len[1]; + fault_propagate_tatal_len += (fpl1 - stem->fault_propagate_len[1]); } + + fault_propagate_score += (fault_weight[stem->id][0] * (fpl0 - stem->fault_propagate_len[0])); + fault_propagate_score += (fault_weight[stem->id][1] * (fpl1 - stem->fault_propagate_len[1])); stem->fault_propagate_len[0] = fpl0; stem->fault_propagate_len[1] = fpl1; @@ -495,6 +528,9 @@ void Circuit::ls_block_recal(Gate* stem) { if(fault_weight[in->id][1]) { fault_propagate_tatal_len += fpl1 - in->fault_propagate_len[1]; } + + fault_propagate_score += fault_weight[in->id][0] * (fpl0 - in->fault_propagate_len[0]); + fault_propagate_score += fault_weight[in->id][1] * (fpl1 - in->fault_propagate_len[1]); in->fault_propagate_len[0] = fpl0; in->fault_propagate_len[1] = fpl1; diff --git a/makefile b/makefile index 79aab05..ae4c441 100644 --- a/makefile +++ b/makefile @@ -7,7 +7,7 @@ #编译工具用g++,以同时支持C和C++程序,以及二者的混合编译 CC=g++ -CPPFLAGS=-O3 -std=c++17 +CPPFLAGS=-O3 -std=c++17 -g #使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表 #sources:=main.cpp command.c diff --git a/report/atpg-ls-动态增量-仿真.txt b/report/atpg-ls-动态增量-仿真.txt new file mode 100644 index 0000000..40ce58f --- /dev/null +++ b/report/atpg-ls-动态增量-仿真.txt @@ -0,0 +1,30 @@ +--------------------------------------------------------------------------------------------------------------- +| data | fault coverage(ATPG-LS) | time(ATPG-LS) | cube(ATPG-LS) | pattern(ATPG-LS) | +| ----------------------- | ----------------------- | -------------------- | ------------- | ---------------- | +| ./benchmark/c17.bench | 100.000 | 0.035004615783691406 | 5 | 5 | +| ./benchmark/b06.bench | 100.000 | 0.07079482078552246 | 11 | 11 | +| ./benchmark/b01.bench | 100.000 | 0.09065485000610352 | 14 | 14 | +| ./benchmark/b03.bench | 100.000 | 2.3637137413024902 | 14 | 14 | +| ./benchmark/b09.bench | 100.000 | 3.8993797302246094 | 18 | 18 | +| ./benchmark/b10.bench | 100.000 | 6.369290351867676 | 29 | 29 | +| ./benchmark/b08.bench | 100.000 | 7.467808723449707 | 35 | 35 | +| ./benchmark/c880.bench | 100.000 | 50.42959809303284 | 22 | 22 | +| ./benchmark/c499.bench | 100.000 | 65.37915563583374 | 49 | 49 | +| ./benchmark/c1355.bench | 100.000 | 363.1095223426819 | 82 | 82 | +| ./benchmark/b17.bench | ERROR | 2000.0039329528809 | ERROR | ERROR | +| ./benchmark/c7552.bench | 25.531 | 2000.0044975280762 | 1 | 1 | +| ./benchmark/b20.bench | ERROR | 2000.0045347213745 | ERROR | ERROR | +| ./benchmark/b11.bench | 98.951 | 2000.0055797100067 | 47 | 47 | +| ./benchmark/c3540.bench | 93.543 | 2000.006273508072 | 63 | 63 | +| ./benchmark/c1908.bench | 95.893 | 2000.0061783790588 | 39 | 39 | +| ./benchmark/b22.bench | ERROR | 2000.0057337284088 | ERROR | ERROR | +| ./benchmark/c2670.bench | 82.328 | 2000.0055947303772 | 31 | 31 | +| ./benchmark/b21.bench | ERROR | 2000.0054640769958 | ERROR | ERROR | +| ./benchmark/c6288.bench | 92.116 | 2000.0076813697815 | 5 | 5 | +| ./benchmark/c5315.bench | 33.139 | 2000.0081040859222 | 2 | 2 | +| ./benchmark/b04.bench | 99.744 | 2000.0090584754944 | 45 | 45 | +| ./benchmark/b12.bench | 91.771 | 2000.0079457759857 | 81 | 81 | +| ./benchmark/b07.bench | 98.568 | 2000.00936460495 | 29 | 29 | +| ./benchmark/c432.bench | 99.235 | 2000.0103182792664 | 19 | 19 | +| ./benchmark/b13.bench | 98.602 | 2000.009345293045 | 32 | 32 | +--------------------------------------------------------------------------------------------------------------- \ No newline at end of file