[Feature] Add ReplayBuffer.update_if_present for generation-safe conditional updates - #4043
[Feature] Add ReplayBuffer.update_if_present for generation-safe conditional updates#4043theap06 wants to merge 4 commits into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/rl/4043
Note: Links to docs will display an error until the docs builds have been completed.
|
6b96677 to
6b16ca6
Compare
Executable spec for step 2 of the conditional replay-update RFC: rb.update_if_present(index=, generation=, patch=) applies every patch key to records whose (index, generation) is still live, skips reused or emptied slots without touching their content, and returns a result with an updated mask aligned to the input order plus updated/stale counts. The whole patch is validated before any write (KeyError for unknown keys, ValueError for shape or dtype mismatches, storage untouched in both cases), handles survive repeated updates, nested keys are supported, ListStorage raises a capability error, multidim storages round-trip, sampled handles flow straight into the call, and a concurrent writer/updater stress test pins non-torn multi-key visibility. RayReplayBuffer delegates the call to the actor. Tests are expected to fail until the implementation lands.
…itional updates Adds a best-effort conditional mutation API for stored replay fields. update_if_present(index=, generation=, patch=) applies a patch only to records whose (index, generation) pair still matches the writer's current slot generation, skipping records whose slot was recycled or emptied instead of corrupting them, and returns a ConditionalUpdateResult with a per-record updated mask plus updated/stale counts. The whole patch is validated (key existence, shape, dtype) before any write; validation failures leave storage untouched. The generation comparison and the patch write share one replay-lock acquisition, giving per-record atomicity against concurrent extends, and updating a record does not consume its handle. Tensor storages advertise supports_conditional_update; unsupported backends such as ListStorage raise a capability error instead of performing an unsafe raw-index write. RayReplayBuffer delegates the call to the actor in a single RPC (validation and write run inside the actor under its own lock); the distributed transport raises a clear capability error. Nested keys and multidimensional storages are supported. Second step of the conditional replay-update RFC. Closes pytorch#4040.
…ytorch#4046) Drop this PR's own generation-stamp scaffold (writers.py machinery, always-on tracking, sample-info insertions and their test patches) in favor of the storage-owned, opt-in implementation from pytorch#4046: - update_if_present keeps its contract but now requires a writer constructed with track_generations=True and raises otherwise; its generation comparison and patch masks are device-aware so CUDA/MPS storages and mixed-device handles work. - TestUpdateIfPresent builds its buffers with tracking writers, gains a test for the non-tracking capability error; the superseded TestSlotGenerations and TestSampleGenerationInfo suites are removed (covered by pytorch#4046's TestWriterGeneration). - The Ray test threads a tracking writer factory to the remote buffer. - The wraparound benchmark enables tracking so it no longer measures a no-op; docs and docstrings describe the opt-in reality and link to the generation-stamp reference section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Refresh update_if_present on the merged opt-in generation API. Add typed Ray delegation with CPU payload staging, delayed-init handling, compile-friendlier empty-live behavior, executable public examples, TensorDict-patch coverage, and a benchmark of the conditional update itself.
6b16ca6 to
b8bf0a7
Compare
|
Rebased onto current main and #4046, resolved the obsolete generation-stamp history, and marked this ready for review. The focused core, Ray, and doctest coverage passes locally. I do not have permission to request reviewers or apply labels; @vmoens, could you review and add the |
|
Reviewed rebased head One blocking correctness issue is at Targeted result: all 14 |
Description
Adds
ReplayBuffer.update_if_present, a generation-safe conditional mutation API for replay fields, on top of the opt-in generation stamps merged in #4046.The API:
ndim > 1.RuntimeErrorfor unsupported storages and writers without generation tracking.ConditionalUpdateResultwith the applied mask and update/skip counts.Version-comparison support remains in #4049.
Tests and documentation
TestUpdateIfPresentcases, including TensorDict patches, stale handles, validation, nested keys, and multidimensional storage.h5py, working Torch Inductor/OpenMP metadata, and a resolvable Gloo hostname).Part of #4040. Builds on #4046.