Skip to main content

Dehb

Struct Dehb 

pub struct Dehb { /* private fields */ }
Expand description

Differential-Evolution Hyperband: a stateful DE sampler over a Hyperband fidelity schedule.

Construct with Dehb::new (min/max fidelity, default η = 3 and the reference F = CR = 0.5) and hand it to a study through StudyBuilder::sampler, ideally paired with a HyperbandPruner over the same (min, max, η). See the module documentation for the algorithm.

use atune_core::sampler::Dehb;

// Fidelities 1, 3, 9, 27 (η = 3) — four DE subpopulations.
let dehb = Dehb::new(1, 27)?;
assert_eq!(dehb.fidelities(), [1, 3, 9, 27]);
assert_eq!(dehb.reduction_factor(), 3);

Implementations§

§

impl Dehb

pub fn new(min_fidelity: u64, max_fidelity: u64) -> Result<Self>

Builds a DEHB sampler over [min_fidelity, max_fidelity] with the default reduction factor η = 3 and the reference F = CR = 0.5.

§Errors

Error::InvalidSpace for a nonsense ladder — see RungLadder::new — and for min_fidelity == max_fidelity, which is not a ladder at all (see with_eta).

pub fn with_eta(min_fidelity: u64, max_fidelity: u64, eta: u32) -> Result<Self>

Builds a DEHB sampler with an explicit reduction factor η.

§Errors

Error::InvalidSpace for a nonsense ladder (RungLadder::new) or for a single-budget one (min_fidelity == max_fidelity). The latter is refused rather than degenerated into “plain DE”: with one fidelity the sole subpopulation is also always the target, the donor pool empties, and every rand/1 donor is a fresh uniform vector — random search wearing a DE hat. DEHB is a multi-fidelity method; a caller who wants one budget wants a different sampler.

pub fn with_mutation_factor(self, f: f64) -> Self

Sets the DE scale factor F (default DEFAULT_MUTATION_FACTOR).

Clamped to be non-negative; a runaway factor is still made safe by the boundary fix.

pub fn with_crossover_prob(self, cr: f64) -> Self

Sets the DE crossover rate CR (default DEFAULT_CROSSOVER_PROB), clamped into [0, 1].

pub const fn with_boundary_fix(self, boundary: BoundaryFix) -> Self

Sets how out-of-range mutant coordinates are repaired (default BoundaryFix::Clamp).

pub fn fidelities(&self) -> &[u64]

The geometric fidelity ladder [min·η⁰, …, max].

pub const fn reduction_factor(&self) -> u32

The reduction factor η.

pub fn min_fidelity(&self) -> u64

The lowest fidelity.

pub fn max_fidelity(&self) -> u64

The highest fidelity (the finish line).

pub const fn mutation_factor(&self) -> f64

The DE scale factor F.

pub const fn crossover_prob(&self) -> f64

The DE crossover rate CR.

pub fn target_fidelity(&self, trial_number: u64) -> Option<u64>

The fidelity a still-in-flight trial’s configuration was bred for, if the trial has been sampled and not yet told back.

This is how an executor learns what budget to run a job to (and, on a promotion, whether to warm-continue). It reads the pending job map, so a finished trial (whose job has been consumed by after_trial) returns None.

Trait Implementations§

§

impl Debug for Dehb

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
§

impl Sampler for Dehb

§

fn infer_relative_space(&self, study: &StudyView) -> Result<SpaceSchema>

The study’s declared space, verbatim.

DEHB evolves a fixed-dimension unit vector, so it wants a declared SpaceSchema. A define-by-run study (no declared space) yields an empty relative space here, which routes every parameter through sample_independent’s uniform fallback — DEHB’s DE engine is a static-space method.

§Errors

Never.

§

fn sample_relative( &self, _study: &StudyView, trial: &TrialMeta, space: &SpaceSchema, ) -> Result<Assignment>

Breeds this trial’s configuration with one DEHB job.

Every returned value lies in its declared support — it is produced through Distribution::from_unit of a unit coordinate in [0, 1], so contains holds for every kind (log, stepped, categorical, boolean).

§Errors

Error::InvalidSpace if a declared distribution is malformed; Error::Sampler if the state lock is poisoned or the restored state’s shape does not fit the live schedule (which restore_state already refuses to create — this is the belt-and-braces path that keeps a shape drift an error rather than an out-of-bounds panic).

§

fn sample_independent( &self, _study: &StudyView, trial: &TrialMeta, name: &str, dist: &Distribution, ) -> Result<ParamValue>

The uniform draw for a parameter the relative space did not cover — the same fallback Tpe uses, keyed on (sampler seed, name).

§Errors

Error::InvalidSpace if dist is malformed.

§

fn after_trial(&self, study: &StudyView, trial: &FrozenTrial) -> Result<()>

DE selection: the finished trial’s config competes for its target slot.

The trial’s pending job is taken unconditionally and first — a job is pending exactly while its trial is in flight, so every path out of this method consumes it. That is what keeps trial_jobs (and therefore the persisted state blob, which the loop re-serializes after every trial end) from growing without bound on the paths that do not select: a failed trial has no value, and a multi-objective study has no single loss.

The job then feeds selection only if all of the following hold; otherwise it is simply dropped, which is never an error:

  • the trial has one objective value and the study one direction;
  • the evaluated point is the bred point. The study loop samples every trial, including one created from a TrialTemplate (enqueued, retried or forked) whose fixed values then override the bred draw. Selection re-derives the evaluated configuration from the trial’s recorded parameters and compares it to the job’s vector, so a template’s loss can never be recorded as the fitness of a configuration nobody ran.

The objective is normalised to a loss (smaller is better) by the study direction; if it is at least as good as the slot’s current fitness — and finite — the slot adopts the child.

§Errors

Never — a failure here must not fail the trial, so a poisoned lock is swallowed (the update is simply skipped).

§

fn state(&self) -> Result<Option<SamplerState>>

The whole DEHB machine as a versioned blob — populations, counters, the bracket cursor and the pending-job map.

§Errors

Error::Sampler if the state lock is poisoned or the state cannot be serialized.

§

fn restore_state(&self, blob: &SamplerState) -> Result<()>

Rebuilds the DEHB machine from a persisted blob so a reopened study continues identically.

The blob’s ladder identity must match this sampler’s: the subpopulations, the parent counters and the promotion queues are all sized n_fid, so adopting a state saved under Dehb::new(1, 9) (3 fidelities) into a Dehb::new(1, 27) (4) would leave every later job indexing past the end of a vector. Such a resume is rejected rather than silently reinitialised, because the two ladders are two different searches and quietly discarding the saved populations would throw away the study’s whole history without telling anyone.

§Errors

Error::Sampler if the blob is not a DEHB blob of the expected version, was saved for a different fidelity ladder, cannot be decoded, or the lock is poisoned.

§

fn reseed(&self, _seed: u64)

A no-op: DEHB’s randomness is keyed on TrialMeta::sampler_seed and the study seed, so there is no auxiliary stream for a reseed to move — the same argument Tpe documents.

§

fn snapshots_space(&self) -> bool

Whether this sampler enumerates a snapshot of the space it was constructed with, rather than the space each ask presents. Read more

Auto Trait Implementations§

§

impl !Freeze for Dehb

§

impl RefUnwindSafe for Dehb

§

impl Send for Dehb

§

impl Sync for Dehb

§

impl Unpin for Dehb

§

impl UnsafeUnpin for Dehb

§

impl UnwindSafe for Dehb

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more