https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
LibtorchRLTrajectoryAssembler Class Reference

Builds fixed-horizon RL trajectories from raw per-sample reporter sequences. More...

#include <LibtorchRLTrajectoryAssembler.h>

Public Types

using ReporterData = std::vector< const std::vector< std::vector< Real > > * >
 Raw reporter data for one rollout quantity, indexed as [component][sample][raw time].
 

Public Member Functions

 LibtorchRLTrajectoryAssembler (unsigned int input_timesteps, unsigned int timestep_window, bool shift_outputs, bool average_reward_over_timestep_window)
 Build the trajectory assembler.
 
std::vector< LibtorchRLTrajectoryBuffer::Trajectory > assemble (const ReporterData &observations, const ReporterData &actions, const ReporterData &log_probabilities, const std::vector< std::vector< Real > > &rewards) const
 Assemble one trajectory per sample that holds at least one transition.
 
unsigned int numTransitions (std::size_t raw_sequence_size) const
 Count the transitions available in a raw reporter sequence.
 

Private Member Functions

std::vector< Real > downsample (const std::vector< Real > &sample, unsigned int offset, unsigned int num_entries) const
 Take every timestep_window-th entry of a raw reporter sequence.
 
std::vector< Real > windowAverage (const std::vector< Real > &sample, unsigned int num_entries) const
 Average a raw reporter sequence over consecutive timestep windows after the initial entry.
 

Static Private Member Functions

static void checkSampleCount (const ReporterData &data, const std::string &quantity, std::size_t num_samples)
 Check that every component of a rollout quantity holds one sequence per sample.
 

Private Attributes

const unsigned int _timestep_window
 Raw reporter entries per transition.
 
const bool _shift_outputs
 Whether actions and log probabilities are read one raw entry after the observation.
 
const bool _average_reward_over_timestep_window
 Whether rewards are averaged over each window instead of sampled at its end.
 
const LibtorchObservationHistoryHelper _observation_history
 Observation history stacking helper.
 

Detailed Description

Builds fixed-horizon RL trajectories from raw per-sample reporter sequences.

Raw index 0 of every sequence holds the initial value and raw index n holds the value at the end of time step n. Transition k uses the observation at raw index k * W, the action and log probability at raw index k * W (+ 1 when outputs are shifted), and the reward at raw index (k + 1) * W, or the mean over raw indices k * W + 1 through (k + 1) * W. Here W is the timestep window. Observation history lags also span W raw entries.

Definition at line 29 of file LibtorchRLTrajectoryAssembler.h.

Member Typedef Documentation

◆ ReporterData

using LibtorchRLTrajectoryAssembler::ReporterData = std::vector<const std::vector<std::vector<Real> > *>

Raw reporter data for one rollout quantity, indexed as [component][sample][raw time].

Definition at line 33 of file LibtorchRLTrajectoryAssembler.h.

Constructor & Destructor Documentation

◆ LibtorchRLTrajectoryAssembler()

LibtorchRLTrajectoryAssembler::LibtorchRLTrajectoryAssembler ( unsigned int  input_timesteps,
unsigned int  timestep_window,
bool  shift_outputs,
bool  average_reward_over_timestep_window 
)

Build the trajectory assembler.

Parameters
input_timestepsNumber of stacked observation time levels.
timestep_windowRaw reporter entries per transition.
shift_outputsWhether actions and log probabilities are read one raw entry later.
average_reward_over_timestep_windowWhether rewards are averaged over each window.

Definition at line 20 of file LibtorchRLTrajectoryAssembler.C.

25 : _timestep_window(timestep_window),
26 _shift_outputs(shift_outputs),
27 _average_reward_over_timestep_window(average_reward_over_timestep_window),
28 _observation_history(input_timesteps)
29{
31 mooseError("The RL trajectory timestep window must be at least 1.");
32}
void mooseError(Args &&... args)
const bool _average_reward_over_timestep_window
Whether rewards are averaged over each window instead of sampled at its end.
const LibtorchObservationHistoryHelper _observation_history
Observation history stacking helper.
const unsigned int _timestep_window
Raw reporter entries per transition.
const bool _shift_outputs
Whether actions and log probabilities are read one raw entry after the observation.

Member Function Documentation

◆ assemble()

std::vector< LibtorchRLTrajectoryBuffer::Trajectory > LibtorchRLTrajectoryAssembler::assemble ( const ReporterData &  observations,
const ReporterData &  actions,
const ReporterData &  log_probabilities,
const std::vector< std::vector< Real > > &  rewards 
) const

Assemble one trajectory per sample that holds at least one transition.

Parameters
observationsObservation reporter data.
actionsAction reporter data.
log_probabilitiesLog-probability reporter data, one entry per action.
rewardsReward reporter data indexed as [sample][raw time].
Returns
Assembled trajectories in sample order.

Definition at line 35 of file LibtorchRLTrajectoryAssembler.C.

39{
40 if (actions.size() != log_probabilities.size())
41 mooseError("The number of log-probability reporters (",
42 log_probabilities.size(),
43 ") must match the number of action reporters (",
44 actions.size(),
45 ").");
46
47 checkSampleCount(observations, "observation", rewards.size());
48 checkSampleCount(actions, "action", rewards.size());
49 checkSampleCount(log_probabilities, "log-probability", rewards.size());
50
51 std::vector<LibtorchRLTrajectoryBuffer::Trajectory> trajectories;
52
53 for (const auto sample_i : index_range(rewards))
54 {
55 const auto & reward_sample = rewards[sample_i];
56 const auto num_transitions = numTransitions(reward_sample.size());
57 if (!num_transitions)
58 continue;
59
60 std::vector<std::vector<Real>> component_trajectories(observations.size());
61 for (const auto observation_i : index_range(observations))
62 component_trajectories[observation_i] =
63 downsample((*observations[observation_i])[sample_i], 0, num_transitions + 1);
64
66 trajectory.observations.reserve(num_transitions);
67 trajectory.next_observations.reserve(num_transitions);
68 trajectory.actions.assign(num_transitions, std::vector<Real>());
69 trajectory.log_probabilities.assign(num_transitions, std::vector<Real>());
70
71 for (auto & action_row : trajectory.actions)
72 action_row.reserve(actions.size());
73 for (auto & log_probability_row : trajectory.log_probabilities)
74 log_probability_row.reserve(log_probabilities.size());
75
76 for (const auto step_i : make_range(num_transitions))
77 {
78 trajectory.observations.push_back(
79 _observation_history.stackTrajectoryObservation(component_trajectories, step_i));
80 trajectory.next_observations.push_back(
81 _observation_history.stackTrajectoryObservation(component_trajectories, step_i + 1));
82 }
83
84 for (const auto action_i : index_range(actions))
85 {
86 const auto action_sequence =
87 downsample((*actions[action_i])[sample_i], _shift_outputs, num_transitions);
88 const auto log_probability_sequence =
89 downsample((*log_probabilities[action_i])[sample_i], _shift_outputs, num_transitions);
90
91 for (const auto step_i : make_range(num_transitions))
92 {
93 trajectory.actions[step_i].push_back(action_sequence[step_i]);
94 trajectory.log_probabilities[step_i].push_back(log_probability_sequence[step_i]);
95 }
96 }
97
99 ? windowAverage(reward_sample, num_transitions)
100 : downsample(reward_sample, _timestep_window, num_transitions);
101 // Full-solve rollout states are discarded after transfer, so GAE must stop at the boundary.
102 trajectory.terminals.assign(num_transitions, false);
103 trajectory.terminals.back() = true;
104
105 trajectories.push_back(std::move(trajectory));
106 }
107
108 return trajectories;
109}
std::vector< Real > stackTrajectoryObservation(const std::vector< std::vector< Real > > &component_trajectories, unsigned int time_index) const
std::vector< Real > windowAverage(const std::vector< Real > &sample, unsigned int num_entries) const
Average a raw reporter sequence over consecutive timestep windows after the initial entry.
unsigned int numTransitions(std::size_t raw_sequence_size) const
Count the transitions available in a raw reporter sequence.
std::vector< Real > downsample(const std::vector< Real > &sample, unsigned int offset, unsigned int num_entries) const
Take every timestep_window-th entry of a raw reporter sequence.
static void checkSampleCount(const ReporterData &data, const std::string &quantity, std::size_t num_samples)
Check that every component of a rollout quantity holds one sequence per sample.
auto index_range(const T &sizable)
IntRange< T > make_range(T beg, T end)
Vector data for one on-policy trajectory.
std::vector< Real > rewards
Scalar rewards for each transition.
std::vector< std::vector< Real > > observations
Observations for each transition.
std::vector< std::vector< Real > > actions
Actions applied at each transition.
std::vector< std::vector< Real > > next_observations
Next observations for each transition.
std::vector< std::vector< Real > > log_probabilities
Action log-probabilities recorded during rollout.
std::vector< bool > terminals
Terminal flags for each transition. A true value cuts value bootstrapping at that step.

Referenced by LibtorchDRLControlTrainer::collectTrajectoriesFromReporters().

◆ checkSampleCount()

void LibtorchRLTrajectoryAssembler::checkSampleCount ( const ReporterData &  data,
const std::string &  quantity,
std::size_t  num_samples 
)
staticprivate

Check that every component of a rollout quantity holds one sequence per sample.

Parameters
dataReporter data to check.
quantityName of the rollout quantity used in the error message.
num_samplesNumber of samples held by the reward reporter.

Definition at line 119 of file LibtorchRLTrajectoryAssembler.C.

122{
123 for (const auto component_i : index_range(data))
124 if (data[component_i]->size() != num_samples)
125 mooseError("Entry ",
126 component_i,
127 " of the ",
128 quantity,
129 " reporters holds ",
130 data[component_i]->size(),
131 " samples, but the reward reporter holds ",
132 num_samples,
133 " samples.");
134}
if(subdm)

Referenced by assemble().

◆ downsample()

std::vector< Real > LibtorchRLTrajectoryAssembler::downsample ( const std::vector< Real > &  sample,
unsigned int  offset,
unsigned int  num_entries 
) const
private

Take every timestep_window-th entry of a raw reporter sequence.

Parameters
sampleRaw reporter sequence.
offsetRaw index of the first entry.
num_entriesNumber of entries to extract.
Returns
Downsampled sequence.

Definition at line 137 of file LibtorchRLTrajectoryAssembler.C.

140{
141 std::vector<Real> values;
142 values.reserve(num_entries);
143
144 for (const auto entry_i : make_range(num_entries))
145 {
146 const auto raw_index = offset + entry_i * _timestep_window;
147 if (raw_index >= sample.size())
148 mooseError("Reporter data is shorter than required by the configured timestep window and "
149 "history stacking.");
150 values.push_back(sample[raw_index]);
151 }
152
153 return values;
154}
std::array< Real, 2 > values

Referenced by assemble().

◆ numTransitions()

unsigned int LibtorchRLTrajectoryAssembler::numTransitions ( std::size_t  raw_sequence_size) const

Count the transitions available in a raw reporter sequence.

Parameters
raw_sequence_sizeNumber of raw time entries in the reporter sequence.
Returns
Number of complete timestep windows after the initial entry.

Definition at line 112 of file LibtorchRLTrajectoryAssembler.C.

113{
114 // Raw index 0 holds the initial value, so each transition consumes one full window after it.
115 return raw_sequence_size ? (raw_sequence_size - 1) / _timestep_window : 0;
116}

Referenced by assemble().

◆ windowAverage()

std::vector< Real > LibtorchRLTrajectoryAssembler::windowAverage ( const std::vector< Real > &  sample,
unsigned int  num_entries 
) const
private

Average a raw reporter sequence over consecutive timestep windows after the initial entry.

Parameters
sampleRaw reporter sequence.
num_entriesNumber of windows to average.
Returns
Window-averaged sequence.

Definition at line 157 of file LibtorchRLTrajectoryAssembler.C.

159{
160 std::vector<Real> values;
161 values.reserve(num_entries);
162
163 for (const auto entry_i : make_range(num_entries))
164 {
165 const auto window_begin = 1 + entry_i * _timestep_window;
166 const auto window_end = window_begin + _timestep_window;
167 if (window_end > sample.size())
169 "Reporter reward data is shorter than required by the configured timestep window.");
170
171 const Real sum =
172 std::accumulate(sample.begin() + window_begin, sample.begin() + window_end, 0.0);
173 values.push_back(sum / _timestep_window);
174 }
175
176 return values;
177}
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

Referenced by assemble().

Member Data Documentation

◆ _average_reward_over_timestep_window

const bool LibtorchRLTrajectoryAssembler::_average_reward_over_timestep_window
private

Whether rewards are averaged over each window instead of sampled at its end.

Definition at line 102 of file LibtorchRLTrajectoryAssembler.h.

Referenced by assemble().

◆ _observation_history

const LibtorchObservationHistoryHelper LibtorchRLTrajectoryAssembler::_observation_history
private

Observation history stacking helper.

Definition at line 104 of file LibtorchRLTrajectoryAssembler.h.

Referenced by assemble().

◆ _shift_outputs

const bool LibtorchRLTrajectoryAssembler::_shift_outputs
private

Whether actions and log probabilities are read one raw entry after the observation.

Definition at line 100 of file LibtorchRLTrajectoryAssembler.h.

Referenced by assemble().

◆ _timestep_window

const unsigned int LibtorchRLTrajectoryAssembler::_timestep_window
private

Raw reporter entries per transition.

Definition at line 98 of file LibtorchRLTrajectoryAssembler.h.

Referenced by assemble(), downsample(), LibtorchRLTrajectoryAssembler(), numTransitions(), and windowAverage().


The documentation for this class was generated from the following files: