Preserve FixedScaleOffset array dimensions - #853
Conversation
|
CI/review follow-up: the four fork workflows (Tests, Wheels, i386, and Code Scanning) are all |
|
I'll have a look today |
|
🤖 AI text below 🤖 Thanks for working on this! I ran a review of the PR (multiple independent review passes, with each finding adversarially verified by executing the code). The core feature unfortunately has some fundamental problems in real storage pipelines, plus a metadata-compatibility break. Details below, roughly in order of severity. Correctness1. Decode silently scrambles F-ordered data after serialization ( With arr = np.arange(24, dtype='<f4').reshape((2, 3, 4), order='F')
enc = codec.encode(arr) # F-contiguous (2,3,4)
out = np.empty((2, 3, 4), '<f4', order='C')
codec.decode(enc, out=out) # correct (np.copyto branch)
codec.decode(enc.tobytes(order='A'), out=out) # scrambled: [0,4,8,...] instead of [0,2,4,...]Any compressor or store between encode and decode produces the second case: 2.
3.
4. Output layout depends on The fast-path guard
5. Minor: 0-d input now yields a scalar — with Design6. The 7. The flag persists an implementation detail into on-disk metadata. The transform is purely elementwise; the flatten exists only to "simplify implementation", and the stored bytes are identical either way. Tests8. The serialized-bytes paths are untested. No 9. Efficiency note: with F-ordered input, encode now returns an F-contiguous chunk where it previously always returned a flat memory-order array; downstream consumers that C-flatten (e.g. Overall: I don't think this should merge in its current form — the feature only functions in the direct in-memory encode→decode case, silently corrupts F-ordered data through any real pipeline, and the unconditional config key breaks reading new data with all existing releases. Happy to discuss the |
ab5a7e3 to
bbc3f4a
Compare
|
Thanks for the thorough review. I reproduced the findings and rewrote the PR at
The PR now states that raw serialized bytes remain 1-D because no shape/order metadata exists; encoded bytes are verified byte-identical to the legacy implementation for C and F inputs. The full locally available suite passes (656 passed, 32 optional-dependency skips), and Ruff check/format are clean. Could you please re-review the revised design when convenient? |
Closes #852.
Summary
FixedScaleOffset, so its elementwise transform preserves the shape needed by downstream codecsndarray_copycentrally so equally shaped arrays retain logical coordinates across C/F memory-order differences, including shaped memoryview destinationsSerialization boundary
Raw serialized bytes do not contain shape or memory-order metadata, so
decode(serialized)remains one-dimensional. The tests make that boundary explicit. When the caller supplies the correctly shaped output buffer, serialized C- and F-ordered data round-trip correctly.The tests also compare the new encoded bytes with the legacy flattened implementation for both C and F inputs; they are byte-identical.
Validation
pytest tests/test_fixedscaleoffset.py tests/test_compat.py -q— 24 passedpytest -q— 656 passed, 32 optional-dependency skipsruff checkon all four changed source/test files — passedruff format --checkon all four changed source/test files — passedgit diff --check— passedChecklist
AI assistance
Codex assisted with test planning and independent review. I reproduced and evaluated each review finding, ran the tests and quality checks, and inspected the final diff.