Skip to content

RISC-V: return the first occurrence on ties in the RVV index kernels - #6170

Open
HiderX wants to merge 1 commit into
OpenMathLib:developfrom
HiderX:riscv-rvv-index-first-occurrence
Open

HiderX wants to merge 1 commit into
OpenMathLib:developfrom
HiderX:riscv-rvv-index-first-occurrence

Conversation

@HiderX

@HiderX HiderX commented Oct 25, 2026 •

Copy link
Copy Markdown

Summary

The RVV index kernels iamax_rvv.c, iamin_rvv.c, imax_rvv.c,
imin_rvv.c, izamax_rvv.c and izamin_rvv.c do not always return the first
occurrence of the extreme value when that value appears more than once, which
BLAS requires. These kernels are used by RISCV64_ZVL128B and x280.

How the kernels work: each vector lane keeps the index of the first extreme
value it has seen. After the loop, they pick the lowest lane that holds the
overall extreme, using vfirst, and return that lane's index after a
vslidedown. When the extreme value is duplicated, a lower lane can hold a
later index. For example, with n = 65 and equal maxima at positions 21 and 64,
cblas_isamax returns 64.

The patch instead returns the smallest index recorded by the lanes that hold
the extreme value: it sets every other lane to all-ones with vmerge and then
reduces with vredminu. The search loops are unchanged.

Testing

Platform: SpacemiT K3 (X100, VLEN 256), TARGET=RISCV64_ZVL128B, GCC 15.2.

  • Targeted check of i?amax, i?amin, i?max, i?min and of
    icamax/izamax/icamin/izamin
    , 15312 cases in total:

    • S, D, C and Z;
    • strides 1, 2 and 3;
    • 47 lengths from 1 to 32775;
    • the extreme is planted at strip boundaries, in the tail, at a random
      position, or twice (a tie).

    Results:

    • develop (5bab605): 552 mismatches, all ties;
    • patched: 0 mismatches.
  • OpenBLAS tests. The default make goal's tests give identical results
    before and after the patch: utest 141/141, extension tests 1479/1479, and all
    BLAS/CBLAS tests PASSED.

  • Performance is unchanged. ISAMAX/IDAMAX at n = 1024, 32768 and 4M all
    stay within ±0.35 %.

RISCV64_ZVL256B uses the *_vector.c index kernels, which already return the
first occurrence. Its ISMIN/IDMIN bug is fixed separately in #6169.

The i?amax/i?amin/i?max/i?min (and complex icamax/izamax/icamin/izamin) RVV
kernels track, per vector lane, the index of the first extreme value that lane
has seen, and then return the index held by the lowest lane containing the
overall extreme (vfirst + vslidedown). When the extreme value occurs more than
once, the lowest such lane can hold a later index than another lane, so the
kernels did not return the first occurrence as BLAS requires (for example
isamax returned 64 instead of 21 for n = 65 with equal maxima at 21 and 64).

Select the smallest recorded index among the lanes holding the extreme value
instead (vmerge with UINT_MAX + vredminu).

This branch has not been deployed

No deployments
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