feat(tensor): byteConversionAppend — bit-offset packing for mixed-width streams#385
Merged
Conversation
…th streams byteConversion can only start at bit 0 of a byte pointer and leads with a memset, so mixed-width bit-dense streams (delta compression: wide base values + narrow deltas) cannot be appended at non-byte-aligned boundaries. - byteConversionAppend(..., dstStartBit): same loop machinery, out cursor seeded from dstStartBit, no memset; bits outside the written range are preserved, numValues==0 is a safe no-op. - writeByte: OR -> clear-then-set, so the [startbit, endbit) range is fully defined regardless of stale in-range bits. Behavior-identical for all existing callers (every production write lands on memset-zeroed bits). - byteConversion now delegates to byteConversionAppend(..., 0) after its memset (single source of truth for the loop). Co-Authored-By: Claude Fable 5 <[email protected]>
(numValues * dataOutBits - 1) / 8 + 1 underflows to ~SIZE_MAX for an empty stream (and for dataOutBits == 0), turning the leading memset into a crash. Unreachable in-tree today, but one guard away: convertSymTensorToInt32Tensor passes n straight through and N=0 tensors are constructible (#160). - numValues == 0 returns early (no memset: N=0 tensor data may be NULL, #160) - size expression switched to the canonical ceiling idiom (bits + 7) / 8 (identical for bits > 0, safely 0 for dataOutBits == 0) Co-Authored-By: Claude Fable 5 <[email protected]>
LeoBuron
force-pushed
the
feat/byte-conversion-append
branch
from
July 20, 2026 16:34
4d7faa9 to
9de065f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
A student is building delta compression (wide base values + narrow deltas, bit-dense) and hit two limits of the bit-packing layer:
byteConversioncan only start writing at bit 0 of a byte pointer, and its leadingmemsetclobbers previously written bits in a shared byte. Appending mixed-width segments at non-byte-aligned boundaries is therefore impossible today. (In-tree chunked packing is unaffected:elemOffset % 8 == 0keeps every chunk start byte-aligned for any qBits — see the_Static_assertin TensorConversion.c.)Change
byteConversionAppend(dataIn, dataInBits, dataOut, dataOutBits, numValues, dstStartBit)(Tensor.h/Tensor.c): identical loop machinery, out cursor seeded fromdstStartBit, no memset. Bits outside the written range are preserved;numValues == 0is a safe no-op.writeByte: OR → clear-then-set. The[startbit, endbit)range is now fully defined regardless of stale in-range bits, making appends robust on previously written buffers. Behavior-identical for all existing callers — every production write lands on memset-zeroed in-mask bits.byteConversiondelegates tobyteConversionAppend(..., 0)after its memset — single source of truth for the loop.byteConversionwithnumValues == 0used to underflow its memset size(n*bits-1)/8+1to ~SIZE_MAX (crash; one guard away viaconvertSymTensorToInt32Tensor+ tensor: N=0 element allocation has implementation-defined behavior #160 N=0 tensors). Now: early return fornumValues == 0(no memset — N=0 tensor data may be NULL), and the size expression uses the canonical ceiling idiom(bits+7)/8, which is identical forbits > 0and safely 0 fordataOutBits == 0.docs/conventions/tensor.md: zero-fill-on-widen / sign-extend caveat applies to the append entry point too.Verification
dstStartBit%8, ignoredstStartBit/8, unconditional clobber, broken input reseed, skip-zero-fill, restored underflow formula). The skip-zero-fill mutation was surfaced by review and is covered by the widening-into-stale-buffer test.ctest --preset unit_test_debug: 81/81; examples build 395/395;uv run pytest: 29/29.Notes
size_tbit cursor; signed deltas must unpack via theunpackSignExtendidiom; overflow → fit-guard abort per numerics: SYM int16×int16 products overflow int32 in Linear/Matmul/LayerNorm (Conv #45 fixed via int12 operands) #227) is intentionally out of scope.🤖 Generated with Claude Code