fixture API

Luna-Flow/mare_mark/fixture はベンチマーク入力のライフサイクルを記述します。データセットに対してどう生成され、フィンガープリントを取られ、コピーされ、実装向けに準備され、使用後にリセットされるか、そしてその作業が計時されるかどうかです。ランナーがこれらの関数を呼び出します。ライフサイクルについては fixture の設計で説明しています。

ソース: src/fixture/fixture.mbt。

import {
  "Luna-Flow/mare_mark/model",
  "Luna-Flow/mare_mark/fixture",
}

フィクスチャ

Fixture

Fixture は 1 種類の入力のライフサイクルです。

pub struct Fixture[Scale, Input, Prepared] {
  id : String
  version : String
  materialize : (@model.GenerationContext[Scale]) -> Input
  fingerprint : (Input) -> String
  clone_input : (Input) -> Input
  prepare : (Input, String, SampleContext) -> Prepared
  reset : (Prepared, ResetContext) -> Unit
  setup_policy : @model.SetupPolicy
}
フィールド呼び出し時期目的
materializeデータセットごとに 1 回コンテキストから入力を生成します
fingerprintデータセットごとに 1 回、および最小化された入力に対してイベント中で入力を識別します
clone_input各 prepare の前実体化された入力を変更から守ります
prepareセットアップポリシーに従ってコピーを実装が実行対象とするものに変換します。実装 ID を受け取ります
reset準備された値が使われた後それを解放または復元します
setup_policyprepare を実行する頻度と、それを計時するかどうか

Fixture::new

Fixture::new はすべての構成要素からフィクスチャを構築します。

pub fn[Scale, Input, Prepared] Fixture::new(String, String, (@model.GenerationContext[Scale]) -> Input, (Input) -> String, (Input) -> Input, (Input, String, SampleContext) -> Prepared, (Prepared, ResetContext) -> Unit, @model.SetupPolicy) -> Self[Scale, Input, Prepared]

引数はフィールドの順序に従います。

test "a fixture with a workspace" {
  let resets = Ref(0)
  let fixture : @fixture.Fixture[Int, Array[Double], (Array[Double], Array[Double])] = @fixture.Fixture::new(
    "vector",
    "1",
    context => Array::make(context.dataset_key.scale, 1.0),
    xs => "len=" + xs.length().to_string(),
    xs => xs.copy(),
    (xs, _, _) => (xs, Array::make(xs.length(), 0.0)),
    (_, _) => resets.val += 1,
    @model.SetupPolicy::new(
      @model.SetupFrequency::PerBatch,
      @model.SetupTiming::ExcludedFromMeasurement,
      @model.WorkspaceScope::BatchWorkspace,
    ),
  )
  let context = @model.GenerationContext::new(1UL, "s", "axpy", @model.DatasetKey::new(3, 0), fixture.id, fixture.version)
  let input = @fixture.materialize(fixture, context)
  let (x, workspace) = @fixture.prepare(fixture, input, "axpy", @fixture.SampleContext::new(0, "axpy", 0))
  (fixture.reset)((x, workspace), @fixture.ResetContext::new(0, "axpy"))
  inspect(workspace.length(), content="3")
  inspect(resets.val, content="1")
}

Fixture::immutable

Fixture::immutable は決して変更されない入力のためのフィクスチャを構築します。

pub fn[Scale, Input] Fixture::immutable(String, String, (@model.GenerationContext[Scale]) -> Input, (Input) -> String) -> Self[Scale, Input, Input]

clone_input と prepare は引数をそのまま返し、reset は何もせず、セットアップポリシーは PerDataset、ExcludedFromMeasurement、DatasetWorkspace です。

test "an immutable fixture" {
  let fixture = @fixture.Fixture::immutable("numbers", "1", context => context.dataset_key.scale * 10, (n : Int) => n.to_string())
  inspect(fixture.setup_policy.frequency is PerDataset, content="true")
  let context = @model.GenerationContext::new(0UL, "s", "c", @model.DatasetKey::new(4, 0), "numbers", "1")
  inspect(@fixture.materialize(fixture, context), content="40")
}

materialize

materialize はフィクスチャの materialize 関数を呼び出します。

pub fn[Scale, Input, Prepared] materialize(Fixture[Scale, Input, Prepared], @model.GenerationContext[Scale]) -> Input

prepare

prepare はフィクスチャの prepare 関数を呼び出します。

pub fn[Scale, Input, Prepared] prepare(Fixture[Scale, Input, Prepared], Input, String, SampleContext) -> Prepared

clone_input は呼び出しません。ランナーが準備の前にクローンします。

コンテキスト

SampleContext

SampleContext は、どのサンプルとどの実装のために準備するのかを prepare に伝えます。

pub struct SampleContext {
  sample_id : Int
  implementation_id : String
  repetition_id : Int
}
pub fn SampleContext::new(Int, String, Int) -> Self

ランナーは sample_id と repetition_id に同じ値を渡します。負の ID は検証、ウォームアップ、キャリブレーション、探索的バッチを表します(runner の設計を参照)。

ResetContext

ResetContext は、どのサンプルとどの実装をリセットするのかを reset に伝えます。

pub struct ResetContext {
  sample_id : Int
  implementation_id : String
}
pub fn ResetContext::new(Int, String) -> Self