From c04c94715fb0b393e76b25d774e511e886f619d5 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sun, 18 Oct 2026 20:53:15 +0200 Subject: [PATCH] docs for ndarray v0.16.0: /docs/0.16/, float32 sum blocks on ppc64le (VSX) - params.ndarray.version v0.16.0 (and baseURL). - sync-mirrors.sh at v0.16.0: performance gains the POWER9 xvaddsp block kernel (-36% / -48%); s390x is what is left. - security.md: the v0.16.0 audit entry for the float32 block kernels. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- content/en/dtypes.md | 2 +- content/en/linalg.md | 4 ++-- content/en/performance.md | 20 ++++++++++++++++---- content/en/random.md | 8 ++++---- content/en/roadmap.md | 4 ++-- content/en/security.md | 13 ++++++++++++- hugo.yaml | 4 ++-- 8 files changed, 40 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index cf94848..24125f0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ describes**: | Source | Published under | | --- | --- | -| branch `main`, with `params.ndarray.version: v0.15.0` in `hugo.yaml` | `https://go-ndarray.github.io/docs//`, here `/docs/0.15/` | +| branch `main`, with `params.ndarray.version: v0.16.0` in `hugo.yaml` | `https://go-ndarray.github.io/docs//`, here `/docs/0.16/` | | the newest version | also `https://go-ndarray.github.io/docs/latest/` | `https://go-ndarray.github.io/docs/` redirects to `latest/`. Each push to diff --git a/content/en/dtypes.md b/content/en/dtypes.md index 3ec7443..1d06728 100644 --- a/content/en/dtypes.md +++ b/content/en/dtypes.md @@ -8,7 +8,7 @@ description: "Why the dtype is a run-time property of one Array type, how arrays tags: [dtypes, numpy] --- -> Mirrored from [`docs/design-dtypes.md`](https://github.com/go-ndarray/ndarray/blob/v0.15.0/docs/design-dtypes.md) at v0.15.0. +> Mirrored from [`docs/design-dtypes.md`](https://github.com/go-ndarray/ndarray/blob/v0.16.0/docs/design-dtypes.md) at v0.16.0. > Status: implemented (Phase 2). Supersedes decision 4 of > [plan-ndarray.md](roadmap.md) ("`float64` first"). diff --git a/content/en/linalg.md b/content/en/linalg.md index 174072f..3ac9328 100644 --- a/content/en/linalg.md +++ b/content/en/linalg.md @@ -8,9 +8,9 @@ description: "Solve, Inv, Det, Cholesky, QR, SVD, Eig and the rest of numpy.lina tags: [linalg, numpy] --- -> Mirrored from [`docs/linalg.md`](https://github.com/go-ndarray/ndarray/blob/v0.15.0/docs/linalg.md) at v0.15.0. +> Mirrored from [`docs/linalg.md`](https://github.com/go-ndarray/ndarray/blob/v0.16.0/docs/linalg.md) at v0.16.0. -Package [`linalg`](https://pkg.go.dev/github.com/go-ndarray/ndarray@v0.15.0/linalg) gives ndarray arrays the functions of +Package [`linalg`](https://pkg.go.dev/github.com/go-ndarray/ndarray@v0.16.0/linalg) gives ndarray arrays the functions of `numpy.linalg`, written in Go without cgo or assembly of its own: the matrix products it relies on are the ndarray package's packed SIMD GEMM. diff --git a/content/en/performance.md b/content/en/performance.md index 3f9822b..52d8dfc 100644 --- a/content/en/performance.md +++ b/content/en/performance.md @@ -948,10 +948,22 @@ accumulators, and was **26–47% slower** than the scalar loop. Every block's addition waited on the previous one, a single dependency chain, where the scalar loop has eight. Two registers give two chains, as SSE2 does on amd64. -Left: ppc64le and s390x run the scalar block loop. Go's assembler lacks -`xvaddsp` (ppc64) and `vfasb` (s390x). go-asmgen/asmgen#27 adds the VSX -single-precision family to go-asmgen's registry, with references from GNU as -and llvm-mc, and needs a cmd/asm patch of its own. +**ppc64le (2026-10-18).** Go's assembler has no `xvaddsp`, so go-asmgen +emits it as a `WORD`. The encoding is pinned against GNU as 2.44 and llvm-mc +on a POWER9 (go-asmgen/asmgen#27). The cmd/asm spelling is +[CL 846285](https://go.dev/cl/846285), and go-asmgen's registry check +assembles every entry with that CL applied. The eight accumulators sit in two +VSX registers, loaded and stored with `LXVW4X`/`STXVW4X`, so every word keeps +its lane. VSX is the ppc64le baseline, so there is no feature check. The kernel +tests passed on the POWER9, and a sabotaged kernel (one `xvsubsp`) failed them. + +| float32 `Sum`, 2¹⁴ / 2²⁰ | change | controls | +|---|---:|---| +| POWER9 (cfarm29) | −36% / −48% | float64, int32 ~ | + +Left: s390x runs the scalar block loop. Go's assembler lacks `vfasb` +(vector-enhancements facility 1, z14), which [CL 846286](https://go.dev/cl/846286) +adds, and go-asmgen's registry has no s390x entries yet to pin its encoding. ## SIMD coverage diff --git a/content/en/random.md b/content/en/random.md index 6ab53ae..8943c99 100644 --- a/content/en/random.md +++ b/content/en/random.md @@ -8,9 +8,9 @@ description: "numpy.random with NumPy's numbers for the same seed: the bit gener tags: [random, numpy] --- -> Mirrored from [`docs/random.md`](https://github.com/go-ndarray/ndarray/blob/v0.15.0/docs/random.md) at v0.15.0. +> Mirrored from [`docs/random.md`](https://github.com/go-ndarray/ndarray/blob/v0.16.0/docs/random.md) at v0.16.0. -Package [`random`](https://pkg.go.dev/github.com/go-ndarray/ndarray@v0.15.0/random) is `numpy.random` over go-ndarray arrays. Its goal +Package [`random`](https://pkg.go.dev/github.com/go-ndarray/ndarray@v0.16.0/random) is `numpy.random` over go-ndarray arrays. Its goal is migration: a notebook moved from NumPy to Go keeps its numbers for the same seed. @@ -24,7 +24,7 @@ u, _ := random.Rand(3) // np.random.rand(3) ``` `Example`, `ExampleSeed` and `ExampleGenerator_ChoiceN` in -[`example_test.go`](https://github.com/go-ndarray/ndarray/blob/v0.15.0/random/example_test.go) print NumPy's own numbers. +[`example_test.go`](https://github.com/go-ndarray/ndarray/blob/v0.16.0/random/example_test.go) print NumPy's own numbers. ## What is implemented @@ -118,7 +118,7 @@ random arguments. Used as-is, that made 3% of `np.random.randn` values and 10% of `lognormal` values one ULP off. So `random` rounds `log`, `log1p`, `exp`, `expm1` and `pow` **correctly** -([`libm.go`](https://github.com/go-ndarray/ndarray/blob/v0.15.0/random/libm.go)): a fast evaluation to about 2⁻⁶⁸ with Ziv's +([`libm.go`](https://github.com/go-ndarray/ndarray/blob/v0.16.0/random/libm.go)): a fast evaluation to about 2⁻⁶⁸ with Ziv's rounding test, and a double-double fallback (about 2⁻¹⁰⁰) for the one argument in ~2¹⁵ that needs it. Checked against mpmath at 300 bits on 63,000 arguments (0 misrounded; the committed `libm.json` keeps 8,400), and the fast paths diff --git a/content/en/roadmap.md b/content/en/roadmap.md index 543fc28..9d6862c 100644 --- a/content/en/roadmap.md +++ b/content/en/roadmap.md @@ -8,7 +8,7 @@ description: "The plan for go-ndarray and what ships today." tags: [roadmap] --- -> Mirrored from [`docs/plan-ndarray.md`](https://github.com/go-ndarray/ndarray/blob/v0.15.0/docs/plan-ndarray.md) at v0.15.0. +> Mirrored from [`docs/plan-ndarray.md`](https://github.com/go-ndarray/ndarray/blob/v0.16.0/docs/plan-ndarray.md) at v0.16.0. > Goal: a **pure-Go (CGO=0)** NumPy-style N-dimensional array library, as a > **standalone, reusable** module with correct scalar kernels now and a clean @@ -112,7 +112,7 @@ suite (plus the per-arch CI jobs already wired in `.github/workflows/ci.yml`). - **Performance — DONE (beats NumPy on its core ops; matmul at tuned-BLAS parity).** Several levers behind the kernel seam, measured honestly vs NumPy 2.2.4 (see [docs/perf.md](performance.md) and the repo's - [BENCHMARKS.md](https://github.com/go-ndarray/ndarray/blob/v0.15.0/BENCHMARKS.md)): + [BENCHMARKS.md](https://github.com/go-ndarray/ndarray/blob/v0.16.0/BENCHMARKS.md)): - **Multicore.** `Add/Sub/Mul/Div/Map`, `Sum/Max/Min`, the axis reductions, `Concatenate`/`Stack`, and the GEMM fan out across `GOMAXPROCS` above a size threshold (small arrays stay serial). Plus an allocation fix: the diff --git a/content/en/security.md b/content/en/security.md index c04c8ff..e034ee7 100644 --- a/content/en/security.md +++ b/content/en/security.md @@ -8,7 +8,7 @@ description: "How to report a vulnerability, what the library guarantees, and th tags: [security] --- -> Mirrored from [`SECURITY.md`](https://github.com/go-ndarray/ndarray/blob/main/SECURITY.md) at v0.15.0. +> Mirrored from [`SECURITY.md`](https://github.com/go-ndarray/ndarray/blob/main/SECURITY.md) at v0.16.0. ## Reporting @@ -76,6 +76,17 @@ standard library's known vulnerabilities; `govulncheck ./...` reports none. ## Audit log +**2026-10-18 (v0.16.0).** The float32 pairwise-sum block kernels (SSE2, NEON, +RVV, LSX since v0.14.0/v0.15.0, VSX now) take raw pointers and a block count. +`AddBlocks8F32` refuses a length that is not a positive multiple of 8, and +each wrapper touches the last element before the call, so a kernel never sees +a count its operand cannot hold. `TestBlocks8StaysInsideItsOperands` puts the +accumulators and the input against PROT_NONE pages, and it passes on real +hardware for each kernel: Zen 3, Neoverse N1, SpacemiT X60, Loongson +3C5000L and POWER9. The ppc64le kernel's `xvaddsp` is a `WORD` whose encoding +go-asmgen pins against GNU as and llvm-mc. A sabotaged one (`xvsubsp`) failed +the bit-identity test on the POWER9. + **2026-10-17 (after v0.12.0, tests only).** v0.10.0 added thirteen dtypes, and `FuzzOps` builds only float64 arrays; `values.json` checks every operation on operands of one dtype, so the values of a mixed-dtype operation diff --git a/hugo.yaml b/hugo.yaml index 8963f67..c697015 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -6,7 +6,7 @@ # have used since the site was built with MkDocs and mike. The CI sets it # through --baseURL, from params.ndarray.version below. This default is the # same build. -baseURL: "https://go-ndarray.github.io/docs/0.15/" +baseURL: "https://go-ndarray.github.io/docs/0.16/" title: "go-ndarray" # themes/hextra is the tannevaled/hextra fork, pinned at a release tag: # upstream Hextra plus opt-in features (partial menu items, combos, @@ -97,7 +97,7 @@ params: # The ndarray release these pages describe. Its minor version is the # documentation's version label (v0.9.1 -> 0.9): the CI reads it here. ndarray: - version: "v0.15.0" + version: "v0.16.0" navbar: displayTitle: true