Skip to content

F16 coverage: pruning, chunked, Pco, CSV, CLI, Calcite, Parquet (follow-up to #515) - #521

Merged
dfa1 merged 11 commits into
mainfrom
f16-full-coverage
Oct 10, 2026
Merged

dfa1 merged 11 commits into
mainfrom
f16-full-coverage

Conversation

@dfa1

@dfa1 dfa1 commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Follow-up to #515 (merged in #517). After the first fix, I audited F16 end to end: every encoding x data shape x plain/nullable/multi-chunk, read back by the Java reader and by vortex-jni, then every switch that handles F32 but not F16. These are the remaining gaps. Eleven commits, one per fix; please rebase-merge, not squash.

commit fix
5dfb50bd zone-map pruning and columnStats() for F16 (boxedScalar had no Float16Array case, so nothing was ever pruned)
58c7db6d chunked layout/encoding decode F16 (ChunkedFloat16Array)
65db1cc7 CSV export writes F16
d9435345 CLI filter, grid and inspector handle F16
3bbcc6b0 Calcite: F32 columns return Float, so SQL on them runs (existing bug: ClassCastException)
0be3dc55 Calcite: F16 columns are REAL
b2af32eb vortex.pco encodes and decodes F16 (Rust's compact preset)
3ec8914c test: F16 is accepted by every encoder that takes F32, except ALP and ALP-RD (Rust's btrblocks skips both for f16)
9c20c2b4 test: nullable, multi-batch and filtered scans against vortex-jni, both directions
0573f067 a nullable F16 column accepts boxed Short[] like every other primitive
058a0816 Parquet import/export of F16 as FLOAT16

Verification

  • Pco is checked against pco 1.0.1's own output (fixtures from a scratch crate): Java encodes the Classic shapes byte for byte and decodes all five shapes Rust wrote, including FloatQuant. FloatMult is untested: pco never chose it for any half shape I tried.
  • Float16InteropIntegrationTest: 58 cases against vortex-jni 0.86.1 (Java writes / JNI reads, JNI writes / Java reads, nullable, multi-batch, filtered).
  • ./mvnw test and ./mvnw verify -pl integration -am (427 tests, 2 skipped) pass locally.

Not fixed here (filed separately)

Nested F16 inside a Parquet list or struct is still unsupported.

🤖 Generated with Claude Code

dfa1 and others added 11 commits October 10, 2026 17:03
ScanIterator#boxedScalar had no Float16Array case, so an F16 zone-map table decoded to no
min/max at all: a filter on an F16 column read every chunk and VortexReader#columnStats
reported nothing. It now boxes the widened half as a Float, like F32.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
ChunkedArrayCombiner had no F16 case, so a nested chunked layout or a vortex.chunked array of
half-precision values threw 'unsupported ptype for chunked layout'. New ChunkedFloat16Array
concatenates the chunks as raw 16-bit halves, like the other chunked views; the default branch
of the ptype switch is gone, so a new PType fails to compile there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
CsvExporter#cellValue had no Float16Array case and threw 'unsupported array type for CSV export'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
FilterCommand#compareValue threw 'filter not supported for column type' on F16, and the grid and
inspector renderers printed the '<MaterializedFloat16Array ...>' placeholder instead of the value.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
)

VortexEnumerator returned a Double for an F32 column that VortexTable declares REAL, which
Calcite's generated code casts to Float: every SQL query that read such a column failed with a
ClassCastException. The adapter's own test pinned the Double (it read rows without going through
SQL); Float32ColumnSqlTest runs select and where over JDBC.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
VortexTable#toSqlType threw 'unsupported ptype: F16', so a table with a half-precision column
could not be created at all; its rows, SUM and filter literals had no F16 case either. SQL has no
half type, so F16 maps to REAL like F32 and reads as the Float it widens to exactly. The default
branches of those ptype switches are gone, so a new PType fails to compile there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
Rust's compact preset runs Pco on half-precision floats (pco has f16: 16-bit latents ordered like
f32's), but PcoEncodingEncoder rejected F16 and PcoEncodingDecoder threw 'unsupported ptype'.
The latents machinery was already width-generic (I16/U16), so F16 adds the ordered mapping, the
half array and the FloatMult/FloatQuant joins (explicit F16/F32/F64 switches, no default).

PcoF16RustParityTest checks both directions against pco 1.0.1's own output (fixtures dumped by a
scratch crate): Java encodes the Classic shapes byte for byte, and decodes all five shapes, among
them FloatQuant. FloatMult is untested: pco never chose it for a half shape. Float16 round-trip and
vortex-jni interop tests now include forced Pco and the compact cascade. Java's 16-bit delta
binning is far worse than Rust's (2474 vs 192 bytes on a ramp, u16 too); not touched here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
… ALP-RD (#515)

Pins the F16 encoder set to Rust's: btrblocks declines half floats for ALP and ALP-RD only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
…, both directions (#515)

Float16InteropIntegrationTest adds a nullable column written in three chunks (Java writes, JNI
reads) and in three batches (JNI writes, Java reads), and a filtered scan over a sorted column
written by either side: no matching row may be lost, and Java's zone map must prune.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
…mitive (#515)

ChunkImpl#adaptPrimitive took only short[] for F16, so the null-marking boxed form that I8..F64
all accept was rejected as a type mismatch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
ParquetExporter wrote nothing for an F16 column (UnsupportedOperationException) and
ParquetImporter rejected every FIXED_LEN_BYTE_ARRAY. F16 now maps to FIXED_LEN_BYTE_ARRAY(2)
with the Float16Type annotation, the little-endian half; the importer reads only that annotated
form (any other fixed-length byte array stays unsupported), keeps the 16 raw bits so a NaN
payload or -0.0 survives, and handles nullable columns. Nested F16 in a list or struct is still
unsupported.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
@dfa1
dfa1 merged commit 496353a into main Oct 10, 2026
6 checks passed
dfa1 added a commit that referenced this pull request Oct 10, 2026
Eleven one-per-fix lines (#515, #517, #521) become a single F16 entry that lists the commits; the
Calcite F32 fix stays separate, being a different bug.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sko6B2519bE1TkpPx7WKxf
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