model 设计
设计目标
其他每个包都通过 model 交换数据。该包确定了一套词汇:带版本、对失败显式表达,并且足够完整,使结果可以追溯到其协议、输入和环境。除身份函数和访问器外,它不拥有任何行为,因此每一层都可以依赖它而不会形成循环。
数学背景
作为等价关系的环境兼容性
把环境快照写作 ,其中 为语义部分, 为性能部分, 为来源信息。environment_compatible 为
逐字段比较。这是投影 的核:。任何映射的核都是等价关系,因为相等是自反、对称且传递的。因此,一组运行的快照会划分为若干类,比较恰好在同一类内才有意义。传递性在实践中很重要:如果运行 A 可以与 B 比较,B 可以与 C 比较,那么 A 就可以与 C 比较,因此一次存储的基线可以服务于同一类中之后的任何运行。
带容差的关系(例如“CPU 频率相差在 5 % 以内”)不是传递的,无法把运行划分为类;这就是检查采用声明字符串完全相等的原因。
作为和类型的结果
一次操作要么产生一个值,要么以几种值得区别对待的方式之一失败。把结果建模为一个和类型,
使各种情形在类型、事件和报告中保持区分。value_option 是到前两个分量上的投影;其他每个分量都没有值,包含它的计时批次是无效的。
设计决策
带版本的标识符
问题。 旧 JSONL 的读取器不能悄无声息地误读新字段。选择。 三个版本枚举产生标识符 mmkp_1(协议词汇)、mmka_1(事件产物)和 mmks_1(Plot IR)。每个事件都携带 artifact_version;读取器拒绝未知版本。理由。 增量式的变化保持版本不变;破坏性变化则增加 V2 和一个生命周期条目,旧的读取器会明确失败,而不是去猜测。
三部分的环境快照
问题。 有些差异会使正确性失效(目标、标志、ABI),有些会使计时失效(CPU、GC、时钟、频率策略),还有些只是簿记信息(主机名、时间、修订版本)。选择。 SemanticEnvironment、PerformanceEnvironment 和 ProvenanceEnvironment,兼容性取决于前两者。理由。 在不同主机上、声明的硬件相同的两次运行仍然可以比较;标志不同的运行则不行。快照记录的是你声明的内容;mare_mark 不会探测机器。
显式的协议
问题。 “跑了基准测试”掩盖了预热、批次大小、顺序、样本数和决策阈值。选择。 RunProtocol 为所有这些命名,protocol_identity 把预热次数、验证性样本数和实际阈值折叠成一个短键。理由。 只有协议可复现,结果才可复现。该键有意保持简短,并不覆盖每个字段;请在将要比较的结果旁存储完整的协议。
失败种类,而非字符串
ExecutionOutcome 把工作进程崩溃(Aborted)与超时、解码问题、不受支持的输入和被接受的偏差区分开来,ValidationStatus 在判定器一侧与之对应。报告在能力矩阵中分别统计每一种,因此“不支持”永远不会被读成“错误”,超时也永远不会被读成一次慢的测量。
带构造函数的只读记录
记录是 pub struct:字段在任何地方都可读,值通过 new 构建。用户需要构建的枚举是 pub(all)。IntervalMode 和 CrossoverResult 通过函数构建,使其构造始终只有一条有文档记录的路径。
决策与部署类型
ScaleBoundary、Region、ParetoPoint、DeploymentPolicy 和 CrossoverResult 描述测得的偏好如何成为部署规则。它们位于 model 中,使 experiment、tune 和应用无需相互依赖即可对它们达成一致。
正确性与不变量
environment_compatible是一个等价关系(推导见上文)。- 对每个版本枚举,
X::identifier()都是implementation() + "_" + version(),且V1值都是Supported。 ExecutionOutcome::value_option(o)恰好对Value和RaisedFlags为Some;flags(o)只对RaisedFlags和Trapped非空。OperationResult::completed(v, c)等于输出为空且没有退出码的OperationResult::new(Value(v), Some(c))。- 构造函数不复制任何东西,也不验证任何东西:验证属于
runner.validate_protocol和BenchSpec::compile。
被否决的方案
- 探测环境。 读取 CPU 型号、调速器和 GC 设置需要针对各平台的代码和权限;声明的值则是显式且可测试的。
- 带容差的兼容性。 不具有传递性(见上文)。
- 自由格式的结果字符串。 会丢失失败种类之间的区分。
- 单个扁平的协议字符串。 不可读且未经验证。
边界
- 不验证值;没有 IO;没有序列化(JSON 位于
event、report和tune_gemm中)。 protocol_identity只覆盖三个字段。ExperimentDesign、ValidationCoverage、OutlierPolicy和WorkspaceScope是记录下来的意图;运行器不解释它们。ProtocolVersion、ArtifactVersion和SchemaVersion各只有一个版本;没有迁移代码。