incomp-flame-post/scratch/compare_termspecs.py

129 lines
5.1 KiB
Python

import os
import subprocess
import difflib
import re
termspecs = [
"termspec.20210708",
"termspec.banded_fsd-0.05-0.95-0.1",
"termspec.fsd-pos-neg",
"termspec.masked_fsd-0.1-0.9",
"termspec.pdf-sampling-ic1",
"termspec.pdf-sampling-ic1-ddxc",
"termspec.t1-8",
"termspec.vnsd_fluctuation"
]
workspace_dir = "/home/ignis/workspace/incomp-flame-post"
termspecs_dir = os.path.join(workspace_dir, "code/termspecs")
artifacts_dir = "/home/ignis/.gemini/antigravity-ide/brain/738c7ef6-4504-4268-bb13-023dffb2a2eb"
report_path = os.path.join(artifacts_dir, "sympy_comparison_report.md")
def run_cmd(args):
res = subprocess.run(args, capture_output=True, text=True, cwd=workspace_dir)
return res.stdout, res.stderr, res.returncode
def extract_loops_diff(base_code, opt_code):
"""
Diff the two source codes and extract the main loop calculation hunks.
"""
base_lines = base_code.splitlines(keepends=True)
opt_lines = opt_code.splitlines(keepends=True)
diff = list(difflib.unified_diff(base_lines, opt_lines, fromfile='baseline', tofile='optimized', n=4))
# Filter hunks to keep the report clean and concise
hunks = []
current_hunk = []
in_hunk = False
for line in diff:
if line.startswith('@@'):
if current_hunk:
hunks.append("".join(current_hunk))
current_hunk = []
in_hunk = True
current_hunk.append(line)
elif in_hunk:
current_hunk.append(line)
if current_hunk:
hunks.append("".join(current_hunk))
# Standardize or filter non-essential changes (like comments with date or file paths)
meaningful_hunks = []
for hunk in hunks:
lines = hunk.splitlines()
has_logic_change = False
for l in lines:
if (l.startswith('+') or l.startswith('-')) and not l.startswith('+++') and not l.startswith('---'):
# Ignore trivial comments or compilation timestamp lines if any
if "build date" in l or "build base" in l or "build_date" in l:
continue
has_logic_change = True
break
if has_logic_change:
meaningful_hunks.append(hunk)
return "\n".join(meaningful_hunks[:4]) # limit to first 4 meaningful hunks to keep it extremely readable
report_content = []
report_content.append("# SymPy 기호 최적화 도입 전후 생성 코드 정밀 비교 보고서\n")
report_content.append("본 보고서는 8가지 모든 termspec 설정에 대해 SymPy 대수 단순화 및 루프 단위 공통 하위식 제거(CSE) 최적화 도입 전(Baseline)과 도입 후(Optimized) 생성되는 포트란 코드를 대조 분석하여 정량적 최적화 메트릭 및 코드 수준의 차이점을 시각적으로 증명합니다.\n")
report_content.append("````carousel")
for idx, ts in enumerate(termspecs):
ts_path = os.path.join(termspecs_dir, ts)
print(f"Processing termspec: {ts}")
# Generate baseline
base_out, base_err, base_code = run_cmd([
"python3", "code/code_gen/code_gen_baseline.py", ts_path
])
# Generate optimized (profile report prints to stderr)
opt_out, opt_err, opt_code = run_cmd([
"python3", "code/code_gen/code_gen.py", ts_path
])
# Parse profile report from opt_err
reports = []
# Profile reports are bounded by [SymPy Optimizer Report: ...] and Estimated Speedup
matches = re.findall(r"(\[SymPy Optimizer Report: [a-zA-Z0-9_]+\]\n.*?\n=> Estimated Speedup in loop:.*?\n)", opt_err, re.DOTALL)
# Create diff
loop_diff = extract_loops_diff(base_out, opt_out)
report_content.append(f"## {idx+1}. {ts}\n")
report_content.append("### 📊 SymPy 정적 분석 최적화 메트릭 요약\n")
if matches:
report_content.append("```text")
for r in matches[:5]: # show up to 5 field reports for conciseness
report_content.append(r.strip())
if len(matches) > 5:
report_content.append(f"... (외 {len(matches)-5}개 필드는 생략됨)")
report_content.append("```\n")
else:
report_content.append("> [!NOTE]\n> 본 termspec은 단순 변수나 primary field 위주로 구성되어 별도의 복잡한 기호 최적화 타겟이 발견되지 않았습니다.\n")
report_content.append("### 💻 생성 코드 차이점 상세 (Diff)\n")
if loop_diff:
report_content.append("```diff")
report_content.append(loop_diff)
report_content.append("```\n")
else:
report_content.append("> [!TIP]\n> 생성된 포트란 코드 로직이 완전히 완벽하게 동일하여 물리 수치 및 연산량이 기존과 100% 일치합니다. (최적화 오버헤드 0%)\n")
if idx < len(termspecs) - 1:
report_content.append("<!-- slide -->")
report_content.append("````\n")
# Write report
os.makedirs(os.path.dirname(report_path), exist_ok=True)
with open(report_path, "w", encoding="utf-8") as f:
f.write("\n".join(report_content))
print(f"SymPy termspec comparison report built at: {report_path}")