ppc64le: Add POWER8 VSX backend (little- and big-endian)#1258
Open
Scottcjn wants to merge 1 commit into
Open
Conversation
Contributor
|
Thanks @Scottcjn. It's my understanding that a colleague of @bhess also has a ppc backend for mldsa-native which will likely be upstreamed shortly. Preference will likely be given to that backend. Until then I'm happy to keep this PR open. |
Author
|
Standing by. |
First ppc64 native backend for mldsa-native, alongside the existing
aarch64 and x86_64 backends. Selected automatically via MLD_SYS_PPC64LE
/ MLD_SYS_PPC64BE. Replaces poly_caddq, poly_pointwise_montgomery,
polyvecl_pointwise_acc_montgomery (L in {4,5,7}), ntt and intt.
The int32 Montgomery reduction works in the word domain: even/odd
32x32->64 products via vmulesw/vmulosw, m = low32(prod * QINV) via
vmuluwm, then (prod - m*q) >> 32 taken as the high words, recombined
with vmrgow/vmrgew. It relies only on architectural (endian-invariant)
VSX element numbering, so the kernels are bit-exact on both endians with
no code differences.
NTT and inverse NTT use natural coefficient order matching the C
reference. The outer six layers (len >= 4) are vectorized four
coefficients at a time with a per-block broadcast twiddle; the inner two
layers (len = 1, 2) run scalar.
The kernels require POWER8 VSX. On toolchains targeting an older CPU
the meta.h wrappers return MLD_NATIVE_FUNC_FALLBACK so the C reference
is used instead, matching the mlkem-native ppc64le backend. The
big-endian test lane passes -mcpu=power8 explicitly since big-endian
toolchains default to a pre-POWER8 CPU.
dev/ and mldsa/src/native/ppc64le/ are kept in sync by hand: scripts/cfify
does not yet emit CFI for ppc64 and the autogen has no ppc64 simpasm job.
Inner NTT layers use a scalar fallback for now.
Validated on an IBM POWER8 S824 (-mcpu=power8): tests unit matches the C
reference for poly_ntt / poly_invntt_tomont; tests func and tests kat pass
for ML-DSA-44/65/87. Big-endian validated under qemu-ppc64
(powerpc64-linux-gnu, -mcpu=power8): the same unit, func and kat suites
pass with the native backend active.
Signed-off-by: Scott Boudreaux <scottbphone12@gmail.com>
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.
This adds a POWER8 (ppc64) VSX backend to mldsa-native, working on both little- and big-endian POWER. The repository previously had aarch64 and x86_64 native backends; this is the first ppc64 one. It is selected automatically via
MLD_SYS_PPC64LE/MLD_SYS_PPC64BEand replaces:poly_caddq+q(vcmpgtsw/vadduwm/xxsel)poly_pointwise_montgomerypolyvecl_pointwise_acc_montgomery_l{4,5,7}nttinttMontgomery reduction
int32 reduction in the word domain: even/odd 32x32->64 products via
vmulesw/vmulosw,m = low32(prod * QINV)viavmuluwm, then(prod - m*q) >> 32taken as the high words. Low words are recombined withvmrgowand high words withvmrgew, the same even/odd convention on both ends, a closed permutation back to input coefficient order. Because this relies only on the architectural (endian-invariant) VSX element numbering and never on where a load physically places coefficients, the kernels are bit-exact on both endians with no code differences.NTT / inverse NTT
Natural coefficient order, matching the C reference exactly. The outer six layers (len >= 4) are vectorized four coefficients at a time with a per-block broadcast twiddle; the inner two layers (len = 2, 1) have within-vector partners and run scalar. Twiddles stream from a natural-order table (one per block,
kascending for the forward transform, descending + negated for the inverse), so twiddle addressing is a single moving pointer.VSX requirement and fallback
The kernels require POWER8 VSX. The meta.h wrappers guard each call on
__POWER8_VECTOR__and returnMLD_NATIVE_FUNC_FALLBACKotherwise, so a toolchain targeting an older CPU (in particular big-endian defaults) builds and runs correctly through the C reference, matching how the mlkem-native ppc64le backend handles this. The big-endian test lane passes-mcpu=power8explicitly so the backend is actually exercised there.Notes
scripts/cfifydoes not yet emit CFI for ppc64 and the autogen has no ppc64 simpasm job, sodev/andmldsa/src/native/ppc64le/are kept in sync directly. Happy to wire up autogen support as a follow-up.Testing
-mcpu=power8, OPT=1):run_func,run_kat, andrun_unitpass for ML-DSA-44/65/87 with the native backend active (verified via the ppc64le symbols in the test binaries).CC='gcc -mno-vsx', OPT=1): builds, links, and the same suites pass through the C reference, with no ppc64le assembly symbols in the binaries.qemu-ppc64(powerpc64-linux-gnu,-mcpu=power8): the same unit, func, and KAT suites pass with the native backend active.Resubmission of #1191 (closed under the contributor policy before we had been in touch), rebased onto current main and extended with the VSX fallback guards and the big-endian test lane flag.