Skip to contents

Every performance-policy default shipped in EDI (whether an inference class uses a smart cold start, whether resampling reuses warm starts and at what sample sizes, which optimizer algorithm a family uses, and at what sample size parallel bootstrapping starts to beat serial) was measured empirically on the maintainer's machine. Yours differs – core count, cache, BLAS, compiler flags – so a policy that is net-positive there can be net-negative here, and vice versa. This function re-runs those benchmarks on your hardware, decides the winning setting per axis, saves the result to a per-user config file, and applies it immediately; every later library(EDI) re-applies it. Hardware changed? Re-run; it overwrites.

Usage

tune_EDI_for_this_machine(
  effort = c("standard", "quick", "thorough"),
  axes = NULL,
  families = NULL,
  n_grid = NULL,
  reps = NULL,
  num_cores_grid = NULL,
  converged_fn = NULL,
  quiet = FALSE,
  dry_run = FALSE,
  force = FALSE
)

Arguments

effort

One of "standard" (default; moderate sample-size grid and replicate count), "quick" (coarser grid, fewer replicates, warm-start families narrowed to those the shipped tables already name, parallel axis on the bootstrap operation only), or "thorough" (full grid, more replicates).

axes

Which axes to tune: any subset of "cold_start", "warm_start", "optimizer", "parallel". NULL (default) means all that are available here – see Details for when the optimizer and parallel axes are included.

families

Optional character vector of inference class names to restrict every axis to; NULL (default) tunes every class each axis governs.

n_grid

Optional integer vector of sample sizes overriding the effort tier's grid.

reps

Optional replicate count per timed cell overriding the effort tier's.

num_cores_grid

Optional integer vector of core counts (each \(\ge 2\)) for the parallel axis; default c(2, detectCores()).

converged_fn

function(inf) -> logical(1), required for the optimizer axis (see Details).

quiet

If TRUE, print nothing (no preamble, no progress bar, no summary).

dry_run

If TRUE, run every benchmark and print the would-be policy changes, but write no file and apply nothing.

force

If FALSE (default), refuse to run when the machine looks busy (see Details: "Idle machine") – in an interactive session you are asked whether to proceed anyway; non-interactively it is an error. TRUE skips the check. Applies under dry_run too, since a dry run still benchmarks.

Value

Invisibly, an EDILocalMachineTuning object: the policy diffs (policy_diffs), the raw per-axis deviations (raw_deviations), the hardware fingerprint, the effort/grid/reps used, timing, and the config file path – printable via print().

Details

What is tuned. Four axes, each against the corresponding get_*_dispatch_policy() table: cold start (get_cold_start_dispatch_policy), warm start per resampling operation (get_warm_start_dispatch_policy), optimizer algorithm (get_optimization_dispatch_policy), and the parallel-vs-serial crossover sample size per family (get_parallel_dispatch_policy). The bootstrap confidence-interval type policy is a statistical-validity table, not a performance one, and is never touched; nor are entries in the parallel policy's serial blocklist that exist for parallel safety.

How a deviation is accepted. Per axis, per (family, sample size) cell, both settings are timed on identical synthetic data – interleaved (A/B/A/B) for the cold-start/warm-start/optimizer axes, and blocked (all serial reps, then all parallel reps) for the parallel axis, whose fork-cluster setup cost rules out per-replicate interleaving. A candidate displaces the shipped default only if its median time is at least 5% better and that improvement exceeds twice the candidate's own interquartile spread; ties keep the shipped default. The optimizer axis additionally requires the candidate to have converged on every replicate of the cell – speed never trumps a convergence failure. Only deviations from the shipped defaults are stored, in the exact shape the matching set_*_dispatch_policy() setter accepts, and they are merged into (never replacing) the shipped tables.

Progress. A single progress bar with a running estimated-time-left is redrawn in place as each benchmark cell completes – the same bar InferenceSuite$run_all_inference() shows.

Correctness gate. A timing win alone does not displace a shipped default: every accepted deviation is re-fit once under both settings on identical synthetic data and the outputs compared (point estimates for cold start/optimizer/parallel; the resampling operation's own output, RNG-matched, for warm start). A disagreement – or an unverifiable comparison – discards the deviation, with a warning() naming it; discarded deviations are available on the returned object via attr(x, "discarded_by_correctness_gate") and are never written to the config file or applied.

The optimizer axis and converged_fn. There is not yet a generic, class-independent accessor on an inference object that reports whether its fit converged, so the optimizer axis needs you to supply one as converged_fn(inf). When axes is left NULL the optimizer axis is included only if converged_fn is given; asking for it explicitly without one is an error. An always-TRUE converged_fn disables the convergence guard and is not appropriate for a real tuning run.

The parallel axis. Runs only on Unix-alikes with at least two logical cores (it benchmarks a real fork cluster). Its preferred core count is recorded only – never applied at package load – you still opt into parallelism with set_num_cores.

Idle machine. Run this on an otherwise idle machine; a tuning run under contention measures the contention, not the hardware. Before benchmarking, the function checks the 1-minute load average against the core count and times a small fixed calibration operation for noise; if either says the machine is busy it refuses to run (interactively, it asks first) unless force = TRUE.

Examples

# \donttest{
# See what would change without writing anything. force = TRUE skips the
# idle-machine contention guard (see Details/`force` above) -- an example
# must not fail just because the machine running R CMD check happens to
# be busy (e.g. a shared CI runner); the guard itself has its own
# dedicated tests (test-local-machine-tuning-assembly.R). Scoped to one
# axis/family/n rather than the full live registry effort = "quick"
# otherwise walks (narrowing "quick" itself to a handful of
# high-effect-size families across every axis is still open, see
# edi_tuning_effort_presets()'s docs) -- this keeps the example a
# few-second sanity check instead of a multi-minute benchmark run.
res = tune_EDI_for_this_machine(effort = "quick", dry_run = TRUE, force = TRUE,
                                 axes = "cold_start", families = "InferenceIncidLogRegr",
                                 n_grid = 50L, reps = 1L)
#> tune_EDI_for_this_machine(): effort = "quick", axes = cold_start
#>   1 benchmark cells, n-grid = {50}, 1 replicates per cell. Expect roughly 2-5 minutes.
#>   Please keep the machine otherwise idle while this runs.
#>   dry_run = TRUE: nothing will be written or applied.
#> Cells 0/1     [                0%                 ] Status: Estimating...
Cells 1/1     [============= 100% ==============] Estimated Time Left: 0s
Status: Completed in 0s.
#> EDI local machine tuning (dry run -- not saved, not applied) 
#>   Run: 2026-09-02 06:58:00 | EDI 1.0.0 | effort = quick | 1 cells in 0s
#>   Machine: AMD EPYC 7763 64-Core Processor | 4 logical / 4 physical cores | BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> Deviations from shipped defaults:
#>   (none -- the shipped defaults already win on this machine)
print(res)
#> EDI local machine tuning (dry run -- not saved, not applied) 
#>   Run: 2026-09-02 06:58:00 | EDI 1.0.0 | effort = quick | 1 cells in 0s
#>   Machine: AMD EPYC 7763 64-Core Processor | 4 logical / 4 physical cores | BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> Deviations from shipped defaults:
#>   (none -- the shipped defaults already win on this machine)
# }