Commit f1600373 authored by 李晓奇's avatar 李晓奇

move script back

parent 9d5c5e1f
#!/usr/bin/env python3
import subprocess
import os
import argparse
import re
import time
import glob
import json5
from pathlib import Path
# you can run the script from anywhere!
cminusfc_path = Path(__file__).absolute().parents[2] / "build/cminusfc"
cminusfc = str(cminusfc_path)
try:
from tqdm import tqdm
except Exception as _:
os.system("apt install -y python3-tqdm || python3 -m pip install tqdm")
from tqdm import tqdm
repeated_time = 3
def init_args():
parser = argparse.ArgumentParser()
parser.add_argument("--GlobalValueNumber", "-gvn", action="store_true")
parser.add_argument(
"--GlobalValueNumberAnalysis", "-gvn-analysis", action="store_true"
)
args = parser.parse_args()
return args
def get_raw_testcases(root_path):
file_names = glob.glob(root_path + "/*.cminus")
# pattern=r'[0-9]+'
# file_names.sort(key= lambda item:int(re.findall(pattern, os.path.basename(item))[0]))
return file_names
def get_baseline_files(root_path):
file_names = glob.glob(root_path + "/*.ll")
# pattern=r'[0-9]+'
# file_names.sort(key= lambda item:int(re.findall(pattern, os.path.basename(item))[0]))
return file_names
def compile_baseline_files(file_lists):
print("Compiling baseline files")
progess_bar = tqdm(total=len(file_lists), ncols=50)
exec_files = list()
for each in file_lists:
exec_file, _ = os.path.splitext(each)
COMMAND = "clang -O0 -w " + each + " -o " + exec_file + " -L. -lcminus_io"
try:
result = subprocess.run(
COMMAND,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
timeout=1,
)
if result.returncode == 0:
exec_files.append(exec_file)
else:
exec_files.append(None)
print(
f"\nCompile {each.split('/')[-1]} \033[31;1m failed\033[0m")
except Exception as _:
exec_files.append(None)
print(f"Compile {each.split('/')[-1]} \033[31;1m failed\033[0m")
progess_bar.update(1)
progess_bar.close()
return exec_files
def compile_testcases(file_lists, option):
COMMAND = cminusfc + " " + option + " "
exec_files = list()
print("Compiling ", option)
progess_bar = tqdm(total=len(file_lists), ncols=50)
for each in file_lists:
try:
result = subprocess.run(
COMMAND + each,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
timeout=1,
)
if result.returncode == 0:
exec_file, _ = os.path.splitext(each)
exec_files.append(exec_file)
else:
exec_files.append(None)
print(
f"\nCompile {each.split('/')[-1]} \033[31;1m failed\033[0m")
except Exception as _:
exec_files.append(None)
print(f"Compile {each.split('/')[-1]} \033[31;1m failed\033[0m")
progess_bar.update(1)
progess_bar.close()
return exec_files
def gvn_evaluate(file_lists, metric_func, check_mode=True):
result = list()
print("Evalution ")
progess_bar = tqdm(total=len(file_lists), ncols=50)
for each in file_lists:
if each == None:
result.append(None)
continue
if check_if_correct(each, check_mode):
base = 0
for _ in range(repeated_time):
re_value = metric_func(each)
if re_value != None:
base += re_value / repeated_time
else:
base = None
break
result.append(base)
else:
result.append(None)
subprocess.call(["rm", "-rf", each])
progess_bar.update(1)
progess_bar.close()
return result
def check_if_correct(exec_file, check_mode=True):
if check_mode:
input_option = None
if os.path.exists(exec_file + ".in"):
with open(exec_file + ".in", "rb") as fin:
input_option = fin.read()
try:
result = subprocess.run(
[exec_file],
input=input_option,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=10,
)
with open(exec_file + ".out", "rb") as fout:
answer = fout.read()
if result.stdout == answer:
return True
else:
print(
f"Execute {exec_file.split('/')[-1]} result is not correct! your output:{result.stdout}, but the answer is:{answer}"
)
return False
except Exception as e:
print(
f"Execute {exec_file.split('/')[-1]} \033[31;1m failed\033[0m")
return False
else:
return True
def get_execute_time(exec_file):
try:
cmdline = "taskset -c 0 " + exec_file + " < " + exec_file + ".in" + " 2>&1"
input_option = None
start = time.time()
result = subprocess.run(
[cmdline],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
timeout=10,
)
elapsed = time.time() - start
return elapsed
except Exception as e:
print(f"Execute {exec_file.split('/')[-1]} \033[31;1m failed\033[0m")
return None
def table_print(testcase, before_optimization, after_optimization, baseline):
if len(before_optimization) == len(baseline) and len(before_optimization) == len(
after_optimization
):
pass
else:
max_len = max(
[len(before_optimization), len(after_optimization), len(baseline)]
)
if len(before_optimization) < max_len:
before_optimization += [None] * \
(max_len - len(before_optimization))
if len(after_optimization) < max_len:
after_optimization += [None] * (max_len - len(after_optimization))
if len(baseline) < max_len:
baseline += [None] * (max_len - len(baseline))
print(
"\033[33;1mtestcase",
"\t",
"\033[31;1mbefore optimization\033[0m",
"\t",
"\033[32;1mafter optimization\033[0m",
"\t",
"\033[35;1mbaseline\033[0m",
)
for index, (result1, result2, result3) in enumerate(
zip(before_optimization, after_optimization, baseline)
):
print(
testcase[index].split("/")[-1],
"\t\t%.2f" % result1 if result1 != None else "\t\tNone",
"\t\t\t%.2f" % result2 if result2 != None else "\t\t\tNone",
"\t\t %.2f" % result3 if result3 != None else "\t\t None",
)
def calculate_gvn_bb_score(input_partition, answer_partition):
# score of every bb is either 0 or 1
if len(input_partition) != len(answer_partition):
return 0
score_cnt = 0
for in_cc in input_partition:
for ans_cc in answer_partition:
if set(in_cc) == set(ans_cc):
score_cnt += 1
break
if score_cnt == len(answer_partition):
return 1
return 0
def calculate_gvn_score(input_functions, answer_functions):
# input & answer is dict from json
# calculate score use sum(score of every bb)/total_bb
# score of every bb is either 1 or 0
# total_bb is count of pout
total_bb = 0
for ans_func in answer_functions:
total_bb += len(ans_func["pout"])
cal_score = 0
for ans_func in answer_functions:
for in_func in input_functions:
if ans_func["function"] == in_func["function"]:
for ans_bb, ans_partition in ans_func["pout"].items():
for in_bb, in_partition in in_func["pout"].items():
if ans_bb == in_bb:
cal_score += calculate_gvn_bb_score(
in_partition, ans_partition
)
else:
continue
else:
continue
return cal_score / total_bb
if __name__ == "__main__":
script_path = os.path.join(os.getcwd(), __file__)
usr_args = init_args()
if usr_args.GlobalValueNumber:
print("=" * 10, "GlobalValueNumber", "=" * 10)
root_path = os.path.join(
os.path.dirname(script_path), "testcases/GVN/performance"
)
testcases = get_raw_testcases(root_path=root_path)
exec_files1 = compile_testcases(
file_lists=testcases, option="-mem2reg")
results1 = gvn_evaluate(file_lists=exec_files1,
metric_func=get_execute_time)
exec_files2 = compile_testcases(
file_lists=testcases, option="-mem2reg -gvn")
results2 = gvn_evaluate(file_lists=exec_files2,
metric_func=get_execute_time)
baseline_files = get_baseline_files(
os.path.join(root_path, "baseline"))
exec_files3 = compile_baseline_files(baseline_files)
results3 = gvn_evaluate(
file_lists=exec_files3, metric_func=get_execute_time, check_mode=False
)
table_print(
testcase=testcases,
before_optimization=results1,
after_optimization=results2,
baseline=results3,
)
if usr_args.GlobalValueNumberAnalysis:
print("=" * 10, "GlobalValueNumberAnalysis", "=" * 10)
root_path = os.path.join(
os.path.dirname(script_path), "testcases/GVN/functional"
)
testcases = get_raw_testcases(root_path=root_path)
option = "-mem2reg -emit-llvm -gvn -dump-json"
COMMAND = cminusfc + " " + option + " "
print("Compiling ", option)
progess_bar = tqdm(total=len(testcases), ncols=50)
score_list = []
i = 0
for each in testcases:
i += 1
try:
result = subprocess.run(
COMMAND + each,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
timeout=1,
)
if result.returncode == 0:
exec_file, _ = os.path.splitext(each)
each_base = each.split("/")[-1]
print(f"\nCompile {each_base} \033[32;1m success\033[0m")
with open("gvn.json", "r") as load_input:
with open(exec_file + ".json", "r") as load_answer:
print(
f"generate json {each_base} \033[32;1m success\033[0m"
)
# here, input is a list of dict
input_functions = json5.load(load_input)
answer_functions = json5.load(load_answer)
score = calculate_gvn_score(
input_functions, answer_functions
)
score_list.append((each_base, score))
subprocess.call(["rm", "-rf", exec_file + ".ll"])
else:
print(
f"\nnCompile {each.split('/')[-1]} \033[31;1m failed\033[0m")
except Exception as _:
print(
f"Analyze {each.split('/')[-1]} \033[31;1m failed\033[0m")
progess_bar.update(1)
progess_bar.close()
i = 0
for file, score in score_list:
i += 1
print(file + ":", score)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment