Skip to content

Support primitive types with unused bits (Julia 1.14) - #17

Open
AntonOresten wants to merge 1 commit into
mainfrom
unused-bits
Open

AntonOresten wants to merge 1 commit into
mainfrom
unused-bits

Conversation

@AntonOresten

Copy link
Copy Markdown
Member

Julia 1.14 lets a primitive type declare fewer bits than it stores (JuliaLang/julia#61359), e.g. primitive type Float4 4 end, which occupies a byte and has Core.bitsizeof(Float4) == 4. JuliaLang/julia#62852, also in 1.14, rounds sizeof of such types up to their alignment, so a 24-bit primitive now takes 4 bytes.

Changes

  • bitwidth fallback: Core.bitsizeof(T) where it exists (@static if isdefined(Core, :bitsizeof)), else 8 * sizeof(T) as before. These types need no overload, and byte-multiple types like a 24-bit primitive keep their real width; the old fallback reports 32 on 1.14. Bool, Pad, NArray and NarrowTuple keep their own methods.
  • raw_bits(x) / from_raw_bits(T, bits) (new, public): reinterpret rejects these types (bitcast requires equal bit sizes), so these zero-extend and truncate them instead, and fall back to reinterpret for everything else.
  • NArray, NarrowTuple: use the helpers. On 1.14, NVector and NarrowTuple of such types threw.
  • NarrowArray: reinterpret also refuses arrays of these types, so the constructor, copy, T.(narr) and dest .= x route them through raw bits (one temporary). Other types take the same reinterpret path as before. copy now builds concrete SVector{L,T}s instead of map(SArray, …), which keeps it inferable on the new path.

Testing

  • test/unused_bits.jl runs only where Core.bitsizeof exists, covering native 4-, 6- and 24-bit types across the scalar helpers, NVector, NarrowTuple and NarrowArray. It uses @inferred because GPU broadcasts need these to infer (an earlier from_raw_bits.(T, x) with a static parameter T did not).
  • Local: 274/274 tests pass on 1.14.0-alpha1 and nightly; 229/229 on 1.13 and 1.10.
  • GPU (GB10, 1.14, CuArray): construction, copy, T.(narr) and Narrow(T).(d) work for a native 4-bit type, and copy/UInt8.(…) for Bool. I didn't run the opt-in cuTile tests locally; they don't use the changed paths.
  • Codegen for byte-sized types is unchanged: the new condition folds at compile time.

Not in this PR

dest .= cuarray into a GPU-backed NarrowArray throws a kernel exception. It does the same on main with Bool: GPUArrays' copyto! takes over and calls setindex! on the NarrowArray. It needs a method that's aware of GPUArrays, so I left it for a separate change.

🤖 Generated with Claude Code

Julia 1.14 lets a primitive type declare fewer bits than it stores
(`primitive type Float4 4 end`), exposed as `Core.bitsizeof`, and its
`sizeof` now rounds such types up to their alignment (a 24-bit type
takes 4 bytes). `bitwidth` falls back to `Core.bitsizeof` where it
exists, so these types need no overload and byte-multiple types keep
their real width.

`reinterpret` refuses these types, both as scalars and as array or
tuple elements. New public `raw_bits`/`from_raw_bits` widen and
truncate them instead, and `NArray`, `NarrowTuple` and `NarrowArray`
go through them, with `NarrowArray` routing dense arrays of such types
through their raw bits. `copy(::NarrowArray)` now builds concrete
`SVector`s, which keeps it inferable on that path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.25000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.47%. Comparing base (cf69542) to head (54da004).

Files with missing lines Patch % Lines
src/NarrowArray.jl 66.66% 5 Missing ⚠️
src/BitPacking.jl 88.88% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #17      +/-   ##
==========================================
- Coverage   98.44%   97.47%   -0.98%     
==========================================
  Files           7        7              
  Lines         578      593      +15     
==========================================
+ Hits          569      578       +9     
- Misses          9       15       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant