Skip to content

Add topic 06 benchmark test suite - #46

Open
2813183274-cloud wants to merge 6 commits into
ScratchV-Compiler:mainfrom
2813183274-cloud:topic06-test-clean
Open

2813183274-cloud wants to merge 6 commits into
ScratchV-Compiler:mainfrom
2813183274-cloud:topic06-test-clean

Conversation

@2813183274-cloud

@2813183274-cloud 2813183274-cloud commented Aug 8, 2026

Copy link
Copy Markdown

本次更新

  • 增加 DSLInterpreter 与真实 TinyFive 双后端验证
  • 为 23 个 DSL 用例生成独立 JSON/Markdown 报告
  • 增加指令数、代码大小、运行时间和 cost model 指标
  • 增加编译与模拟超时保护
  • 增加双后端失败原因分类
  • 更新性能基线、CI、使用说明和设计文档
  • 补充解释器与 TinyFive 未通过用例分析

当前结果

  • DSLInterpreter:17 PASS,6 UNSUPPORTED
  • TinyFive:12 PASS,3 TIMEOUT,8 UNSUPPORTED
  • 双后端可比较用例:9
  • 输出一致:9
  • 输出不一致:0

已知限制

  • 解释器暂不支持分支和循环控制流
  • 分支用例因编译器标签不一致导致 TinyFive 超时
  • 数组和矩阵用例尚未接通 TinyFive 输入内存 ABI

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 AI Code Review

共审查 10 个变更文件
⚠️ 另有 19 个文件超过上限(最多 10 个)未审查

📁 .github/workflows/topic06-benchmark.yml

🔴 Bug: Missing path filteron: push / pull_request has no paths filter. This benchmark workflow runs on every commit/PR in the repo, wasting CI minutes on unrelated changes.
Suggestion: Add paths: [ '**topic06**', '**Topic06**', 'benchmark_reports/**', 'scripts/run_topic06_benchmarks.py', '.github/workflows/topic06-benchmark.yml' ] or equivalent.

🔴 Bug: Cascading failure hides results — The "Run supported correctness gates" step runs three sequential commands; if the first (activation) fails, the elementwise and loop categories are never executed, and the diagnostic report step is also skipped. A single flaky category blocks all diagnostics.
Suggestion: Use continue-on-error: true on the correctness gates step, or run each category as a separate job, so you get the full diagnostic picture even when a category fails.

🟡 Magic number: --benchmark 3 — Line 36: the meaning of 3 is opaque. Future readers will have to trace into the script to understand what it controls.
Suggestion: Add a comment (e.g., # 3 = full sweep including edge cases) or replace with a named flag.

🟡 Missing pip cache — No actions/cache or built-in pip cache (cache: 'pip' on setup-python). Benchmark dependency installs will re-download wheels on every run.
Suggestion: Add cache: 'pip' to the setup-python step, or add a cache step for ~/.cache/pip.

🟡 Missing concurrency — Rapid successive pushes will spawn parallel benchmark runs, doubling CI load and potentially producing conflicting reports.
Suggestion: Add concurrency: group: topic06-benchmark-${{ github.ref }}, cancel-in-progress: true.

🟡 Upload may reference non-existent directoriesbenchmark_reports/topic06/cases/ and benchmark_reports/topic06/failures/ may not exist if no failures are generated. upload-artifact@v4 can emit warnings or produce empty archives.
Suggestion: Ensure the script creates these directories (even if empty) before the upload step, or remove the paths that aren't guaranteed.

💭 Nit: --fail-on-test-failure semantics unclear — The flag name suggests it fails the job on test failure, but since you want diagnostics regardless, consider whether this flag is what you actually want or if --strict would be clearer.

💭 Nit: Python version pinning"3.11" is pinned but not documented with a reason. A brief comment explaining why 3.11 is required (vs 3.10 or 3.12) helps future maintainers.


📁 Makefile

🟡 **Magic number: `--benchmark 3`** — `bench-topic06` hardcodes this value with no explanation of what "3" means or why it's sufficient to cover both "DSL correctness + TinyFive" as the comment claims.
Suggestion: Add a brief comment explaining what benchmark 3 is, or accept it as a variable (e.g. `BENCHMARK ?= 3`).

🟡 **No dependency on prerequisites** — `bench-topic06` has no prerequisite to ensure `scripts/run_topic06_benchmarks.py` exists or that required packages are installed. If the script is missing, the failure message (`python3: can't open file ...`) is less clear than a Makefile-level check.
Suggestion: Consider a lightweight guard (e.g. `@test -f scripts/run_topic06_benchmarks.py || (echo "Missing: ..." && exit 1)`), or document that the user must run `make install` first.

💭 **No output directory creation** — Unlike `bench:` which writes to `benchmark_reports/`, there's no indication where topic06 benchmarks land. If the script creates files, the target doesn't ensure the directory exists.
Suggestion: If the script writes reports, add an `@mkdir -p <dir>` prerequisite or let the script handle it and document that.

💭 **Hardcoded `python3`** — Other targets in the file may use a different interpreter (virtualenv, conda, etc.). Consistency check: does the rest of the Makefile assume `python3` or a specific environment?
Suggestion: If the project uses a virtualenv, consider `$(PYTHON)` with a default `PYTHON ?= python3`.

📁 README.md

🔴 Data accuracy: test count dropped — Line 65: tests/ originally stated "348 个单元测试". The new text "单元测试及课题 06 的 23 个 DSL 用例" drops the 348 count entirely. If those 348 unit tests still exist, the number was lost. Either preserve it (348 个单元测试 + 23 个 DSL 用例) or add a note explaining the count changed.

🔴 DSL case count ambiguity — Line 64: The original had "23 个 DSL 基准用例" under benchmarks/. The new text moves "23 个 DSL 用例" to tests/ while benchmarks/ now says "通用基准与课题 06 性能基线". Are the 23 cases physically moved, or do both dirs still reference them? If moved, the benchmarks description is vague. If duplicated, both descriptions should clarify the relationship.

🟡 README coupled to a single topic — Lines 64-66 now name-drop "课题 06" in three consecutive directory descriptions. If Topic 06 is rotated out or renamed, the main README breaks. Consider keeping directory descriptions generic and putting Topic-06 specifics in the linked doc (06-性能测试套件使用说明.md) only.

🟡 Link path may not exist — Line 108: [课题 06 测试套件](docs/topics/06-性能测试套件使用说明.md) — verify this file is actually added in the same PR. If it's a dangling link, the nav table is broken on merge.


📁 benchmark_reports/topic06/cases/activation-add_relu_relu.json

🔴 Hardcoded absolute Windows pathscompile_command leaks D:\anaconda3\python.exe and D:\PycharmProjects\ScratchV\.... These are non-portable and expose dev-machine paths in a committed artifact. Other developers or CI on Linux/macOS cannot reproduce the command.
Suggestion: Store relative or environment-templated commands (e.g., ${PYTHON} + repo-relative paths), or strip the command to a canonicalized form before committing.

🟡 Missing trailing newline — Diff explicitly flags \ No newline at end of file. Violates POSIX convention and causes noisy diffs on future edits.
Suggestion: Add \n at EOF (most linters catch this — ensure your JSON formatter does too).

🟡 Inconsistent numeric types between perf_counters and cost_modelperf_counters uses integers ("add": 4), cost_model uses floats ("dynamic_add": 4.0). Same values, two types. If this is generated from different code paths, downstream consumers doing === comparison will silently fail.
Suggestion: Unify to one type across both objects.

🟡 output_dtype: null contradicts expected_type: "scalar" — The field explicitly says scalar, so dtype should be determinable (e.g., int32, float64). null makes the field useless for schema validation or cross-case analysis.
Suggestion: Populate output_dtype from the DSL type inference; if genuinely unknown, add a reason field.

🟡 ci95_instr_count: 0.0 with benchmark_runs: 3 — Zero variance is plausible for a deterministic scalar benchmark, but 3 runs is the minimum to compute any meaningful CI. If this is expected, document it; otherwise consider bumping the run count for non-deterministic cases.

💭 total_time_sec (0.829) doesn't decompose into visible sub-componentscompile_time_sec (0.085) + simulation_time_sec (0.147) + interpreter_time_sec (0.129) ≈ 0.361, leaving ~0.47s unaccounted (presumably the 3 benchmark runs). Adding a benchmark_time_sec field would make the report self-documenting.


📁 benchmark_reports/topic06/cases/activation-add_relu_relu.md

🟡 绝对路径泄漏 — 编译命令中包含 D:\anaconda3\python.exeD:\PycharmProjects\ScratchV\... 等机器特定路径。提交到仓库会泄漏环境信息且不可复现。
建议:使用相对路径(python -m scratchv.main)或占位符(<PYTHON>)。

🟡 数据三重冗余 — 同一组性能指标以三种形式重复出现:

  1. 子弹列表(静态汇编指令数: 5 等)
  2. Cost model 指标 字典
  3. Cost model 对比 字典

建议:保留一个规范来源(字典形式便于程序化解析),其余引用而非重复。

🟡 疑似遗漏优化未记录--optimize all 下生成 max t3, t2, 0 + max t4, t3, 0,而 max(max(x,0),0) ≡ max(x,0),理论上可折叠为一条指令。报告未标注此情况。
建议:加一条注释说明是编译器当前未实现该折叠,还是有意保留语义显式性。否则读者会误以为优化已生效。

💭 Cost model 对比 中所有 delta 均为 0——对 PASS 且无变化的 case,可省略此段或仅保留一行摘要 Cost model: 无变化,减少噪音。

💭 表格中 null 建议统一为空字符串或 null 是 JSON/编程术语,在 Markdown 阅读体验不佳。


📁 benchmark_reports/topic06/cases/activation-relu_add.json

Review: activation-relu_add.json (New File)

🔴 Missing newline at EOF — Final line lacks trailing newline. POSIX convention and most tools expect one; will cause spurious diffs on every subsequent edit.
Suggestion: Ensure the file ends with \n.

🟡 Hardcoded Windows paths in compile_command — Backslash paths (D:\\anaconda3\\...) make this file non-portable and unparseable on Linux/macOS CI. If this file is checked in, any path change invalidates it.
Suggestion: Store paths relative to project root, or omit the absolute command from the report artifact.

🟡 cost_model_comparison is extremely redundant — 9 metrics × 5 fields (current/baseline/delta/delta_pct/regressed) when all values are identical. This is 100+ lines of JSON that add no information.
Suggestion: If all deltas are zero, store just "cost_model_regressed": false (which already exists) and skip the per-metric breakdown, or emit the comparison only when regressions are detected.

🟡 perf_counters.add = 3 for a single add + ReLU — For a + bias followed by ReLU, you'd expect 1 add + 1 branch (or a single fused compare-and-select). 3 adds suggests the compiler is expanding ReLU into an add sequence, which may indicate a missed optimization.
Suggestion: Verify the assembler output at build/topic06/relu_add.s — if ReLU compiles to multiple adds instead of a branch/move, that's a compiler optimization gap, not a report bug.

💭 expected_type: "scalar" but expected: 3 (int, no decimal) — The interpreter produced 3.0 (float). The schema treats the expected value as an integer but actual as float. Minor type mismatch risk if consumed programmatically.
Suggestion: Ensure expected matches the type implied by expected_type, or document that the comparison is type-coerced.

💭 output_dtype: null, output_shape: null — For a scalar output, these are arguably unnecessary. If the schema allows null for scalars, fine; otherwise consider "output_dtype": "float32" and "output_shape": [].


📁 benchmark_reports/topic06/cases/activation-relu_add.md

🔴 Bug: 汇编与描述不一致 — "Add input and bias" 暗示 input + 常量 bias,但汇编为 add t2, t0, t1(两个寄存器相加)。要么描述有误,要么 DSL 在别处把 bias 加载进了 t1 但未记录。

🟡 Suggestion: 硬编码绝对路径 — 编译命令包含 D:\anaconda3\...D:\PycharmProjects\...。应使用相对路径或环境变量,否则报告不可移植且泄露本地目录结构。

🟡 Suggestion: Cost model 对比无诊断价值 — 所有指标的 current == baselinedelta 全为 0。说明要么 baseline 就是当前值(自我比较),要么 baseline 生成逻辑有问题。建议明确标注 baseline 来源,或当无外部基准时省略该表。

💭 Nit: TinyFive 分类计数 全零 load/store — 输入数据来源未说明,建议在 ABI 说明中补充数据如何进入寄存器的。


📁 benchmark_reports/topic06/cases/activation-relu_only.md

🔴 Hardcoded absolute paths — Line 44: 编译命令含 Windows 绝对路径 (D:\anaconda3\..., D:\PycharmProjects\...),报告不可移植。CI 或其他开发者无法复现。
Suggestion: 用相对路径或环境变量替代,或至少在文档中注明这是单机快照。

🟡 Output format inconsistency — Lines 15-16: DSLInterpreter 输出 0.0(float), TinyFive 输出 0(int)。虽然 "与期望匹配" 都是 True,但类型表示不一致,后续 diff-based 回归检测可能误判。
Suggestion: 统一输出格式,或在验证逻辑中显式做类型归一化。

🟡 Cost model 数据冗余 — Lines 38-40 与前文 line 25-36 的指标完全重复,且 line 40 是 line 36 的复述。文件可读性下降,维护时需同步更新多处。
Suggestion: 移除重复的 Cost model 字段,或改为引用上方指标。

🟡 总耗时不可解释 — Line 33: 总耗时 0.812s,但三项分耗时之和仅 0.364s (0.086+0.123+0.155),剩余 0.448s 无来源说明。
Suggestion: 记录额外的耗时来源(如报告生成、文件 I/O),或标注总耗时的计算范围。

💭 ABI 说明为 null — Line 21: "TinyFive 输入 ABI 可用: True" 但说明为 null,信息量不足。可补充 ABI 格式简述,或将不可用时直接省略该行。

💭 Assembly code fence 缺少关闭后的空行 — 文件以 ``` 结尾 (line 63),建议末尾加一个空行,避免某些 markdown 渲染器将后续内容吞入代码块。


📁 benchmark_reports/topic06/cases/activation-relu_twice.json

🟡 Machine-specific paths — Lines containing compile_command: embeds Windows absolute paths (D:\anaconda3\python.exe, D:\PycharmProjects\...). These break reproducibility on other environments/CI runners. Consider replacing with relative paths or a canonical placeholder.

🟡 Baseline is self-referential — Every cost_model_comparison entry has delta: 0 and delta_pct: 0.0 because baseline equals current exactly. This means the regression detector can never fire. Ensure baseline values come from a prior run, not the current run's own metrics.

🟡 Type inconsistencyexpected: 4 (int) vs actual: 4 (int) vs interpreter_actual: 4.0 (float). The comparison logic must handle this. Consider normalizing all numeric results to the same type to avoid subtle float/int comparison bugs downstream.

💭 Missing newline at EOF — Last line lacks trailing newline. Harmless but triggers warnings from git diff, git commit, and some linters.

💭 output_dtype: null / output_shape: null — For a scalar expected type these are plausibly null, but consider documenting the convention explicitly so it's not mistaken for incomplete metadata.

💭 Over-precision on timingscompile_time_sec: 0.08641380001790822 carries float noise beyond meaningful precision. Consider rounding to ~6 decimals for readability and to avoid spurious diffs.


📁 benchmark_reports/topic06/cases/activation-relu_twice.md

🟡 冗余信息 — 性能指标区同时列出了独立字段和完整的 Cost model 指标 字典,内容完全重复,增加阅读负担。建议只保留表格或字典其中一种呈现方式。

🟡 Windows 绝对路径 — 编译命令中的 D:\anaconda3\...D:\PycharmProjects\... 是本地开发路径,不适合提交到版本库。建议生成报告时替换为相对路径或占位符(如 <VENV><PROJECT_ROOT>)。

🟡 验证模式 both 缺少定义 — 读者无法知道 both 的具体含义。建议补充一行说明,例如 验证模式: both (Interpreter + TinyFive 交叉验证)

💭 是否退化: False 重复三次 — "动态指令变化率"、顶层"是否退化"、以及 "Cost model 是否退化" 三处表达同一结论,合并为一个字段即可。

💭 max 幂等优化值得注释 — 汇编中 max(max(t0,0),0) 被正确折叠为单次 max,这是正确的编译器行为。建议在报告或 DSL 注释中注明这个优化,方便后续理解指令数为 4 而非 6 的原因。



⚠️ 未审查的文件

  • benchmark_reports/topic06/cases/branch-if_else.json
  • benchmark_reports/topic06/cases/branch-if_else.md
  • benchmark_reports/topic06/cases/branch-if_relu.json
  • benchmark_reports/topic06/cases/branch-if_relu.md
  • benchmark_reports/topic06/cases/branch-if_then.json
  • benchmark_reports/topic06/cases/branch-if_then.md
  • benchmark_reports/topic06/cases/elementwise-add_chain.json
  • benchmark_reports/topic06/cases/elementwise-add_chain.md
  • benchmark_reports/topic06/cases/elementwise-add_chain_3.json
  • benchmark_reports/topic06/cases/elementwise-add_chain_3.md
  • benchmark_reports/topic06/cases/elementwise-add_fan_in_4.json
  • benchmark_reports/topic06/cases/elementwise-add_fan_in_4.md
  • benchmark_reports/topic06/cases/elementwise-add_reuse.json
  • benchmark_reports/topic06/cases/elementwise-add_reuse.md
  • benchmark_reports/topic06/cases/elementwise-vector_add.json
  • benchmark_reports/topic06/cases/elementwise-vector_add.md
  • benchmark_reports/topic06/cases/loop-loop_add_4.json
  • benchmark_reports/topic06/cases/loop-loop_add_4.md
  • benchmark_reports/topic06/cases/loop-loop_add_chain_4.json

Comment thread benchmarks/topic06/baseline.json Outdated
{
"add_relu_relu": {
"category": "activation",
"avg_instr_count": 7.0,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个baseline是怎么测出来的

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

基于当前基线得出的

@2813183274-cloud

Copy link
Copy Markdown
Author

topic06 pr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants