Skip to content

perf: VSX kernels on ppc64le (sum, dot, sqrt, elementwise, 8x8 GEMM) - #20

Merged
tannevaled merged 1 commit into
mainfrom
perf/ppc64le-vsx
Oct 4, 2026
Merged

tannevaled merged 1 commit into
mainfrom
perf/ppc64le-vsx

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Go's ppc64 assembler has the VSX loads, stores and permutes but no vector
double arithmetic, so ppc64le ran the scalar code. go-asmgen v0.13.0 now
encodes xvadddp/xvmaddadp/... as WORDs (pinned against GNU as, run
bit-identical to Go's arithmetic and math.FMA on POWER8 and POWER9); this
uses them for sum, dot, sqrt, add/sub/mul/div and an 8x8 GEMM micro-kernel
(sum_ppc64le.s, generated). max/min stay scalar: xvmaxdp's NaN rule is not
NumPy's.

The GEMM kernel follows OpenBLAS's POWER9 dgemm scheme: no splats; A pairs
and their swaps multiply B column pairs into diagonal/anti-diagonal
accumulators, rebuilt into rows with xxpermdi at the store. Measured in one
binary on a POWER9 core: 13.3 GFLOP/s with lxvdsx splats, 14.8 with
xxpermdi splats, 15.4 unrolled, 16.9 with the diagonal scheme (shipped).

POWER9 (cfarm29), against the scalar code, best of 3-4 interleaved runs:
micro-kernel 8.3 -> 16.2 GFLOP/s; serial GEMM 512^2 7.9 -> 15.8
MatMul 1024^2 (32 threads) 39.2 -> 23.6 ms; 128^2 x1.8; 512^2 x1.5
MatVec x3.1; Sum x3.2-7.3 below 4 Mi; AddInto x2.7-4.1; Sqrt x1.05-1.18
Against OpenBLAS 0.3.34's POWER9 kernel on the same host: serial 0.69x,
32 threads 0.56x.

Tests: the whole suite passes on a real POWER8 and POWER9; replacing
xvsubdp's operand order or the store's xxpermdi selector makes it fail
there. CI regenerates sum_ppc64le.s and fails if it is stale. Docs and
comments that said ppc64le has no SIMD kernel are updated.

🤖 Generated with Claude Code

Go's ppc64 assembler has the VSX loads, stores and permutes but no vector
double arithmetic, so ppc64le ran the scalar code. go-asmgen v0.13.0 now
encodes xvadddp/xvmaddadp/... as WORDs (pinned against GNU as, run
bit-identical to Go's arithmetic and math.FMA on POWER8 and POWER9); this
uses them for sum, dot, sqrt, add/sub/mul/div and an 8x8 GEMM micro-kernel
(sum_ppc64le.s, generated). max/min stay scalar: xvmaxdp's NaN rule is not
NumPy's.

The GEMM kernel follows OpenBLAS's POWER9 dgemm scheme: no splats; A pairs
and their swaps multiply B column pairs into diagonal/anti-diagonal
accumulators, rebuilt into rows with xxpermdi at the store. Measured in one
binary on a POWER9 core: 13.3 GFLOP/s with lxvdsx splats, 14.8 with
xxpermdi splats, 15.4 unrolled, 16.9 with the diagonal scheme (shipped).

POWER9 (cfarm29), against the scalar code, best of 3-4 interleaved runs:
  micro-kernel 8.3 -> 16.2 GFLOP/s; serial GEMM 512^2 7.9 -> 15.8
  MatMul 1024^2 (32 threads) 39.2 -> 23.6 ms; 128^2 x1.8; 512^2 x1.5
  MatVec x3.1; Sum x3.2-7.3 below 4 Mi; AddInto x2.7-4.1; Sqrt x1.05-1.18
Against OpenBLAS 0.3.34's POWER9 kernel on the same host: serial 0.69x,
32 threads 0.56x.

Tests: the whole suite passes on a real POWER8 and POWER9; replacing
xvsubdp's operand order or the store's xxpermdi selector makes it fail
there. CI regenerates sum_ppc64le.s and fails if it is stale. Docs and
comments that said ppc64le has no SIMD kernel are updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit cda7d66 into main Oct 4, 2026
12 checks passed
@tannevaled
tannevaled deleted the perf/ppc64le-vsx branch October 4, 2026 16:19
tannevaled added a commit to go-ndarray/go-ndarray.github.io that referenced this pull request Oct 4, 2026
ndarray v0.2.3 (go-ndarray/ndarray#20) adds VSX SIMD kernels on ppc64le.
The SIMD wording now names amd64, arm64 and ppc64le, ppc64le leaves the
list of targets running the pure-Go reference code, the GEMM blurb lists
the VSX 8x8 micro-kernel next to NEON and AVX2/FMA, and the library card
shows v0.2.3.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
tannevaled added a commit to go-ndarray/docs that referenced this pull request Oct 4, 2026
ndarray v0.2.3 (go-ndarray/ndarray#20) adds VSX SIMD kernels on ppc64le.

- performance.md: re-synced verbatim from docs/perf.md at v0.2.3 (new
  section 'ppc64le: VSX kernels (2026-10-04)' and the SIMD coverage
  update); the summary is now 'Where it stands at v0.2.3', names amd64,
  arm64 and ppc64le and gives the POWER9 GEMM figures from that section.
- index.md: SIMD on amd64, arm64 and ppc64le, worded as the ndarray
  README at v0.2.3 (max/min SIMD on amd64 only, VSX 8x8 micro-kernel).
- roadmap.md: the 'Today (v0.2.1)' sentence and the 'other four
  targets' clause no longer leave ppc64le on scalar code.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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