Skip to content

Run Parameters

Every value that controls a survey is a field of one of these two classes, one key of the plan file, and one command-line flag. The command-line surface is generated from dataclasses.fields(), so a new field reaches all three places.

ArchiveParams holds the values with the same meaning on every backend. GpuParams holds the values only a device backend can use. The two stay separate so that a device value on a host run is an error and not a setting with no effect.

A caller gives ordered override layers to resolve: the backend capability defaults, then the plan file, then the command-line flags. A later layer wins.

ArchiveParams dataclass

Survey parameters with the same meaning on every backend.

Attributes:

Name Type Description
cell float

Niche side in barycentric units. The grid is unbounded.

origin float

Grid origin on both axes.

n_iters int

The survey budget cap in variations.

seed int

RNG seed.

sigma_slide, scale_width float

Proposal widths for the branch moves.

logl_margin (float, optional)

Relative log-likelihood gate as a fixed number of nats below the best tree found. None leaves the gate to logl_margin_coeff.

logl_margin_coeff (float, optional)

Relative log-likelihood gate as this coefficient times the square root of the site count, used when logl_margin is None. None as well turns the gate off and leaves the budget as the only limit.

logl_floor (float, optional)

Absolute log-likelihood gate. Not permitted together with logl_margin.

converge bool

Halt on discovery saturation when set.

force_full_run bool

Run the full budget and ignore the halt.

gate_window int

Trailing window in checkpoints for the halt rates.

coverage_eps, precision_eps float

Halt thresholds on the windowed coverage and precision rates.

checkpoint_every int

Variations between two checkpoints. This sets the halt granularity and the monitor resolution on both engines.

n_walkers int

Parents drawn per pass. The GPU runs the walkers in parallel. The CPU runs them in a loop.

walk_steps int

Moves each walker makes per pass. Each move writes one candidate.

Source code in src/hifuku/params.py
@dataclass(frozen=True)
class ArchiveParams:
    """Survey parameters with the same meaning on every backend.

    Attributes
    ----------
    cell : float
        Niche side in barycentric units.  The grid is unbounded.
    origin : float
        Grid origin on both axes.
    n_iters : int
        The survey budget cap in variations.
    seed : int
        RNG seed.
    sigma_slide, scale_width : float
        Proposal widths for the branch moves.
    logl_margin : float, optional
        Relative log-likelihood gate as a fixed number of nats below the best
        tree found.  None leaves the gate to ``logl_margin_coeff``.
    logl_margin_coeff : float, optional
        Relative log-likelihood gate as this coefficient times the square root
        of the site count, used when ``logl_margin`` is None.  None as well
        turns the gate off and leaves the budget as the only limit.
    logl_floor : float, optional
        Absolute log-likelihood gate.  Not permitted together with
        ``logl_margin``.
    converge : bool
        Halt on discovery saturation when set.
    force_full_run : bool
        Run the full budget and ignore the halt.
    gate_window : int
        Trailing window in checkpoints for the halt rates.
    coverage_eps, precision_eps : float
        Halt thresholds on the windowed coverage and precision rates.
    checkpoint_every : int
        Variations between two checkpoints.  This sets the halt granularity and
        the monitor resolution on both engines.
    n_walkers : int
        Parents drawn per pass.  The GPU runs the walkers in parallel.  The CPU
        runs them in a loop.
    walk_steps : int
        Moves each walker makes per pass.  Each move writes one candidate.
    """

    cell: float = ARCHIVE_CELL
    origin: float = 0.0
    n_iters: int = ARCHIVE_N_ITERS
    seed: int = 0
    sigma_slide: float = DEFAULT_SIGMA_SLIDE
    scale_width: float = DEFAULT_SCALE_WIDTH
    logl_margin: float | None = None
    logl_margin_coeff: float | None = ARCHIVE_LOGL_MARGIN_COEFF
    logl_floor: float | None = None
    converge: bool = True
    force_full_run: bool = False
    gate_window: int = ARCHIVE_GATE_WINDOW
    coverage_eps: float = ARCHIVE_COVERAGE_EPS
    precision_eps: float = ARCHIVE_PRECISION_EPS
    checkpoint_every: int = ARCHIVE_CHECKPOINT_EVERY
    n_walkers: int = ARCHIVE_WALK_M
    walk_steps: int = ARCHIVE_WALK_K

    def __post_init__(self) -> None:
        if self.logl_margin is not None and self.logl_floor is not None:
            raise ValueError(
                "set logl_margin or logl_floor, not both; "
                "to use a floor, set logl_margin to None")
        for name in _POSITIVE:
            if getattr(self, name) < 1:
                raise ValueError(f"{name} must be 1 or more")

    @classmethod
    def resolve(cls, *layers: Mapping[str, Any]) -> "ArchiveParams":
        """Build the parameters from ordered override layers.

        A later layer wins over an earlier one.  Give the layers in this order:
        the backend capability defaults, the plan file, then the command-line
        flags.  An unknown field name raises ``ValueError``.
        """
        return cls(**_merge(cls, layers))

    @property
    def variations_per_pass(self) -> int:
        """Candidates that one pass makes."""
        return self.n_walkers * self.walk_steps

    @property
    def passes_per_checkpoint(self) -> int:
        """Passes that run between two checkpoints.

        A backend submits this many passes and then lets the driver read the
        statistics.  The count is 1 or more, so a checkpoint cadence smaller
        than one pass still makes progress.
        """
        return max(1, self.checkpoint_every // self.variations_per_pass)

variations_per_pass property

variations_per_pass: int

Candidates that one pass makes.

passes_per_checkpoint property

passes_per_checkpoint: int

Passes that run between two checkpoints.

A backend submits this many passes and then lets the driver read the statistics. The count is 1 or more, so a checkpoint cadence smaller than one pass still makes progress.

resolve classmethod

resolve(*layers: Mapping[str, Any]) -> 'ArchiveParams'

Build the parameters from ordered override layers.

A later layer wins over an earlier one. Give the layers in this order: the backend capability defaults, the plan file, then the command-line flags. An unknown field name raises ValueError.

Source code in src/hifuku/params.py
@classmethod
def resolve(cls, *layers: Mapping[str, Any]) -> "ArchiveParams":
    """Build the parameters from ordered override layers.

    A later layer wins over an earlier one.  Give the layers in this order:
    the backend capability defaults, the plan file, then the command-line
    flags.  An unknown field name raises ``ValueError``.
    """
    return cls(**_merge(cls, layers))

GpuParams dataclass

Survey parameters that only a device backend can use.

Attributes:

Name Type Description
extent float

Half-extent of the device niche allocation. This is a memory bound and not a limit on the chart domain.

Source code in src/hifuku/params.py
@dataclass(frozen=True)
class GpuParams:
    """Survey parameters that only a device backend can use.

    Attributes
    ----------
    extent : float
        Half-extent of the device niche allocation.  This is a memory bound and
        not a limit on the chart domain.
    """

    extent: float = ARCHIVE_GPU_EXTENT

    @classmethod
    def resolve(cls, *layers: Mapping[str, Any]) -> "GpuParams":
        """Build the parameters from ordered override layers.

        A later layer wins over an earlier one.  An unknown field name raises
        ``ValueError``.
        """
        return cls(**_merge(cls, layers))

resolve classmethod

resolve(*layers: Mapping[str, Any]) -> 'GpuParams'

Build the parameters from ordered override layers.

A later layer wins over an earlier one. An unknown field name raises ValueError.

Source code in src/hifuku/params.py
@classmethod
def resolve(cls, *layers: Mapping[str, Any]) -> "GpuParams":
    """Build the parameters from ordered override layers.

    A later layer wins over an earlier one.  An unknown field name raises
    ``ValueError``.
    """
    return cls(**_merge(cls, layers))