pub struct EvolutionaryHarness<B, S, F>{ /* private fields */ }Expand description
Wraps a Strategy into a BenchEnv so the benchmark harness can
drive it.
§Example
use burn::backend::Flex;
use rlevo_core::fitness::FitnessEvaluable;
use rlevo_core::evaluation::BenchEnv;
use rlevo_evolution::algorithms::ga::{GaConfig, GeneticAlgorithm};
use rlevo_evolution::fitness::FromFitnessEvaluable;
use rlevo_evolution::strategy::EvolutionaryHarness;
struct Sphere;
struct SphereFit;
impl FitnessEvaluable for SphereFit {
type Individual = Vec<f64>;
type Landscape = Sphere;
fn evaluate(&self, x: &Self::Individual, _: &Self::Landscape) -> f64 {
x.iter().map(|v| v * v).sum()
}
}
let device = Default::default();
let mut harness = EvolutionaryHarness::<Flex, _, _>::new(
GeneticAlgorithm::<Flex>::new(),
GaConfig::default_for(32, 5),
FromFitnessEvaluable::new(SphereFit, Sphere),
0, device, 100,
);
harness.reset();
while !harness.step(()).done {}Each step runs one generation (ask → evaluate →
tell). The reward returned to the harness is -best_fitness_ever so
the harness’s “higher = better” convention matches the strategy’s
minimization direction, and so the per-episode cumulative return
(Σ step rewards) integrates the optimization trajectory —
return_value / num_steps bounds the final best_fitness_ever from
above. The harness only exposes episode-level returns to reporters,
so the “best at end” signal would otherwise be lost.
§Determinism and parallel execution
Burn backends seed their tensor RNG through process-global state —
the flex backend uses a Mutex<Option<FlexRng>>, the
wgpu backend a per-device seeded stream. When multiple harness
instances run in parallel threads (e.g.
Evaluator::run_suite with the default rayon pool), their
interleaved B::seed(...) → Tensor::random(...) call pairs race on
that shared state and destroy bit-reproducibility across runs.
For deterministic reproduction, pass
EvaluatorConfig::num_threads = Some(1) or run one harness per
process. The tests/determinism.rs and tests/rastrigin_run_suite.rs
integration tests both enforce serial execution for this reason.
Implementations§
Source§impl<B, S, F> EvolutionaryHarness<B, S, F>
impl<B, S, F> EvolutionaryHarness<B, S, F>
Sourcepub fn new(
strategy: S,
params: S::Params,
fitness_fn: F,
seed: u64,
device: B::Device,
max_generations: usize,
) -> Self
pub fn new( strategy: S, params: S::Params, fitness_fn: F, seed: u64, device: B::Device, max_generations: usize, ) -> Self
Build a new harness from its parts.
The harness is lazily initialized — the first reset
call materializes the initial state on the supplied device.
Sourcepub fn with_observer(self, observer: SharedPopulationObserver) -> Self
pub fn with_observer(self, observer: SharedPopulationObserver) -> Self
Attach a per-generation PopulationObserver.
The observer is called once per step call, after the
canonical tracing::info!("evolution generation", …) event. It
receives a PopulationSnapshot
carrying the full per-individual fitness vector for the completed
generation. The intended consumer is a benchmark-tier recording sink
that persists population-level data alongside the scalar metric stream.
Attaching an observer adds one device→host transfer of the fitness tensor per generation; runs without an observer pay nothing.
Sourcepub fn latest_metrics(&self) -> Option<&StrategyMetrics>
pub fn latest_metrics(&self) -> Option<&StrategyMetrics>
Snapshot of the most recent generation’s metrics, if any.
Sourcepub fn generation(&self) -> usize
pub fn generation(&self) -> usize
Generation counter — number of completed tell calls.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset to a fresh initial state.
Inherent shape (infallible): EvolutionaryHarness cannot legitimately
fail to reset — it is a deterministic optimization driver. The
BenchEnv trait impl wraps this in Ok(()) so the harness is
callable both directly (this method) and via the BenchEnv surface
when fed to Evaluator::run_suite.
Trait Implementations§
Source§impl<B, S, F> BenchEnv for EvolutionaryHarness<B, S, F>
impl<B, S, F> BenchEnv for EvolutionaryHarness<B, S, F>
Source§type Observation = ()
type Observation = ()
Source§fn reset(&mut self) -> Result<Self::Observation, BenchError>
fn reset(&mut self) -> Result<Self::Observation, BenchError>
Source§fn step(
&mut self,
action: Self::Action,
) -> Result<BenchStep<Self::Observation>, BenchError>
fn step( &mut self, action: Self::Action, ) -> Result<BenchStep<Self::Observation>, BenchError>
action and advance the environment by one step. Read moreAuto Trait Implementations§
impl<B, S, F> !RefUnwindSafe for EvolutionaryHarness<B, S, F>
impl<B, S, F> !UnwindSafe for EvolutionaryHarness<B, S, F>
impl<B, S, F> Freeze for EvolutionaryHarness<B, S, F>
impl<B, S, F> Send for EvolutionaryHarness<B, S, F>
impl<B, S, F> Sync for EvolutionaryHarness<B, S, F>
impl<B, S, F> Unpin for EvolutionaryHarness<B, S, F>
impl<B, S, F> UnsafeUnpin for EvolutionaryHarness<B, S, F>where
S: UnsafeUnpin,
<S as Strategy<B>>::Params: UnsafeUnpin,
F: UnsafeUnpin,
<B as BackendTypes>::Device: UnsafeUnpin,
<S as Strategy<B>>::State: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more