Skip to content

Commit 714ea84

Browse files
Merge pull request #3789 from verilog-to-routing/move_generator_sync_state
Add MoveGenerator methods for syncing RL agent state
2 parents f7d53a4 + 180e02a commit 714ea84

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

vpr/src/place/move_generators/move_generator.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,26 @@ class MoveGenerator {
146146
*/
147147
virtual void process_outcome(double /*reward*/, e_reward_function /*reward_fun*/) {}
148148

149+
/**
150+
* @brief Returns a token describing the generator's state after the most
151+
* recent propose_move(). Only needed when outcomes are not reported right
152+
* after each proposal. A caller can record the token and reward of each
153+
* proposal and apply them later in a batch. Stateless generators return 0.
154+
*/
155+
virtual size_t save_proposal_state() const { return 0; }
156+
157+
/**
158+
* @brief Restores a token from save_proposal_state() so the next
159+
* process_outcome() is credited to that proposal.
160+
*/
161+
virtual void restore_proposal_state(size_t /*state*/) {}
162+
163+
/**
164+
* @brief Copies the state from `other`, which must be of the same
165+
* concrete type, so this generator proposes what `other` would.
166+
*/
167+
virtual void copy_state_from(const MoveGenerator& /*other*/) {}
168+
149169
/**
150170
* @brief Calculates the agent's reward and the total process outcome
151171
*

vpr/src/place/move_generators/simpleRL_move_generator.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ void SimpleRLMoveGenerator::process_outcome(double reward, e_reward_function rew
3131
karmed_bandit_agent->process_outcome(reward, reward_fun);
3232
}
3333

34+
void SimpleRLMoveGenerator::copy_state_from(const MoveGenerator& other) {
35+
// Callers always pass a generator of the same concrete type,
36+
// and this runs once per sync rather than per move, so the cost is negligible.
37+
const SimpleRLMoveGenerator* other_rl = dynamic_cast<const SimpleRLMoveGenerator*>(&other);
38+
VTR_ASSERT_MSG(other_rl != nullptr, "Can only copy agent state from another SimpleRLMoveGenerator.");
39+
karmed_bandit_agent->copy_state_from(*other_rl->karmed_bandit_agent);
40+
}
41+
3442
/* *
3543
* *
3644
* K-Armed bandit agent implementation *
@@ -164,6 +172,15 @@ void KArmedBanditAgent::write_agent_info(int last_action, double reward) {
164172
fflush(agent_info_file_);
165173
}
166174

175+
void KArmedBanditAgent::copy_state_from(const KArmedBanditAgent& other) {
176+
VTR_ASSERT_SAFE(num_available_actions_ == other.num_available_actions_);
177+
VTR_ASSERT_SAFE(q_.size() == other.q_.size());
178+
179+
exp_alpha_ = other.exp_alpha_;
180+
q_ = other.q_;
181+
num_action_chosen_ = other.num_action_chosen_;
182+
}
183+
167184
void KArmedBanditAgent::set_step(float gamma, int move_lim) {
168185
if (gamma < 0) {
169186
exp_alpha_ = -1; //Use sample average

vpr/src/place/move_generators/simpleRL_move_generator.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ class KArmedBanditAgent {
5555
*/
5656
void set_step(float gamma, int move_lim);
5757

58+
/// @brief Returns the action (arm) selected by the most recent propose_action() call.
59+
size_t last_action() const { return last_action_; }
60+
61+
/// @brief Overrides the action credited by the next process_outcome() call.
62+
/// See MoveGenerator::save_proposal_state() for the intended usage.
63+
void set_last_action(size_t action) { last_action_ = action; }
64+
65+
/// @brief Copies the learned state (Q-values, action counts, step size) from `other`.
66+
/// Both agents must have been constructed with identical configurations.
67+
void copy_state_from(const KArmedBanditAgent& other);
68+
5869
protected:
5970
/**
6071
* @brief Converts an action index to a move type.
@@ -252,6 +263,15 @@ class SimpleRLMoveGenerator : public MoveGenerator {
252263

253264
// Receives feedback about the outcome of the previously proposed move
254265
void process_outcome(double reward, e_reward_function reward_fun) override;
266+
267+
/// @brief Saves/restores the agent action behind the most recent proposal.
268+
/// See MoveGenerator::save_proposal_state() for the intended usage.
269+
size_t save_proposal_state() const override { return karmed_bandit_agent->last_action(); }
270+
void restore_proposal_state(size_t state) override { karmed_bandit_agent->set_last_action(state); }
271+
272+
/// @brief Copies the agent state from another SimpleRLMoveGenerator.
273+
/// See MoveGenerator::copy_state_from() for the intended usage.
274+
void copy_state_from(const MoveGenerator& other) override;
255275
};
256276

257277
template<class T, class>

0 commit comments

Comments
 (0)