Skip to content

Add MoveGenerator methods for syncing RL agent state - #3789

Merged
soheilshahrouz merged 2 commits into
masterfrom
move_generator_sync_state
Sep 2, 2026
Merged

Add MoveGenerator methods for syncing RL agent state#3789
soheilshahrouz merged 2 commits into
masterfrom
move_generator_sync_state

Conversation

@soheilshahrouz

@soheilshahrouz soheilshahrouz commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Adds three virtual methods to MoveGenerator, implemented only by SimpleRlMoveGenerator. These methods allow the RL-agent to copy another agent's state. This PR also adds get_last_action() and set_last_action().

In parallel swap evaluation, multiple threads will propose moves using their private instance of MoveGenerator. A master thread captures the proposed move type of each thread with get_last_action() and applies it to its own copy with set_last_action() to update the Q-table in a deterministic order. Then, all thread synchronize their Q-tables by calling sync_state_from().

The serial annealer never calls these new methods, so no runtime overhead is added to the serial code.

@github-actions github-actions Bot added VPR VPR FPGA Placement & Routing Tool lang-cpp C/C++ code labels Aug 28, 2026

@AlexandreSinger AlexandreSinger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @soheilshahrouz , I left one comment below for you to think on. Let me know what you think.

* a generator of the same concrete type, so a replica proposes exactly
* what the master would.
*/
virtual void sync_state_from(const MoveGenerator& /*other*/) {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three methods are specific to the RL agent, and are meaningless for a general move generator in my opinion. I understand why you are doing it this way, since you want all move generators to do the same actions, these just end up being null-opts.

Can these be renamed in some way to make them more general. Something like "pre_move_..", "post_move_sync", etc. so these are more tied to when they are called for the move generator not what they do.

Another idea is to put these in the derived class, and then in the sections that are RL-specific you can dynamically cast the base move_generator class and conditionally run these methods. Something like:

if (auto rl_move_gen = dyn_cast<SimpleRLMoveGenerator>(move_gen)) {
  rl_move_gen->set_last_action(...);
}

I will let you use your judgment on this though; since this can make the code much worse depending on how you are implementing the parallel move generator. What you have here is reasonable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed these methods. I think this would be more similar to how process_outcome() is implemented.

@soheilshahrouz

Copy link
Copy Markdown
Contributor Author

@AlexandreSinger
Thanks for reviewing this. I deciced to rename those methods because process_outcome() already uses a virtual method that doesn't do anything in some generators. Let me know if you have further comments.

@AlexandreSinger AlexandreSinger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @soheilshahrouz

I like these names better. It makes it more clear that its used for "stateful" move generators, which makes sense to me.

@soheilshahrouz
soheilshahrouz merged commit 714ea84 into master Sep 2, 2026
39 checks passed
@soheilshahrouz
soheilshahrouz deleted the move_generator_sync_state branch September 2, 2026 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lang-cpp C/C++ code VPR VPR FPGA Placement & Routing Tool

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants