frontend/testfloat_expr API
frontend/testfloat_expr 解析 Berkeley TestFloat 测试向量,并在 binary16、binary32、binary64 和 binary128 交换格式下针对 bin_float 执行它们。TestFloatSpec 描述生成向量文件时所用的函数、舍入模式、微小性(tininess)规则和精确性;parse_testfloat 读取向量,execute_document 运行它们。该包不进行任何 IO;运行器是 cli/testfloat_expr_cli。教程展示工作流程,设计页面规定通过规则。
在 moon.pkg 中导入该包:
import {
"Luna-Flow/floating/frontend/testfloat_expr",
}
函数规格
TestFloatOperation
TestFloatOperation 列出执行器支持的 TestFloat 函数。
pub(all) enum TestFloatOperation {
Add
Subtract
Multiply
Divide
SquareRoot
MulAdd
Remainder
RoundToInt
ToInt32
ToInt64
ToUInt32
ToUInt64
Equal
LessEqual
Less
EqualSignaling
LessEqualQuiet
LessQuiet
} derive(Eq, @debug.Debug)
| 构造子 | TestFloat 名称 | 操作数 | bin_float 方法 |
|---|---|---|---|
Add, Subtract, Multiply, Divide | add, sub, mul, div | 2 | add_ctx, sub_ctx, mul_ctx, div_ctx |
SquareRoot | sqrt | 1 | sqrt_ctx |
MulAdd | mulAdd | 3 | fma_ctx |
Remainder | rem | 2 | remainder_ctx |
RoundToInt | roundToInt | 1 | 精确时为 to_integral_exact_ctx,否则为 to_integral_value_ctx |
ToInt32, ToInt64, ToUInt32, ToUInt64 | to_i32, to_i64, to_ui32, to_ui64 | 1 | 带 exact~ 的 to_int_ctx、to_int64_ctx、to_uint_ctx、to_uint64_ctx |
Equal, LessEqual, Less | eq, le, lt | 2 | equal_quiet, less_equal_signaling, less_signaling |
EqualSignaling, LessEqualQuiet, LessQuiet | eq_signaling, le_quiet, lt_quiet | 2 | equal_signaling, less_equal_quiet, less_quiet |
TestFloatSpec
TestFloatSpec 是一次 TestFloat 运行的配置。
pub struct TestFloatSpec {
// private fields
} derive(Eq, @debug.Debug)
TestFloatSpec::parse
TestFloatSpec::parse(function_name, rounding, tininess?, exact?) 根据 TestFloat 名称构建一个规格。
pub fn TestFloatSpec::parse(String, String, tininess? : String, exact? : Bool) -> Result[Self, String]
function_name 的形式为 FORMAT_OPERATION:第一个 _ 之前的部分是格式(f16、f32、f64、f128),其余部分是运算(add、mulAdd、to_ui64、le_quiet、…)。名称在去除 -、_ 和空格后按不区分大小写的方式匹配。rounding 为 rnear_even、rnear_maxMag、rminMag、rmin、rmax 之一(也接受去掉开头 r 的形式,或 IEEE 名称 roundTiesToEven、roundTiesToAway、roundTowardZero、roundTowardNegative、roundTowardPositive)。tininess 为 "after"(默认)或 "before"(也接受 tininessAfter、tininessBefore)。exact(默认 false)选择 TestFloat 中 roundToInt 及整数转换的 -exact 变体。错误为 "unsupported TestFloat function name …"、"… format …"、"… operation …"、"… rounding mode …" 和 "… tininess mode …"。
///|
test "spec parse" {
let spec = @testfloat_expr.TestFloatSpec::parse(
"f128_mulAdd",
"rminMag",
tininess="before",
).unwrap()
inspect(spec.operation() == @testfloat_expr.MulAdd, content="true")
inspect(spec.format() == @bin_float.Binary128, content="true")
inspect(spec.rounding() == @bin_float.RoundTowardZero, content="true")
inspect(
@testfloat_expr.TestFloatSpec::parse("f64_mul", "rodd") is Err(_),
content="true",
)
}
TestFloatSpec::function_name, format, operation, rounding, tininess, exact
这些访问器返回解析后的配置。
pub fn TestFloatSpec::function_name(Self) -> String
pub fn TestFloatSpec::format(Self) -> @bin_float.BinaryInterchangeFormat
pub fn TestFloatSpec::operation(Self) -> TestFloatOperation
pub fn TestFloatSpec::rounding(Self) -> @bin_float.BinaryRoundingMode
pub fn TestFloatSpec::tininess(Self) -> @bin_float.TininessDetection
pub fn TestFloatSpec::exact(Self) -> Bool
function_name 是按原样给出的名称。
解析
parse_testfloat
parse_testfloat(source, text, spec) 解析一个函数的向量。
pub fn parse_testfloat(String, String, TestFloatSpec) -> Result[TestFloatDocument, Array[ParseDiagnostic]]
各行会被修剪;空行和以 # 开头的行被跳过。一个向量有 个以空白分隔的字段,其中 是该运算的操作数个数: 个操作数编码、期望结果,以及一个两位十六进制的标志掩码。操作数编码是 spec.format() 的十六进制位模式。对于算术运算,期望结果是一个编码;对于转换,是至多 16 位的十六进制整数;对于比较,是 0 或 1。字段数错误产生 "unexpected TestFloat field count",字段无法读取产生 "invalid TestFloat hexadecimal field"。只有当没有无效行时结果才为 Ok。
TestFloatDocument
TestFloatDocument 是一个已解析的向量文件。
pub struct TestFloatDocument {
// private fields
}
pub fn TestFloatDocument::source(Self) -> String
pub fn TestFloatDocument::spec(Self) -> TestFloatSpec
pub fn TestFloatDocument::cases(Self) -> Array[TestFloatCase]
pub fn TestFloatDocument::case_count(Self) -> Int
cases 返回按文件顺序排列的向量的副本。
TestFloatCase
TestFloatCase 是一个向量。
pub struct TestFloatCase {
// private fields
}
pub fn TestFloatCase::id(Self) -> String
pub fn TestFloatCase::line(Self) -> Int
id 为 FUNCTION:LINE,例如 f64_mulAdd:17。
ParseDiagnostic
ParseDiagnostic 是一个无效行。
pub struct ParseDiagnostic {
// private fields
} derive(Eq, @debug.Debug)
pub fn ParseDiagnostic::source(Self) -> String
pub fn ParseDiagnostic::line(Self) -> Int
pub fn ParseDiagnostic::message(Self) -> String
执行
execute_document
execute_document(document, options?) 执行被选中的向量。
pub fn execute_document(TestFloatDocument, options? : RunOptions) -> RunSummary
对于分片数 和索引 ,当 时执行第 个向量(按文件顺序从 0 开始计数)。操作数被解码为 BinFloat,运算在 spec.format().context(rounding~, tininess~) 中执行。向量在以下情况下通过:
- 算术运算:结果以相同的舍入和微小性规则重新编码到该格式后,其位模式与期望值完全一致,或者期望结果是任意 NaN 而实际结果是静默 NaN;并且运算标志与编码标志合并后的 SoftFloat 掩码等于期望掩码;
- 整数转换:若期望掩码含有无效位
10,则转换必须报告无效(None),其值字段被忽略;否则转换必须返回期望的整数(有符号结果按二进制补码位模式比较);两种情况下标志掩码都必须相等; - 比较:布尔值与标志掩码都相等。
每个被选中的向量都是可执行的;不存在被跳过的向量。
RunOptions
RunOptions 选择一个分片。
pub struct RunOptions {
// private fields
}
pub fn RunOptions::new(shard_count? : Int, shard_index? : Int) -> Self
pub fn RunOptions::shard_count(Self) -> Int
pub fn RunOptions::shard_index(Self) -> Int
默认值:一个分片,索引 0。除非 shard_count > 0 且 0 <= shard_index < shard_count,否则 RunOptions::new 中止。
结果
CaseResult
CaseResult 是一个向量的结果。
pub struct CaseResult {
// private fields
}
pub fn CaseResult::id(Self) -> String
pub fn CaseResult::passed(Self) -> Bool
pub fn CaseResult::message(Self) -> String
消息:通过时为空;否则为 "value mismatch: expected HEX, actual HEX"、"integer mismatch: …"、"comparison mismatch: …" 或 "flags mismatch: expected M, actual M"(掩码以十进制表示)。
RunSummary
RunSummary 汇总一次运行。
pub struct RunSummary {
// private fields
}
pub fn RunSummary::total_cases(Self) -> Int
pub fn RunSummary::selected_cases(Self) -> Int
pub fn RunSummary::passed_cases(Self) -> Int
pub fn RunSummary::failed_cases(Self) -> Int
pub fn RunSummary::results(Self) -> Array[CaseResult]
pub fn RunSummary::success(Self) -> Bool
total_cases 是文档中的向量数,selected_cases = passed_cases + failed_cases 是本分片执行的向量数,当没有向量失败时 success 为真。
trait 实现
TestFloatOperation、TestFloatSpec 和 ParseDiagnostic 的相等性与 Debug
这些方法比较所有字段,并为 Debug 渲染值。新代码中请使用 ==、!= 和 debug_inspect。
pub fn TestFloatOperation::equal(Self, Self) -> Bool
pub fn TestFloatOperation::not_equal(Self, Self) -> Bool
pub fn TestFloatOperation::to_repr(Self) -> @debug.Repr
pub fn TestFloatSpec::equal(Self, Self) -> Bool
pub fn TestFloatSpec::not_equal(Self, Self) -> Bool
pub fn TestFloatSpec::to_repr(Self) -> @debug.Repr
pub fn ParseDiagnostic::equal(Self, Self) -> Bool
pub fn ParseDiagnostic::not_equal(Self, Self) -> Bool
pub fn ParseDiagnostic::to_repr(Self) -> @debug.Repr
完整公共接口
此快照是该包生成的 pkg.generated.mbti。当正文与接口不一致时,以接口为准。
// Generated using `moon info`, DON'T EDIT IT
package "Luna-Flow/floating/frontend/testfloat_expr"
import {
"Luna-Flow/floating/bin_float",
"moonbitlang/core/debug",
}
// Values
pub fn execute_document(TestFloatDocument, options? : RunOptions) -> RunSummary
pub fn parse_testfloat(String, String, TestFloatSpec) -> Result[TestFloatDocument, Array[ParseDiagnostic]]
// Errors
// Types and methods
pub struct CaseResult {
// private fields
}
pub fn CaseResult::id(Self) -> String
pub fn CaseResult::message(Self) -> String
pub fn CaseResult::passed(Self) -> Bool
pub struct ParseDiagnostic {
// private fields
} derive(Eq, @debug.Debug)
pub fn ParseDiagnostic::equal(Self, Self) -> Bool
pub fn ParseDiagnostic::line(Self) -> Int
pub fn ParseDiagnostic::message(Self) -> String
pub fn ParseDiagnostic::not_equal(Self, Self) -> Bool
pub fn ParseDiagnostic::source(Self) -> String
pub fn ParseDiagnostic::to_repr(Self) -> @debug.Repr
pub struct RunOptions {
// private fields
}
pub fn RunOptions::new(shard_count? : Int, shard_index? : Int) -> Self
pub fn RunOptions::shard_count(Self) -> Int
pub fn RunOptions::shard_index(Self) -> Int
pub struct RunSummary {
// private fields
}
pub fn RunSummary::failed_cases(Self) -> Int
pub fn RunSummary::passed_cases(Self) -> Int
pub fn RunSummary::results(Self) -> Array[CaseResult]
pub fn RunSummary::selected_cases(Self) -> Int
pub fn RunSummary::success(Self) -> Bool
pub fn RunSummary::total_cases(Self) -> Int
pub struct TestFloatCase {
// private fields
}
pub fn TestFloatCase::id(Self) -> String
pub fn TestFloatCase::line(Self) -> Int
pub struct TestFloatDocument {
// private fields
}
pub fn TestFloatDocument::case_count(Self) -> Int
pub fn TestFloatDocument::cases(Self) -> Array[TestFloatCase]
pub fn TestFloatDocument::source(Self) -> String
pub fn TestFloatDocument::spec(Self) -> TestFloatSpec
pub(all) enum TestFloatOperation {
Add
Subtract
Multiply
Divide
SquareRoot
MulAdd
Remainder
RoundToInt
ToInt32
ToInt64
ToUInt32
ToUInt64
Equal
LessEqual
Less
EqualSignaling
LessEqualQuiet
LessQuiet
} derive(Eq, @debug.Debug)
pub fn TestFloatOperation::equal(Self, Self) -> Bool
pub fn TestFloatOperation::not_equal(Self, Self) -> Bool
pub fn TestFloatOperation::to_repr(Self) -> @debug.Repr
pub struct TestFloatSpec {
// private fields
} derive(Eq, @debug.Debug)
pub fn TestFloatSpec::equal(Self, Self) -> Bool
pub fn TestFloatSpec::exact(Self) -> Bool
pub fn TestFloatSpec::format(Self) -> @bin_float.BinaryInterchangeFormat
pub fn TestFloatSpec::function_name(Self) -> String
pub fn TestFloatSpec::not_equal(Self, Self) -> Bool
pub fn TestFloatSpec::operation(Self) -> TestFloatOperation
pub fn TestFloatSpec::parse(String, String, tininess? : String, exact? : Bool) -> Result[Self, String]
pub fn TestFloatSpec::rounding(Self) -> @bin_float.BinaryRoundingMode
pub fn TestFloatSpec::tininess(Self) -> @bin_float.TininessDetection
pub fn TestFloatSpec::to_repr(Self) -> @debug.Repr
// Type aliases
// Traits