Repository navigation
Add batched scene expansion and shared episode recording eligibility - #791
Conversation
Load and validate YAML generation parameters, reuse shared scene generation and layout solving, and expand each group from a common baseline. Keep successful candidates in memory and treat budget exhaustion as a normal tagged result. Validation: 97 focused configuration and generation tests passed; Black 26.3.1 passed across the repository. API documentation coverage remains pending because documentation updates are deferred.
Reuse the export loader collision conversion for generated scene fragments, covering default, single-hull and custom decomposition budgets. Document the 12 new public APIs and route grouped scene randomization through the GenSim context.
[Medium impact] The changes reach scene-layout workflows and environment recording across simulator rows. The PR still needs a limit on queued video jobs before merging.
|
| else: | ||
| self._futures[key] = self._executor.submit(self._write_job, key, job) |
There was a problem hiding this comment.
If simulation produces recordings faster than the single writer can encode them, record_camera_data_async._flush_jobs skips running jobs and keeps submitting new ones. Each queued episode holds a full copy of its frames, with no limit on pending work. Memory can keep growing until a long collection run crashes.
Add a pending-job or byte limit and wait for the writer when that limit is reached.
Prompt To Fix With AI
This is a comment left during a code review.
Path: embodichain/lab/gym/envs/managers/record.py
Line: 318-319
Comment:
**Queued videos exhaust RAM**
If simulation produces recordings faster than the single writer can encode them, `record_camera_data_async._flush_jobs` skips running jobs and keeps submitting new ones. Each queued episode holds a full copy of its frames, with no limit on pending work. Memory can keep growing until a long collection run crashes.
Add a pending-job or byte limit and wait for the writer when that limit is reached.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Description
Generate rigid scene variants through a shared CPU/CUDA core and apply them through Sim APIs, Scene Engine post-export jobs, or an
ExpandSceneLayoutreset event for handwritten expert and RL environments. Support group-root XY, selected member XY/yaw and subtree propagation while preserving assets, scales, explicit supports and fixed members. Geometry preparation is content-addressed; sampling remains batched and selected-row application does not step physics.EpisodeContextattaches recording eligibility to the current row buffers. Synchronous component checks block publication until completion; rejection remains sticky until buffers are consumed or discarded and a new episode begins. Normal trajectories, datasets and independent row videos all intersect that eligibility with existing save/fragment/commit policies. Reset consumes old recordings before changing physical state, first-frame errors reject initialization, camera first frames are captured after final host preparation, and asynchronous writers own data/provenance snapshots. Diagnostic exports have a separate purpose and directory; close never implicitly commits live buffers.RandomizeSceneLayoutdirectly withExpandSceneLayoutin Python/YAML. Configured event names keep the same named random streams. Provenance is nowepisode_context.sources["events/<configured_name>"].metadatain both reset info and episode metadata. No old class alias or expansion-specific environment save flags remain.TabletopFourBasesas a downloadable asset. Ship only the portablescene_export; generated layouts, geometry caches and native PNG/GIF/MP4 previews belong to the output workspace.TaskSpec/Task Engine changes stay in
codex/scene-randomization-task-spec, depending on unmerged #729. That integration uses independent frozen-layout and measured TaskSpec checks, restores frozen poses before the first frame and routes rejected/unverified evidence to diagnostics. This PR remains the independently mergeable shared layer.Type of change
Reproduce and preview
Use an empty output directory and the installed project runtime. Assets are published in the Hugging Face demo directory. The command saves
preview/contact_sheet.png,comparison.gifandcomparison.mp4alongside the 20-layout run.Validation
Reset row selection is normalized to
torch.long; regression tests now cover full reset, non-contiguous list selections, int32/int64 tensor inputs and empty reset, including shared robot/sensor UIDs and untouched rows. These stub-only tests explicitly run in the fast CPU lane.GitHub PR merge snapshot
21a37523(basef852b2af, PR head35c9858b) passed 8,726 CPU tests, 1 skipped, and 4 native Default/Newton selective-reset tests with the pinned rc1 runtime. This independently validates the combined source tree in addition to the branch.Latest CI-fix commit validation with the pinned
dexsim_engine==0.5.1rc1wheel: 8,139 passed, 1 skipped in the full shared CPU lane; 50 passed, 2 skipped in focused reset/IK cases; 4 passed in native Default/Newton, Sim/Gym four-row reset tests. No production behavior or dependency change in this follow-up. Context reviewed; no edit needed because lifecycle semantics are unchanged.Full integrated CI CPU lane: 9,401 passed, 2 skipped. Focused recording, functor, host and Task Engine regression suite: 707 passed, 2 skipped; the broader shared CPU run passed 2,281 tests, 1 skipped before the final boundary additions.
Native Default/Newton, Sim/Gym selective-reset tests: 4 passed, with four environments, non-contiguous reset IDs and rotated geometry. Gym probes also render 96×64 first frames, check selected-row camera buffers against current native frames, preserve unselected frames/counters, and forbid physics stepping during reset. CUDA geometry/replay suite: 19 passed.
Downloaded-asset demo: 20/20 valid; saved replay IDs and poses are unchanged, fixed cup/saucer error is below
1e-12, and native PNG/GIF/MP4 previews regenerated.On the dependent integration branch: three different E1 frozen layouts succeeded with measured TaskSpec acceptance, normal trajectories and per-row videos; one geometrically valid but unreachable layout was rejected and produced only labelled diagnostics.
Black 26.3.1, diff checks, context checks and public API coverage passed: 2,719/2,719 shared and 3,143/3,143 integrated. Shared HTML and shared/integrated Sphinx dummy builds passed; existing repository documentation warnings remain. Context/documentation regression tests: 139 passed.
Performance changes are limited to recording checks, snapshots and per-row metadata saving; the sampler is unchanged. On Ryzen 9 9950X / RTX 5090, Python 3.11, Torch 2.7.1, one CPU thread, 5 warmups/40 repetitions, the four-row/two-source CPU medians are 0.053 ms checks, 0.018 ms filtering, 0.043 ms snapshot. Publishing four JSON sidecars costs 0.223 ms with Context vs 0.078 ms baseline, using equal atomic-renaming writes without fsync or video encoding. CUDA-host measurements are synchronized and reported separately; this is not an end-to-end simulator speedup claim.
The existing 20/500/5,000-layout CPU/CUDA benchmark remains applicable because sampling is unchanged. At 5,000 layouts its previous three-seed medians were:
These include validated package I/O and native application to four environments without physics stepping. Geometry acceptance does not certify physical settling or task success; hosts provide measured task validation.
Checklist
black .using Black 26.3.1.