Skip to main content

RecurrentRolloutBuffer

Struct RecurrentRolloutBuffer 

Source
pub struct RecurrentRolloutBuffer { /* private fields */ }
Expand description

Rollout buffer that preserves temporal order for a recurrent policy.

Stores the same nine [num_steps, num_envs] transition arrays as RolloutBuffer (via composition) plus per-step recurrent state hidden / cell, each shaped [num_steps, num_envs, hidden_dim].

Implementations§

Source§

impl RecurrentRolloutBuffer

Source

pub fn new( num_steps: usize, num_envs: usize, obs_dim: usize, hidden_dim: usize, ) -> Self

Create a new recurrent rollout buffer.

§Arguments
  • num_steps - Number of timesteps per rollout
  • num_envs - Number of parallel environments
  • obs_dim - Dimensionality of observations
  • hidden_dim - Width of the LSTM (h, c) state
Source

pub fn add( &mut self, step: usize, env_id: usize, observation: &[f32], action: i64, reward: f32, value: f32, log_prob: f32, terminated: bool, truncated: bool, )

Add a transition to the buffer.

Delegates verbatim to RolloutBuffer::add; see that method for argument semantics. The recurrent (h, c) for this step is recorded separately via Self::add_recurrent_state.

Source

pub fn add_recurrent_state( &mut self, step: usize, env_id: usize, h: &[f32], c: &[f32], )

Record the recurrent state (h, c) entering step step for env env_id.

The rollout loop calls this before the env step, so the stored state is the one that entered the step — used for warm-start verification (via Self::seed_warm_start) and reserved as the hook a future Strategy B trainer would reuse. The training forward itself does not read these back (it recomputes states from a zeroed initial_state).

§Panics

Panics (debug builds) if step/env_id are out of range or if h/c do not have length hidden_dim.

Source

pub fn seed_warm_start( &mut self, last_step: usize, final_hidden: &[Vec<f32>], final_cell: &[Vec<f32>], )

Seed the step-0 recurrent state for the next rollout iteration, in place.

For each env, if it did not end its episode (terminated || truncated) on step last_step, its final recurrent state final_hidden[env] / final_cell[env] (the state exiting the last collected step) is carried into hidden[0][env] / cell[0][env]. If it did end its episode, step 0 is seeded with zeros — the episode already ended, so no memory should survive into the fresh one. This is the warm-start half of the GAE/state-reset asymmetry: the carry decision follows terminated || truncated, not terminated alone.

final_hidden / final_cell are indexed [env][hidden_dim] and must have num_envs rows.

This method also records the per-env cross-iteration carry-in flag that becomes episode_starts[0] of the next materialized batch: an env that ended its episode gets flag 1.0 (its step-0 state resets), a live env gets 0.0 (its state continues). The flag is set in lockstep with the (h, c) carry so the reset mask and the seeded state always agree.

§Strategy A note (the (h, c) carry is a Strategy-B hook)

The (h, c) seeded into hidden[0] / cell[0] here is not consumed by Strategy A’s Self::to_sequence_batch, which always passes initial_state: None (zeros) to the forward — an intentional BPTT truncation at the iteration boundary. Cross-iteration continuity is instead approximated only through the carry-in flag above (which controls the reset, not the value, of step 0’s state). The seeded (h, c) storage is a forward-looking hook a future Strategy B trainer (fixed-length subsequences with stored boundary states) would feed in; under Strategy A it is deliberately left unread.

§Panics

Panics if last_step >= num_steps, if final_hidden / final_cell do not have num_envs rows, or (debug builds) if any row is not hidden_dim wide.

Source

pub fn reset(&mut self)

Reset the buffer’s advantages/returns for a new rollout.

Delegates to RolloutBuffer::reset. The recurrent (h, c) arrays and the episode_start_carry flag are intentionally left in place — (h, c) is overwritten by Self::add_recurrent_state during the next collection, and both the step-0 state and the carry flag are seeded by Self::seed_warm_start so they must survive the reset to bridge the iteration boundary.

Source

pub fn compute_advantages( &mut self, last_values: &[f32], gamma: f32, gae_lambda: f32, )

Compute GAE over the full [num_steps, num_envs] capacity.

Delegates unchanged to compute_advantages — the [step][env] advantage/return grid is byte-identical to the feedforward path (GAE bootstraps on terminated only).

Source

pub fn compute_advantages_partial( &mut self, valid_steps: usize, last_values: &[f32], gamma: f32, gae_lambda: f32, )

Compute GAE over the first valid_steps rows.

Delegates unchanged to compute_advantages_partial.

Source

pub fn shape(&self) -> (usize, usize, usize)

Buffer shape (num_steps, num_envs, obs_dim).

Source

pub fn hidden_dim(&self) -> usize

Width of the recurrent (h, c) state.

Source

pub fn observations(&self) -> &[Vec<Vec<f32>>]

Per-step observations, indexed [step][env] then by obs dimension.

Source

pub fn actions(&self) -> &[Vec<i64>]

Per-step discrete actions, indexed [step][env].

Source

pub fn values(&self) -> &[Vec<f32>]

Per-step value estimates, indexed [step][env].

Source

pub fn log_probs(&self) -> &[Vec<f32>]

Per-step behavior-policy log-probs, indexed [step][env].

Source

pub fn terminated(&self) -> &[Vec<bool>]

Per-step terminal flags, indexed [step][env].

Source

pub fn truncated(&self) -> &[Vec<bool>]

Per-step truncation flags, indexed [step][env].

Source

pub fn advantages(&self) -> &[Vec<f32>]

Per-step GAE advantages, indexed [step][env].

Source

pub fn returns(&self) -> &[Vec<f32>]

Per-step value-function targets, indexed [step][env].

Source

pub fn hidden(&self) -> &[Vec<Vec<f32>>]

Recurrent hidden state entering each step, indexed [step][env] then by hidden dimension.

Source

pub fn cell(&self) -> &[Vec<Vec<f32>>]

Recurrent cell state entering each step, indexed [step][env] then by hidden dimension.

Source

pub fn episode_start_carry(&self) -> &[f32]

Per-env cross-iteration carry-in flag (episode_starts[0] source), indexed [env]. 1.0 marks that the env’s episode ended at the end of the previous rollout iteration (step 0 resets); 0.0 marks a carried-over episode.

Source

pub fn to_sequence_batch<B: Backend>( &self, device: &B::Device, ) -> RecurrentRolloutBatch<B>

Materialize the full buffer as a rank-3 sequence batch (T = num_steps).

Convenience wrapper over Self::to_sequence_batch_partial with valid_steps == num_steps.

Source

pub fn to_sequence_batch_partial<B: Backend>( &self, valid_steps: usize, device: &B::Device, ) -> RecurrentRolloutBatch<B>

Materialize the first valid_steps rows as a rank-3 sequence batch (T = valid_steps).

Selects all envs. See RecurrentRolloutBatch for the exact field shapes. Env-major layout: each env-trajectory is one contiguous row of length T.

§Panics

Panics if valid_steps > num_steps.

Source

pub fn to_minibatches<'a, B: Backend>( &'a self, envs_per_minibatch: usize, shuffle: bool, device: &B::Device, ) -> RecurrentMinibatchIterator<'a, B>

Build an env-major minibatch iterator over full trajectories (T = num_steps).

Shuffles environment indices (not global timesteps) and chunks them by envs_per_minibatch — the recurrent analogue of the feedforward batch_size, counting whole env-trajectories rather than loose timesteps. Over one epoch every env index appears in exactly one minibatch.

When shuffle is false the env order is 0..num_envs (useful for deterministic tests / reproducible evaluation).

Trait Implementations§

Source§

impl Clone for RecurrentRolloutBuffer

Source§

fn clone(&self) -> RecurrentRolloutBuffer

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RecurrentRolloutBuffer

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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