Skip to content

Low-planes untranspose for u8 pixels - #48

Merged
jonwright merged 5 commits into
mainfrom
u8-lowplanes
Nov 14, 2026
Merged

jonwright merged 5 commits into
mainfrom
u8-lowplanes

Conversation

@jonwright

Copy link
Copy Markdown
Owner

A u8 block's eight bit-planes are what the low-planes values already transpose for u16 blocks below 256, so they now take u8 blocks too and write the values as bytes: the fused list replaces kcb plus the scalar collect on the sparse route and in plain sparsify (the dense route keeps kcb). Each kernel (vbmi, avx2, vsx, c) is instantiated per output type; the u16 vbmi kernel is the same machine code as before. Auto picks a low-planes value for u8 as for u16.

Zen 4, silicon 2162x2068 clipped to u8, one core: sparsify 332 -> 1693 fps as recorded, 397 -> 13617 fps with pixels <= 4 zeroed; with the 1D matrix 296 -> 1094 fps. u16 unchanged.

Coded By Claude

jonwright and others added 5 commits November 13, 2026 21:58
A u8 block's eight bit-planes are what the low-planes values already
transpose for u16 blocks below 256, so they now take u8 blocks too and
write the values as bytes: the fused list replaces kcb plus the scalar
collect on the sparse route and in plain sparsify (the dense route keeps
kcb). Each kernel (vbmi, avx2, vsx, c) is instantiated per output type;
the u16 vbmi kernel is the same machine code as before. Auto picks a
low-planes value for u8 as for u16.

Zen 4, silicon 2162x2068 clipped to u8, one core: sparsify 332 -> 1693
fps as recorded, 397 -> 13617 fps with pixels <= 4 zeroed; with the 1D
matrix 296 -> 1094 fps. u16 unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BSLZ4_ALWAYS_INLINE is __forceinline on MSVC; the portable C collect used
the gcc attribute and broke the MSVC build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
avx512cs (one byte compress for 64 pixels), avx2cs (the lane table, 32
pixels a step), sse2, vsx and neon now take u8 blocks, as they take u16
and u32: the dense route and kcb blocks no longer fall back to the scalar
collect for u8, and auto picks them for u8. Tested against numpy for every
collect value available, u8 now included, at every block size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f collect

Skylake-SP and Cascade Lake have AVX-512 F/BW/VL but neither VBMI/VBMI2 nor
GFNI, so they ran the AVX2 values.  Two new values, appended so that the
existing numbers keep their meaning:

- untranspose lowplanes-avx512bw (u8/u16): the low-planes bit transpose by
  mask loads and masked adds (kcb's avx512bw kernel), 64 pixels at a time,
  with the fused collect skipping empty groups and compressing as dwords;
  also the u16 dense-route block.
- collect avx512f (u8/u16/u32): compare at the pixel width, compress 16
  pixels at a time as dwords and narrow; a scalar loop where a step has at
  most 2 pixels.

BSLZ4_IS_LOWPLANES() replaces the range checks in the driver and registry.
Auto tries them after the VBMI/VBMI2 values and before AVX2.

Cascade Lake (Gold 6248), silicon, fps:
  sparsify          lowplanes-avx512bw  lowplanes-avx2
  u16 as recorded         1180               1013
  u8  as recorded         1045               1091
  u16 zeroed <= 4         7768               5692
  u8  zeroed <= 4        10271               6687
  kcb + collect           avx512f            avx2cs
  u16 / u8 as recorded   622 / 920          555 / 827
  u16 / u8 zeroed       1126 / 3004         931 / 2086

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The VSX fused collect reads each plane 8 bytes at a time but accepted any
block of a multiple of 8 pixels: with ne % 64 != 0 the last word of a plane
ran into the next plane and pixels that are not there were collected.  u8
blocks of 1224 pixels (test_decode_matrix) showed it on POWER9; u16 blocks
of such sizes had the same fault.  Other block sizes now go to the fallback,
as for the VBMI value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jonwright
jonwright merged commit 958fc04 into main Nov 14, 2026
26 checks passed
@jonwright
jonwright deleted the u8-lowplanes branch November 14, 2026 08:35
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