Dsxir.Optimizer behaviour (dsxir v0.3.0)

Copy Markdown

Behaviour and dispatcher for program optimizers.

An optimizer compiles a Dsxir.Program.t() against a trainset under a Dsxir.Metric.t(), returning a new program plus an open stats map.

Implementations declare @behaviour Dsxir.Optimizer and implement compile/4. Callers invoke an optimizer through compile/5, which performs argument validation and delegates to the impl module.

The return contract is fixed across versions:

{:ok, Dsxir.Program.t(), stats :: map()} | {:error, Exception.t()}

stats is an open map. Each optimizer documents the keys it populates; consumers must tolerate unknown keys.

Summary

Functions

Return {:ok, mod} when mod implements the four optional checkpointing callbacks as a set; otherwise {:error, %Dsxir.Errors.Invalid.NotCheckpointable{}} listing the missing arities.

Dispatch to impl.compile/4 with validated arguments.

Types

result()

@type result() :: {:ok, Dsxir.Program.t(), stats()} | {:error, Exception.t()}

sampler_state()

@type sampler_state() :: term()

stats()

@type stats() :: map()

trial_idx()

@type trial_idx() :: non_neg_integer()

trial_result()

@type trial_result() :: %{
  trial_idx: trial_idx(),
  candidate_id: String.t() | nil,
  score: float() | nil,
  status: :ok | :error,
  stats: map() | nil,
  duration_ms: non_neg_integer(),
  error: Exception.t() | nil,
  error_class: atom() | nil,
  candidate_program: Dsxir.Program.t() | nil
}

Callbacks

compile(student, trainset, metric, opts)

@callback compile(
  student :: Dsxir.Program.t(),
  trainset :: [Dsxir.Example.t()],
  metric :: nil | Dsxir.Metric.t(),
  opts :: keyword()
) :: result()

deserialize_state(blob, version)

(optional)
@callback deserialize_state(blob :: binary(), version :: pos_integer()) ::
  {:ok, sampler_state()} | {:error, :version_mismatch | term()}

init_session(t, list, arg3, keyword)

(optional)
@callback init_session(
  Dsxir.Program.t(),
  [Dsxir.Example.t()],
  nil | Dsxir.Metric.t(),
  keyword()
) ::
  {:ok, sampler_state(), planned_trials :: pos_integer() | :unknown}
  | {:error, Exception.t()}

serialize_state(sampler_state)

(optional)
@callback serialize_state(sampler_state()) ::
  {:ok, blob :: binary(), version :: pos_integer()} | {:error, term()}

step(sampler_state, trial_idx, t, list, arg5, keyword)

(optional)
@callback step(
  sampler_state(),
  trial_idx(),
  Dsxir.Program.t(),
  [Dsxir.Example.t()],
  nil | Dsxir.Metric.t(),
  keyword()
) ::
  {:cont, sampler_state(), trial_result()}
  | {:halt, sampler_state(), reason :: term()}

Functions

checkpointable?(mod)

@spec checkpointable?(module()) ::
  {:ok, module()} | {:error, Dsxir.Errors.Invalid.NotCheckpointable.t()}

Return {:ok, mod} when mod implements the four optional checkpointing callbacks as a set; otherwise {:error, %Dsxir.Errors.Invalid.NotCheckpointable{}} listing the missing arities.

Calls Code.ensure_loaded?/1 before function_exported?/3 so the check works even if the optimizer module has not been touched in the running BEAM.

compile(impl, student, trainset, metric, opts)

@spec compile(
  module(),
  Dsxir.Program.t(),
  [Dsxir.Example.t()],
  nil | Dsxir.Metric.t(),
  keyword()
) :: result()

Dispatch to impl.compile/4 with validated arguments.

Guards: impl must be an atom (module), trainset a list, metric must be either nil or a 3-arity function (optimizers that do not need a metric — e.g. Dsxir.Optimizer.KNNFewShot — accept nil), and opts a keyword list (any list satisfies the guard; impls are expected to treat it as a keyword list).