Skip to content

Vectorize direct 8-bit scalar-quantizer encoding with RVV - #5604

Open
lyd1992 wants to merge 1 commit into
facebookresearch:mainfrom
lyd1992:rvv-sq-u8-encode-20260907
Open

Vectorize direct 8-bit scalar-quantizer encoding with RVV#5604
lyd1992 wants to merge 1 commit into
facebookresearch:mainfrom
lyd1992:rvv-sq-u8-encode-20260907

Conversation

@lyd1992

@lyd1992 lyd1992 commented Sep 7, 2026

Copy link
Copy Markdown

RVV QT_8bit_direct currently inherits scalar encoding. This adds an RVV encoder using e32m4, explicit round-toward-zero float-to-unsigned conversion, and two narrowing operations before storing bytes.

The generic encoder becomes overridable so the RVV specialization can provide the implementation. The portable scalar conversion domain is finite inputs in (-1, 256), whose truncated values are representable in uint8_t; negative fractions greater than -1 produce zero. The new regression test covers that domain, including signed zero, subnormals, values around integer boundaries, the largest float below 256, short tails, and output guards. This PR is independent of the FP16 and direct-signed-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 commit 80a16564f86530dbf0bfaf96c2b71feffeb5093f; the candidate is that same baseline plus only this kernel change. These measurements were not collected on the newer PR base 2ed4c106e9fb9686e7727e5daf8ad6ad1e164109. The affected scalar-quantizer source files are unchanged between those bases, and the submitted kernel differs from the measured one only in comments/formatting.

Public path Dimension Baseline ns/element Candidate ns/element Paired speedup 95% interval
Direct-u8 encode 16 1.839 1.345 1.366x [1.343, 1.379]
Direct-u8 encode 32 1.839 1.061 1.750x [1.690, 1.775]
Direct-u8 encode 128 1.640 0.823 1.937x [1.901, 1.992]
Direct-u8 encode 768 1.530 0.740 2.059x [1.883, 2.105]

Geometric mean of the dimension-specific speedups at d=32/128/768: Direct-u8 encode 1.911x.

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. Direct-u8 input values are float(rng()%16777216)/65536.f.

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

  • Native public encoding oracle: 7,724,670 legal-domain input elements across the five RISC-V rounding modes; zero differing output bytes or write-guard failures. Inputs include negative fractions, signed zeros, subnormals, all byte-value boundaries, and values just below 256.
  • Original benchmark baseline full C++ suite: 273 passed, 7 skipped, 0 failed.
  • Submission version on 2ed4c106e9fb9686e7727e5daf8ad6ad1e164109: all three independent candidate builds succeeded; this PR's focused C++ suite (NONE: 11 passed, 5 skipped, 0 failed; RISCV_RVV: 12 passed, 4 skipped, 0 failed) and the public-path oracle above pass on native RISC-V. The newly added RVV regression test is executed and passed in the RVV run, and skipped when RVV is disabled in the NONE run.
  • All touched C++ files pass clang-format 21.1.8; git diff --check clean.

Co-authored-by: ww8191201-coder <wanghongyan2025@iscas.ac.cn>
Co-authored-by: ihb2032 <hebome@foxmail.com>
Co-authored-by: YuanSheng <yuansheng@isrc.iscas.ac.cn>
@meta-cla

meta-cla Bot commented Sep 7, 2026

Copy link
Copy Markdown

Hi @lyd1992!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@meta-cla

meta-cla Bot commented Sep 7, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla Bot added the CLA Signed label Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant