fix(data): restore pre-allocated batch_ptr capacity on put - #140
Conversation
Signed-off-by: Ryuhei Okuno <69704776+lil-lon@users.noreply.github.com>
Greptile SummaryThis PR fixes a silent data-loss bug (#136) in
Important Files Changed
Reviews (1): Last reviewed commit: "fix(data): restore pre-allocated batch_p..." | Re-trigger Greptile |
|
#141 fixes the same root cause (#136) by removing the trim in
For the record, why this PR kept the trim: without it, every put leaves the target's Restoring capacity instead keeps "trimmed at rest" as a structural guarantee rather than a usage convention. That was the intent. Happy to close this once #141 lands, or rebase it down to the sinks cleanup + tests if those are still useful. |
|
Thanks for taking a look! |
ALCHEMI Toolkit Pull Request
Description
Fixes #136: the first
put()trims the pre-allocatedbatch_ptrinSegmentedLevelStorage, so every laterput()fails the capacity checks and silently copies nothing, andzero()bakes in the trimmed size.Root cause
batch_ptrmust be tight for readers (len == num_graphs + 1; kernels derive counts from its shape) but must keep headroom forput()to append. The headroom's only record wasbatch_ptr.shape[0]itself, so the first trim destroyed it irreversibly — it cannot be re-derived from the data shape (elements, not segments).Why it went unnoticed
GPUBuffer, the consumer of reusableBatch.emptybuffers, re-extendsbatch_ptrafter everywrite()from its externally-known capacity (_restore_batch_ptr_capacity, added in #4), which masked the bug on that path.Fix
SegmentedLevelStoragerecordsbatch_ptr_capacityat construction and re-extends the trimmedbatch_ptrjust before the capacity checks input()/compute_put_per_system_fit_mask().Every
Batch.emptybuffer is covered at once, and theGPUBufferrestore becomes redundant and is removed.The lazy-init/extend block in
_ensure_bufferwas already dead code:Batch.emptyallocatesbatch_ptreagerly withnum_systems + 2entries. Nothing else changes: the trim and the published tightbatch_ptrare as before, and non-buffer storages record no capacity, so the restore is a no-op for them.Type of Change
Related Issues
#136
Changes Made
SegmentedLevelStorage.__init__recordsbatch_ptr_capacity; new_restore_batch_ptr_capacity()re-extends a trimmedbatch_ptr, called fromput()andcompute_put_per_system_fit_mask();clone()carries the capacityGPUBuffer._restore_batch_ptr_capacityand its call sitesput()into aBatch.emptybuffer,put → zero → putreuse (the 🐛[BUG]: A pre-allocated Batch.empty buffer can only be filled once: every put() after the first is a silent no-op #136 repro), and a storage-level repeated-put testTesting
make pytest)make lint)Checklist
Additional Notes
I reported #136 and already had this fix in hand, so I am submitting it as a concrete reference. I am aware that direct code contributions are not currently being accepted during the public beta, and this touches a fairly deep data-layer class. So, please feel free to close this PR if that process still applies. I hope the diff and the regression tests are useful either way.
Tip
This repository uses Greptile, an AI code review service, to help conduct
pull request reviews. We encourage contributors to read and consider suggestions
made by Greptile, but note that human maintainers will provide the necessary
reviews for merging: Greptile's comments are not a qualitative judgement
of your code, nor is it an indication that the PR will be accepted/rejected.
We encourage the use of emoji reactions to Greptile comments, depending on
their usefulness and accuracy.