frontend/testfloat_expr API
frontend/testfloat_expr は Berkeley TestFloat のテストベクタを構文解析し、binary16、binary32、binary64、binary128 の交換形式で bin_float に対して実行します。TestFloatSpec はベクタファイルを生成した関数、丸めモード、極小性の規則、厳密性を記述します。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 は 1 回の 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)は、roundToInt と整数変換について TestFloat の -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) は 1 つの関数のベクタを構文解析します。
pub fn parse_testfloat(String, String, TestFloatSpec) -> Result[TestFloatDocument, Array[ParseDiagnostic]]
各行は前後の空白が除去され、空行と # で始まる行はスキップされます。ベクタは空白区切りの 個のフィールドからなります。ここで は演算のオペランド数で、内訳は 個のオペランドのエンコーディング、期待結果、および 2 桁の 16 進フラグマスクです。オペランドのエンコーディングは spec.format() の 16 進ビットパターンです。期待結果は、算術演算ではエンコーディング、変換では最大 16 桁の 16 進整数、比較では 0 または 1 です。フィールド数が誤っていると "unexpected TestFloat field count"、読み取れないフィールドがあると "invalid TestFloat hexadecimal field" になります。結果が Ok になるのは無効な行が 1 つもない場合だけです。
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 は 1 つのベクタです。
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 は 1 つの無効な行です。
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 で実際の結果が quiet NaN であること。かつ、演算のフラグとエンコーディングのフラグを合わせた SoftFloat マスクが期待マスクと等しいこと。
- 整数変換: 期待マスクに invalid ビット
10が立っている場合、変換は invalid(None)を報告しなければならず、値フィールドは無視されます。そうでなければ、変換は期待される整数を返さなければなりません(符号付きの結果は 2 の補数のビットパターンとして比較)。いずれの場合もフラグマスクが等しくなければなりません。 - 比較: 真偽値とフラグマスクが等しいこと。
選択されたベクタはすべて実行対象であり、スキップされるベクタはありません。
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
デフォルト:シャード 1 つ、インデックス 0。RunOptions::new は shard_count > 0 かつ 0 <= shard_index < shard_count でなければ異常終了します。
結果
CaseResult
CaseResult は 1 つのベクタの結果です。
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"(マスクは 10 進表記)。
RunSummary
RunSummary は 1 回の実行を集計します。
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 はどれも失敗しなかったとき真です。
トレイト実装
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