Skip to content

Add Iguana container + LZ77 layer to hwy/contrib/iguana - #3342

Open
tvost2 wants to merge 2 commits into
google:masterfrom
tvost2:feat/iguana-full
Open

Add Iguana container + LZ77 layer to hwy/contrib/iguana#3342
tvost2 wants to merge 2 commits into
google:masterfrom
tvost2:feat/iguana-full

Conversation

@tvost2

@tvost2 tvost2 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Completes the Iguana op_wishlist.md item: the container + LZ77 layer on
top of the ANS32 entropy stage from #3341, so hwy/contrib/iguana/ is now a
working portable Iguana codec (github.com/SnellerInc/sneller, ion/zion/iguana).

Stacked on #3341 — review that one first; the diff here is only the new
iguana.{h,cc} / iguana-inl.h / iguana_test.cc.

Ported from the pure-Go reference (decoder.go, encoder.go, stream.go,
recovered via the Go module proxy). Bitstream-compatible with it.

What's here

file contents
iguana.h / iguana.cc the container format (backward control varints, CopyRaw / DecodeIguana / DecodeANS32 commands), the LZ77 stage (DecompressIguanaLZ: token loop + overlap-aware wild copy), and the scalar encoder — a Lizard-style hash-chain match finder (kChainBits, kHashBytes, kHistSize) with the reference's repeat-offset and end-of-buffer handling. DecompressScalar ties it together.
iguana-inl.h Decompress — the same container loop, but each entropy-coded stream goes through the SIMD ANS32 decoder from #3341 (iguana_ans::Ans32Decode). The container parsing and LZ token loop are inherently serial, so they stay in the target-independent helpers. Output is identical to DecompressScalar.
iguana_test.cc round-trips a range of sizes and data models (random / skewed / repetitive text / RLE), the >64 KiB far-offset (24-bit) path, and a re-sliced short string (raw-copy fallback); cross-checks the SIMD path against the scalar reference.

Covers the EncodingIguana / EntropyANS32 pipeline that Encoder.Compress
produces. ANS1 / ANS_nibble stream modes are declared-but-rejected (small
scalar coders; a follow-up).

Validation

  • iguana_test passes on AVX3 / AVX2 / SSE4 / SSSE3 / SSE2 / EMU128 locally.
  • A standalone C++ port of the Go reference (built separately) round-trips
    every test case, including the far-offset path; the encoder here produces the
    same block and both decoders reproduce the input.
  • Strict -Werror (-Wconversion -Wsign-conversion -Wshadow -Wcast-align …)
    and clang-format are clean.

Follow-ups

The LZ wild copy could use wide Highway loads/stores for non-overlapping
matches; ANS1 / ANS_nibble; a HWY_DYNAMIC_DISPATCH entry point.

First step of the "Iguana" op_wishlist item: a Highway port of Iguana's
ANS32 entropy stage - the 32-way interleaved rANS coder that is the
"decompress at 10+ GB/s" core of that compressor (github.com/SnellerInc/
sneller, ion/zion/iguana). Ported from the pure-Go reference (ans32.go,
ans_statistics.go); the bitstream is byte-for-byte compatible.

- ans.h/.cc: the frequency model (histogram + normalization, incl. the
  empty-input and single-symbol edge cases), dense-table (de)serialization,
  the scalar ANS32 encoder, and a scalar reference decoder.
- ans-inl.h: SIMD Ans32Decode. Each round gathers 32 dense-table entries,
  does one Mul/Add, and renormalizes the lanes that fell below 2^16 by
  pulling one 16-bit word each from the two ends of the payload, vectorized
  with Expand (+ Reverse for the backward half). CappedTag<uint32_t, 16>,
  so 4/8/16 lanes per group. HWY_SCALAR and the scalable targets fall back
  to the scalar reference, which produces identical output.
- ans_test.cc: round-trips a range of sizes and models and cross-checks the
  SIMD decoder against the scalar reference.

Passes on AVX3/AVX2/SSE4/SSSE3/SSE2/EMU128 locally; strict -Werror and
clang-format are clean.

Iguana's LZ77 layer, ANS1/ANS_nibble, and a fully-vectorized tail are
follow-ups.
Completes the "Iguana" op_wishlist item on top of the ANS32 entropy stage:
hwy/contrib/iguana/ is now a working portable Iguana codec
(github.com/SnellerInc/sneller). Ported from the pure-Go reference; the
bitstream is compatible with it.

- iguana.h/.cc: the container format (backward control varints; CopyRaw /
  DecodeIguana / DecodeANS32 commands), the LZ77 stage (token loop +
  overlap-aware wild copy), and the scalar encoder - a Lizard-style
  hash-chain match finder with the reference's repeat-offset and
  end-of-buffer handling. DecompressScalar ties it together.
- iguana-inl.h: Decompress - the same container loop, but each entropy-
  coded stream is routed through the SIMD ANS32 decoder. The container
  parsing and LZ token loop are inherently serial, so they stay in the
  target-independent helpers. Output matches DecompressScalar.
- iguana_test.cc: round-trips a range of sizes and data models, the
  >64 KiB far-offset path, and a re-sliced short string; cross-checks the
  SIMD path against the scalar reference.

Covers the EncodingIguana / EntropyANS32 pipeline. ANS1 / ANS_nibble
stream modes and a vectorized wild copy are follow-ups.

Passes on AVX3/AVX2/SSE4/SSSE3/SSE2/EMU128 locally; strict -Werror and
clang-format are clean.
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