10#ifdef MOOSE_LIBTORCH_ENABLED
16#include "libmesh/utility.h"
26bufferMatrixToTensor(
const std::vector<std::vector<Real>> & rows)
31 const auto num_columns = rows.front().size();
32 auto tensor = torch::zeros({
static_cast<long>(rows.size()),
static_cast<long>(num_columns)},
33 torch::TensorOptions().dtype(torch::kDouble));
34 auto accessor = tensor.accessor<
Real, 2>();
36 for (
const auto row_i :
make_range(rows.size()))
38 if (rows[row_i].size() != num_columns)
39 mooseError(
"All rows must have the same number of entries when flattening an RL batch.");
41 for (
const auto column_i :
make_range(num_columns))
42 accessor[row_i][column_i] = rows[row_i][column_i];
49bufferVectorToColumnTensor(
const std::vector<Real> & values)
54 auto tensor = torch::zeros({
static_cast<long>(
values.size()), 1},
55 torch::TensorOptions().dtype(torch::kDouble));
56 auto accessor = tensor.accessor<
Real, 2>();
59 accessor[value_i][0] =
values[value_i];
82 std::size_t transitions = 0;
84 transitions += trajectory.rewards.size();
96 std::vector<std::vector<Real>> observations;
97 std::vector<std::vector<Real>> next_observations;
98 std::vector<std::vector<Real>> actions;
99 std::vector<std::vector<Real>> log_probabilities;
100 std::vector<Real> rewards;
101 std::vector<Real> value_targets;
102 std::vector<Real> advantages;
114 if (!trajectory.value_targets.empty() &&
115 trajectory.value_targets.size() != trajectory.rewards.size())
116 mooseError(
"Value targets must match the reward length of the trajectory.");
117 if (!trajectory.advantages.empty() && trajectory.advantages.size() != trajectory.rewards.size())
118 mooseError(
"Advantages must match the reward length of the trajectory.");
121 observations.end(), trajectory.observations.begin(), trajectory.observations.end());
122 next_observations.insert(next_observations.end(),
123 trajectory.next_observations.begin(),
124 trajectory.next_observations.end());
125 actions.insert(actions.end(), trajectory.actions.begin(), trajectory.actions.end());
126 log_probabilities.insert(log_probabilities.end(),
127 trajectory.log_probabilities.begin(),
128 trajectory.log_probabilities.end());
129 rewards.insert(rewards.end(), trajectory.rewards.begin(), trajectory.rewards.end());
130 value_targets.insert(
131 value_targets.end(), trajectory.value_targets.begin(), trajectory.value_targets.end());
132 advantages.insert(advantages.end(), trajectory.advantages.begin(), trajectory.advantages.end());
135 batch.
observations = bufferMatrixToTensor(observations);
137 batch.
actions = bufferMatrixToTensor(actions);
139 batch.
rewards = bufferVectorToColumnTensor(rewards);
140 batch.
value_targets = bufferVectorToColumnTensor(value_targets);
141 batch.
advantages = bufferVectorToColumnTensor(advantages);
152 if (!num_transitions)
155 const auto squared_deviation_sum = [](
const std::vector<Real> &
values,
const Real mean)
157 return std::transform_reduce(
values.begin(),
161 [mean](
const Real value)
162 { return (value - mean) * (value - mean); });
165 Real reward_sum = 0.0;
168 const auto & rewards = trajectory.rewards;
172 const Real trajectory_sum = std::accumulate(rewards.begin(), rewards.end(), 0.0);
173 const Real trajectory_mean = trajectory_sum / rewards.size();
176 std::sqrt(squared_deviation_sum(rewards, trajectory_mean) / rewards.size()));
177 reward_sum += trajectory_sum;
179 statistics.
mean = reward_sum / num_transitions;
182 Real overall_squared_deviation_sum = 0.0;
184 overall_squared_deviation_sum += squared_deviation_sum(trajectory.rewards, statistics.
mean);
185 statistics.
std = std::sqrt(overall_squared_deviation_sum / num_transitions);
193 const auto num_steps = trajectory.
rewards.size();
196 mooseError(
"RL trajectory observations must match the reward sequence length.");
199 mooseError(
"RL trajectory next observations must match the reward sequence length.");
201 if (trajectory.
actions.size() != num_steps)
202 mooseError(
"RL trajectory actions must match the reward sequence length.");
205 mooseError(
"RL trajectory log probabilities must match the reward sequence length.");
208 mooseError(
"RL trajectory terminal flags must match the reward sequence length.");
211 mooseError(
"RL trajectory value targets must match the reward sequence length.");
214 mooseError(
"RL trajectory advantages must match the reward sequence length.");
void mooseError(Args &&... args)
std::array< Real, 2 > values
void addTrajectory(Trajectory trajectory)
Append one trajectory to the on-policy buffer.
TensorBatch flatten() const
Flatten every stored trajectory into one tensor batch.
RewardStatistics rewardStatistics() const
Compute reward statistics over the stored trajectories.
static void validateTrajectory(const Trajectory &trajectory)
Validate a trajectory before it is stored.
std::vector< Trajectory > _trajectories
Stored on-policy trajectories.
void clear()
Clear every stored trajectory.
std::size_t numTransitions() const
Count the total number of transitions stored across every trajectory.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
Reward statistics over the stored trajectories.
std::vector< Real > trajectory_stds
Reward standard deviation of each non-empty trajectory about its own mean.
Real std
Standard deviation of every stored transition reward about the overall mean.
std::vector< Real > trajectory_means
Mean reward of each non-empty trajectory.
Real mean
Mean reward over every stored transition.
Flattened tensor data assembled from the stored trajectories.
torch::Tensor actions
Flattened action matrix.
torch::Tensor value_targets
Flattened critic targets.
torch::Tensor next_observations
Flattened next-observation matrix.
torch::Tensor observations
Flattened observation matrix.
torch::Tensor advantages
Flattened advantages.
torch::Tensor log_probabilities
Flattened action log-probabilities.
torch::Tensor rewards
Flattened rewards.
Vector data for one on-policy trajectory.
std::vector< Real > advantages
Advantage estimates aligned with each transition.
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< Real > value_targets
Critic targets aligned with 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.