架构
mare_mark 把实验的含义、它的副作用以及它的呈现彼此分开。这种分离使报告可以从其记录重新生成,失败可以从其产物重放,决策可以从原始观测重新计算。
层次
| 层 | 包 | 职责 |
|---|---|---|
| 词汇 | model | 版本、协议、环境、结果、事件、决策 |
| 输入 | generator, fixture | 种子、指纹、输入生命周期与准备计时 |
| 正确性 | experiment | 判定器、缩减、交叉点分析 |
| 测量 | runner | 唯一执行负载并读取时钟的循环 |
| 记录 | event, ir_sink | 接收器与只追加的 JSONL 记录 |
| 分析 | stats, tune, tune_gemm | 摘要、比较、调优策略、GEMM 领域 |
| 呈现 | ir_model, report | Plot IR 及其 JSON、SVG 和 HTML 渲染 |
| 适配器 | cli | 文件、标准流、进程执行、退出码 |
导入图(省略仅用于测试的导入)是无环的:
| 包 | 导入 |
|---|---|
model | 无 |
generator, fixture, experiment, event, ir_model, stats, tune_gemm | model(generator 还导入 moonbitlang/x/crypto) |
ir_sink | event |
runner | model, fixture, event, experiment, moonbitlang/async |
report | model, ir_model |
tune | runner |
cli | model, ir_model, report, moonbitlang/x, moonbitlang/async |
没有包导入 cli。stats 和 report 不依赖 runner,因此它们可以分析和渲染在别处产生的记录。
数据流
RunProtocol ──validate_protocol──▶ ValidatedProtocol ─┐
BenchSpec ────────compile────────▶ ValidatedBenchPlan ├─▶ runner.run ─▶ ObservationSink
seed, EnvironmentSnapshot, sink ───────────────────────┘ │ │
│ JSONL record
per dataset: materialize ─▶ fingerprint ─▶ validate ─▶ warmup │
─▶ calibrate ─▶ exploratory blocks ─▶ confirmatory blocks │
▼
stats (paired comparisons) report.document_from_jsonl ─▶ PlotDocument
tune (scores, selection) │
plot_json · plot_svg · html
run 之前的一切都是描述,在能够运行之前就会被验证。run 之后的一切都消费保存下来的事件。run 是唯一执行负载并读取时钟的地方;cli 是唯一接触文件和进程的地方。
包之间的边界
计时。 计时区域包含负载和输出折叠,仅当夹具的 SetupPolicy 包含准备工作时才包含准备工作。验证、预热、校准、事件发出、接收器的 finish、统计和渲染都在计时区域之外。确切的表格见 runner 设计。
失败。 操作的失败是一个值(ExecutionOutcome),验证的判定结果是一个值(ValidationStatus),失败的验证会发出一个带有最小化输入和重放命令的 ValidationFailure。超时或崩溃是基础设施方面的证据,绝不是一次慢的测量。
统计。 原始观测在记录中从不被过滤或聚合。stats 根据成对数组计算决策;OutlierPolicy 只应用于派生视图。
报告。 report 是一个纯投影。无效观测、被丢弃的批次以及验证失败的实现的系列都会从图表中排除,失败则显示在差分部分。
调优。 tune 和 tune_gemm 保存策略和领域数据。构建、验证和测量候选由应用借助 runner 完成,因此调优测量与其他任何基准测试携带相同的证据。
可复现性
结果由五项记录下来的输入决定:计划(用例 id、实现及其版本、夹具 id 和版本)、经过验证的协议、运行种子、环境快照,以及快照来源信息中的代码修订版本。输入由 generator 从种子派生,实现顺序由种子派生,自助法也带种子,因此除计时本身之外的一切在每个目标上都可逐位复现。当 environment_compatible 成立时,不同运行的计时可以相互比较。
目标
所有包都能在每个目标上构建。runner.run 和 execute_operation 是 async 的,需要 moonbitlang/async 运行时(native、JS、wasm)。子进程工作者、mare-mark replay 以及 stdin/stdout 报告仅限 native;非 native 的 cli 入口点支持文件到文件的报告。native 与 JS 的计时属于不同的总体;只能把它们作为分别标注的运行来比较。