Conversation
Specialize the RVV QT_fp16 encoder while preserving the generic codec's encoded bytes and rounding behavior. Change the generic encoder from final to override so the RVV specialization can override it. Mirror ryg's scalar scale-and-round conversion with vector mask, scale, clamp, bias, and sign operations. A direct IEEE round-to-nearest-even FP16 conversion differs on halfway cases and would change encoded bytes. Detect NaN and infinity per chunk and fall back to the scalar codec for the entire chunk when either is present. Use e32m4 float lanes, narrow to u16m2, and drive loop bounds with vsetvl to support arbitrary dimensions and runtime vector lengths. Add separate regression tests for finite and non-finite inputs so special-value fallback cannot hide errors in the vector path. Compare encoded bytes against the generic codec and cover ties, subnormals, overflow boundaries, short tails, and output guards. Validate 11,564,775 input elements across all five RISC-V rounding modes with no differing output bytes or write-guard failures. Floating-point exception flags are recorded but not required to match. On a native SG2044 host with VLEN=128, GCC 15.1, and one pinned thread, paired speedups range from 2.01x to 2.70x for public compute_codes calls at dimensions 16, 32, 128, and 768. Measurements compare official commit 80a1656 against that baseline plus this kernel change. These results measure encoding throughput on one host; variability at dimensions 32 and 128 limits per-run conclusions. Co-authored-by: ihb2032 <hebome@foxmail.com> Co-authored-by: lyd1992 <liuyudong@iscas.ac.cn> Co-authored-by: Yuansheng <yuansheng@isrc.iscas.ac.cn>
Xlawy
force-pushed
the
rvv-sq-fp16-encode
branch
from
September 15, 2026 08:57
05d4d2c to
7f38254
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RVV
QT_fp16currently inherits scalar encoding. This adds an RVV encoder while preserving the generic codec's byte representation, including its rounding behavior.The generic codec uses ryg's scale-and-round conversion, whose halfway behavior differs from a direct IEEE round-to-nearest-even FP16 conversion. The vector path mirrors its mask, scale, clamp, bias, and sign operations. Chunks containing NaN or infinity use the scalar codec. The generic encoder becomes overridable so the RVV specialization can provide this implementation.
The new regression tests compare encoded bytes with the generic codec for finite values and, separately, for NaN/Inf inputs. Keeping these corpora separate exercises the vector path without allowing special-value fallback to hide an error. Tests include ties, subnormals, overflow boundaries, short tails, and output guards. This PR is independent of the other RVV encoding/distance changes.
Performance
Measured on a native SG2044 RISC-V host (VLEN=128), GCC 15.1, Release
-O3, dynamic dispatch (FAISS_OPT_LEVEL=dd),rv64gcv_zvfhmin/lp64d, one thread pinned to CPU 2. The baseline is official commit80a16564f86530dbf0bfaf96c2b71feffeb5093f; the candidate is that same baseline plus only this kernel change. These measurements were not collected on the newer PR base2ed4c106e9fb9686e7727e5daf8ad6ad1e164109. The affected scalar-quantizer source files are unchanged between those bases, and the submitted kernel differs from the measured one only in comments/formatting.Geometric mean of the dimension-specific speedups at d=32/128/768: FP16 encode 2.434x.
There are three consecutive sessions, each with four alternating ABBA/BAAB blocks per dimension/path: 48 paired blocks for this candidate. A is the baseline and B is the candidate. Each call is calibrated to at least 0.1 s (the shortest formal call in the full campaign was 0.192 s), with three warm-up batches and
n = max(32, floor(32768/d)). Each block uses the ratio of the two-call geometric mean times. Reported speedup is the median of the three session medians; intervals use 5,000 hierarchical bootstrap resamples, resampling sessions and then blocks within each ABBA/BAAB order stratum. The timing columns are separate medians, so their quotient need not equal the paired speedup. All 48 paired blocks favored this candidate.The timed operation is public
ScalarQuantizer::compute_codes, using fixed-seed (718) finite input batches. FP16 input values arefloat(int(rng()%100000)-50000)/113.f.Variability is material at d=32/128: paired-ratio CV is 13.25%/13.47%, and ABBA-vs-BAAB order gaps are 13.46%/4.80%. The d=32/128/768 geometric mean for the individual sessions is 2.419x, 2.040x, and 2.463x. The aggregate 2.434x should therefore not be interpreted as a stable per-run guarantee.
These results describe public encoding/distance throughput on one non-exclusive host, not end-to-end ANN search speedup. The intervals describe these sessions only, with no multiple-comparison correction; they do not establish portability across machines or vector lengths.
Validation
2ed4c106e9fb9686e7727e5daf8ad6ad1e164109: all three independent candidate builds succeeded; this PR's focused C++ suite (NONE: 11 passed, 6 skipped, 0 failed;RISCV_RVV: 13 passed, 4 skipped, 0 failed) and the public-path oracle above pass on native RISC-V. The newly added RVV regression tests are executed and passed in the RVV run, and skipped when RVV is disabled in the NONE run.git diff --checkclean.Notes
faiss/impl/scalar_quantizer/quantizers.h(one-linefinal→overrideso the generic encoder can be specialized),faiss/impl/scalar_quantizer/sq-rvv.cpp(the RVV encoder), andtests/test_scalar_quantizer.cpp(two regression tests).e32m4float lanes and narrows tou16m2at the end, withvsetvl-driven bounds, so it adapts to the runtime vector length rather than assuming VLEN=128.vmsgeuagainst0x7f800000on the magnitude andvcpop_m; if any lane is special, the whole chunk falls back to the scalar codec. This keeps the vector path free of special-value branching while guaranteeing identical bytes for non-finite inputs.0x1p-112, clamp to the largest finite FP16 exponent field, add0x1000, shift right by 13, re-OR the sign) is deliberately a mirror of ryg's scalar operation rather than an IEEEvcvtFP16 conversion, because the two disagree on halfway cases.Co-authored-by: ihb2032 hebome@foxmail.com
Co-authored-by: lyd1992 liuyudong@iscas.ac.cn
Co-authored-by: Yuansheng yuansheng@isrc.iscas.ac.cn