From 30eac7dc0e556324d1355216ddd6bddd2fd1c844 Mon Sep 17 00:00:00 2001 From: YuhangQ Date: Mon, 14 Aug 2023 06:40:21 +0000 Subject: [PATCH] =?UTF-8?q?v1.5:=20=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=9F=BA?= =?UTF-8?q?=E5=87=86=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- atpg | Bin 187480 -> 187480 bytes crun | 2 +- run_exp.py | 234 ------------------------------------------------ src/circuit.cpp | 6 +- src/ls.cpp | 5 +- 6 files changed, 12 insertions(+), 238 deletions(-) delete mode 100644 run_exp.py diff --git a/.gitignore b/.gitignore index 85f8c6f..1f25712 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ CTestTestfile.cmake _deps benchmark build -old \ No newline at end of file +old +experiment \ No newline at end of file diff --git a/atpg b/atpg index 9f80ede976ca82851d60e0c34847f32c778d094e..14619b53d6b5b9c48a1cca63dbdbb216800ca2d8 100755 GIT binary patch delta 22263 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]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 jwDli+JNvEwDr8&fj6eAHE^B-gKdprA3- %s 2>&1 " % ( timeout, command, output_file )) - else: res = os.system("%s > %s 2>&1 " % (command, output_file)) - T2 = time.time() - - exec_time = T2 - T1 - exit_status = ExitStatus.normal - - # if(res == 31744): - # exit_status = ExitStatus.timeout - # if(res != 0): - # exit_status = ExitStatus.runtime_error - - os.system("echo \"time: %.4f\" >> %s " % ( exec_time, output_file )) - - return (exit_status, exec_time) - -class AtalantaSolver: - name = "Atalanta" - def run(filename, output_file, timeout): - return run_shell_command("./Atalanta/atalanta -b 10000 %s" % filename, output_file, timeout) - - def analyse(output_file): - content = open(output_file, "r").read() - p1 = re.compile(r'Fault coverage\s*:\s*(\d+\.\d+)\s*%', re.S) - coverage = p1.findall(content)[0] - p2 = re.compile(r'Number of test patterns before compaction\s*:\s*(\d+)', re.S) - cube = p2.findall(content)[0] - p3 = re.compile(r'Number of test patterns after compaction\s*:\s*(\d+)', re.S) - pattern = p3.findall(content)[0] - return (coverage, cube, pattern) - -class ATPGLS: - name = "ATPG-LS" - def run(filename, output_file, timeout): - return run_shell_command("./crun %s" % filename, output_file, timeout) - - def analyse(output_file): - print("anal:" + output_file) - content = open(output_file, "r").read() - p1 = re.compile(r'coverage\s*:\s*(\d+\.\d+)\s*%', re.S) - - if len(p1.findall(content)) == 0: - return("ERROR", "ERROR", "ERROR") - - coverage = p1.findall(content)[-1] - p2 = re.compile(r'pattern\s*:\s*(\d+)', re.S) - cube = p2.findall(content)[-1] - p3 = re.compile(r'pattern\s*:\s*(\d+)', re.S) - pattern = p3.findall(content)[-1] - return (coverage, cube, pattern) - -class TGPro: - name = "TGPro" - def run(filename, output_file, timeout): - return run_shell_command("./tg-pro/bin/atpgSat %s" % filename, output_file, timeout) - - def analyse(output_file): - content = open(output_file, "r").read() - - total = re.compile(r'Total: (\d+)', re.S).findall(content)[1] - detectable = re.compile(r'Detectable: (\d+)', re.S).findall(content)[0] - undetectable = re.compile(r'Undetectable: (\d+)', re.S).findall(content)[0] - - print(detectable, undetectable, total) - - coverage = str((int(undetectable) + int(detectable)) / int(total) * 100) + "%" - cube = "-*-" - pattern = "-*-" - - return (coverage, cube, pattern) - -class OpenTPG: - name = "OpenTPG" - def run(filename, output_file, timeout): - (path, filename) = os.path.split(filename) - fault_file = os.path.join(res_dir,"%s_%s.txt" % (solver.name, filename)) - cube_file = os.path.join(res_dir,"%s_%s.txt" % (solver.name, filename)) - - return run_shell_command("./OpenTPG/opentpg/opentpg -n %s -f %s -c /dev/null -u %s" \ - % (filename, output_file), output_file, timeout) - - def analyse(output_file): - content = open(output_file, "r").read() - p1 = re.compile(r'coverage:\s*:\s*(\d+\.\d+)\s*%', re.S) - coverage = p1.findall(content)[-1] - p2 = re.compile(r'pattern:\s*:\s*(\d+)', re.S) - cube = p2.findall(content)[-1] - p3 = re.compile(r'pattern:\s*:\s*(\d+)', re.S) - pattern = p3.findall(content)[-1] - return (coverage, cube, pattern) - -class Table: - def __init__(self, header): - self.header = header - self.col_size = len(header) - self.lines = [] - def add_line(self, cols): - if len(cols) != self.col_size: - raise Exception("cols number error! need %d but you have %d." % (self.col_size, len(cols))) - for var in cols: var = str(var) - self.lines.append(cols) - - def print_table(self): - col_widths = [] - for var in self.header: - col_widths.append(len(var)) - - for i in range(self.col_size): - for j in range(len(self.lines)): - self.lines[j][i] = str(self.lines[j][i]) - - - for i in range(self.col_size): - for line in self.lines: - col_widths[i] = max(col_widths[i], len(line[i])) - - table_with = 1 - for width in col_widths: - table_with = table_with + width + 3 - - for i in range(table_with): print("-", end="") - print() - - def print_with_filler(str, width, filler): - print(str, end="") - for i in range(len(str), width): - print(filler, end="") - - print("| ", end="") - for i in range(self.col_size): - print_with_filler(self.header[i], col_widths[i], " ") - print(" | ", end="") - - print() - - print("| ", end="") - for i in range(self.col_size): - print_with_filler("", col_widths[i], "-") - print(" | ", end="") - - print() - - for line in self.lines: - print("| ", end="") - for i in range(self.col_size): - print_with_filler(line[i], col_widths[i], " ") - print(" | ", end="") - print() - - for i in range(table_with): print("-", end="") - print() - -class Logger: - def __init__(self, filename): - self.f = open(filename, "w") - def log(self, str): - print(str) - self.f.write(str + "\n") - self.f.flush() - -table = None - -def multiprocess_run_solver(solver, input_file): - (path, filename) = os.path.split(input_file) - out_file = os.path.join(res_dir,"%s_%s.txt" % (solver.name, filename)) - - (status, time) = solver.run(input_file, out_file, TIMEOUT) - # time = "-*-" - # status = ExitStatus.normal - - fault = "-*-" - cube = "-*-" - pattern = "-*-" - - if status == ExitStatus.runtime_error: - fault = "Runtime Error" - elif status == ExitStatus.timeout: - fault = "Time Out" - else: - (f, c, p) = solver.analyse(out_file) - fault = f - cube = c - pattern = p - - table.add_line([input_file, fault, time, cube, pattern]) - - return input_file - -if __name__ == '__main__': - logger = Logger("check.log") - - os.chdir(work_dir) - os.makedirs(res_dir, exist_ok=True) - all_task = [] - - solver = ATPGLS - - table = Table(["data", "fault coverage(%s)" % solver.name, "time(%s)" % solver.name, "cube(%s)" % solver.name, "pattern(%s)" % solver.name ]) - - for filename in os.listdir(data_dir): - if not filename.endswith(data_suffix): continue - all_task.append(pool.submit(multiprocess_run_solver, solver, os.path.join(data_dir, filename))) - - s = 0 - for task in as_completed(all_task): - data = task.result() - s = s + 1 - logger.log("[{}/{}] 任务 {}".format(s, len(all_task), data)) - - table.print_table() diff --git a/src/circuit.cpp b/src/circuit.cpp index 903448d..7731696 100644 --- a/src/circuit.cpp +++ b/src/circuit.cpp @@ -184,8 +184,12 @@ void Circuit::init_avg_dist() { } for(Gate* g : gates) { - // printf("gate: %s total: %d cnt: %d\n", g->name.c_str(), total_dist[g->id], total_cnt[g->id]); + printf("gate: %s total: %d cnt: %d\n", g->name.c_str(), total_dist[g->id], total_cnt[g->id]); + assert(total_cnt[g->id] > 0); + g->avg_dist = total_dist[g->id] / total_cnt[g->id]; + + // if(g->id) if(!g->isPO) assert(g->avg_dist > 0); } diff --git a/src/ls.cpp b/src/ls.cpp index 4ab421e..353a849 100644 --- a/src/ls.cpp +++ b/src/ls.cpp @@ -178,8 +178,11 @@ void LUTCircuit::ls_main() { if(num_fault > 0) { num_pattern++; } + + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); - printf("Cover: %.2f%% pattern: %d new_detected: %d undected: %d\n", (double)num_detected_fault / num_total_fault * 100, num_pattern, num_fault, num_undetected_fault); + printf("Cover: %.2f%% pattern: %d new_detected: %d undected: %d time: %.2fs\n", (double)num_detected_fault / num_total_fault * 100, num_pattern, num_fault, num_undetected_fault, (double)duration/1000); // break; }