diff --git a/hugo.toml b/hugo.toml
index c633050..c6479be 100644
--- a/hugo.toml
+++ b/hugo.toml
@@ -1,40 +1,87 @@
baseURL = 'https://go-ndarray.github.io/'
locale = 'en-us'
title = 'go-ndarray'
-# No theme — layouts live in ./layouts
+# No theme -- the layout is the go-* family template go-fft.github.io uses
+# (itself go-authn.github.io's): one self-contained layouts/index.html,
+# partials/styles.html (inline :root tokens, a verbatim copy of go-fft's) and
+# partials/theme-toggle.html (system / light / dark).
-disableKinds = ['taxonomy', 'term', 'rss', 'sitemap']
+disableKinds = ['taxonomy', 'term', 'rss', 'sitemap', '404']
+
+[markup.goldmark.renderer]
+ unsafe = true
[params]
description = "go-ndarray is a pure-Go (CGO=0) NumPy-style n-dimensional array library for float64 — slicing/views, broadcasting, ufuncs, reductions and linear algebra, multicore + SIMD on amd64 and arm64, with a Workspace arena for loops."
- brand = "go-ndarray"
- github = "go-ndarray"
- heroAccent = "go-ndarray"
- heroTagline = "NumPy-style n-dimensional arrays in pure Go. float64, multicore + SIMD."
- heroIntro = [
- "go-ndarray is the numpy equivalent for Go: a float64 n-dimensional array with creation routines, strided views that share data, broadcasting elementwise ops and ufuncs, reductions (incl. arg / cumulative / clip / where), manipulation, and linear algebra (a panel-packed, cache-blocked GEMM) — all in pure Go, with cgo disabled.",
- "Ruby has no cgo-free ndarray (Numo::NArray and NMatrix are C extensions) and gonum's optimized assembly is amd64-only. go-ndarray pairs a portable pure-Go core with multicore fan-out and, on amd64 and arm64, go-asmgen SIMD kernels; a Workspace arena takes the garbage collector out of loops. Measured against NumPy 2.5.3 on a 16-core Zen 3 it is faster on whole-array and row reductions, on Exp from 256 Ki elements and on MatMul against single-threaded OpenBLAS, and slower against 16-thread BLAS. 100% test coverage is the bar, differentially checked against NumPy."
- ]
+# The colours are read by partials/styles.html. Emerald, shared with go-fft:
+# the two are one scientific-computing family, told apart by their glyphs.
+# The values are go-fft's, unchanged.
+[params.brand]
+ base = "#059669" # emerald-600: accent, primary button, gradient start
+ deep = "#047857" # emerald-700: gradient end
+ bright = "#34d399" # emerald-400: accent in dark mode
+ shadow = "rgba(5,150,105,.7)"
+ chipBg = "#d1fae5"
+ chipBorder = "#a7f3d0"
+ chipFg = "#047857"
+ chipBgDark = "rgba(52,211,153,.14)"
+ chipBorderDark = "rgba(52,211,153,.32)"
+ chipFgDark = "#6ee7b7"
+ glow = "rgba(110,231,183,.22)"
+ glow2 = "rgba(5,150,105,.10)"
+ glyphShadow = "rgba(5,150,105,.6)"
+ statsTint = "#a7f3d0"
+ bandFg = "#d1fae5"
+ # White on emerald-600 is 3.77:1, under the 4.5:1 body text needs; the band
+ # paragraph and the primary button sit on this gradient, so it runs one step
+ # darker than the accent: 700 -> 800 (white 5.48:1, #d1fae5 4.84:1 at worst).
+ gradFrom = "#047857"
+ gradTo = "#065f46"
+ # The hero's accent words: emerald-400 -> 300 on the dark background (the
+ # light theme keeps base -> deep, 600 -> 700).
+ gradTextDark = "linear-gradient(135deg,#34d399,#6ee7b7)"
+ [params.brand.surfaces]
+ ink = "#052e22"
+ slate = "#065f46"
+ muted2 = "#047857"
+ line = "#a7f3d0"
+ bg = "#f0fdf9"
+ bgSoft = "#d1fae5"
+ surface = "#ffffff"
+ navBg = "rgba(240,253,249,.82)"
+ navBorder = "#a7f3d0"
+ elevBorder = "#6ee7b7"
+ ghostHover = "#6ee7b7"
+ statsBg = "#052e22"
+ [params.brand.surfacesDark]
+ ink = "#d1fae5"
+ slate = "#a7f3d0"
+ muted2 = "#6ee7b7"
+ line = "#0a3d2a"
+ bg = "#04130d"
+ bgSoft = "#052e22"
+ surface = "#06291c"
+ navBg = "rgba(4,19,13,.82)"
+ navBorder = "#0a3d2a"
+ elevBorder = "#10593d"
+ ghostHover = "#10593d"
+ statsBg = "#06291c"
-[menu]
- [[menu.main]]
- identifier = "why"
- name = "Why"
- url = "#why"
- weight = 10
- [[menu.main]]
- identifier = "repos"
- name = "Repos"
- url = "#repos"
- weight = 20
- [[menu.main]]
- identifier = "quality"
- name = "Quality"
- url = "#quality"
- weight = 30
- [[menu.main]]
- identifier = "docs"
- name = "Docs"
- url = "https://go-ndarray.github.io/docs/"
- weight = 40
+# Each repo. Every field is rendered: "name" in the strip under the hero and on
+# its card, "kind" as the card's tag, "href" as both links, "blurb" in full.
+[[params.repos]]
+ name = "ndarray"
+ kind = "library · v0.2.2"
+ href = "https://github.com/go-ndarray/ndarray"
+ blurb = "The library. Creation (Zeros/Arange/Linspace/…), strided views, broadcasting elementwise + ufuncs, reductions (Sum/Max/ArgMax/CumSum/Clip/Where), manipulation (Reshape/Concatenate/Stack), linalg (MatMul/Dot) via a panel-packed cache-blocked GEMM with a go-asmgen SIMD-FMA micro-kernel (NEON 4×8 on arm64, AVX2/FMA 6×8 on amd64), and a Workspace arena for loops (Use/Reset/Detach)."
+[[params.repos]]
+ name = "docs"
+ kind = "site"
+ href = "https://go-ndarray.github.io/docs/"
+ blurb = "Versioned documentation site (MkDocs Material): API reference, the roadmap, and honest benchmark pages versus NumPy 2.5.3 / OpenBLAS 0.3.34. Source →"
+[[params.repos]]
+ name = "brand"
+ kind = "assets"
+ href = "https://github.com/go-ndarray/brand"
+ blurb = "Logos and icons for the organization, in SVG / PNG / JPG / ICO / ICNS across colour, white and black variants."
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
deleted file mode 100644
index 1f54d98..0000000
--- a/layouts/_default/baseof.html
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
{{ . }}
{{ end }} -{{ . | safeHTML }}
{{ end }} -
- NumPy is the lingua franca of numerical computing, but in Go the choices are
- gonum (matrix-centric, amd64-only assembly) or a C extension. go-ndarray
- brings the n-dimensional array vocabulary — shapes, strided
- views, broadcasting, ufuncs, reductions and linear algebra — to Go with
- no cgo, cross-compiling to a static binary everywhere. The hot paths
- are multicore, and SIMD on amd64 and arm64, so it beats NumPy on
- whole-array and row reductions, large Exp and MatMul against
- single-threaded BLAS; a Workspace arena removes the garbage-collector cost
- of temporaries in loops. It is the cgo-free ndarray the Go and Ruby ecosystems lacked.
-
The library. Creation (Zeros/Arange/Linspace/…), strided views, broadcasting elementwise + ufuncs, reductions (Sum/Max/ArgMax/CumSum/Clip/Where), manipulation (Reshape/Concatenate/Stack), linalg (MatMul/Dot) via a panel-packed cache-blocked GEMM with a go-asmgen SIMD-FMA micro-kernel (NEON 4×8 on arm64, AVX2/FMA 6×8 on amd64), and a Workspace arena for loops (Use/Reset/Detach).
go-ndarray is the numpy equivalent for Go: a float64 n-dimensional array with creation routines, strided views that share data, broadcasting elementwise ops and ufuncs, reductions (incl. arg / cumulative / clip / where), manipulation, and linear algebra (a panel-packed, cache-blocked GEMM) — all in pure Go, with cgo disabled.
Versioned documentation site (MkDocs Material): API reference, the roadmap, and honest benchmark pages versus NumPy 2.5.3 / OpenBLAS 0.3.34. Source →
+ {{/* Lines taken verbatim from the Example section of go-ndarray/ndarray's README at v0.2.2. */}} +import "github.com/go-ndarray/ndarray" + +a, _ := ndarray.Arange(0, 6, 1) // [0 1 2 3 4 5] +m, _ := a.Reshape(2, -1) // -1 inferred -> [[0 1 2] [3 4 5]] + +row, _ := ndarray.FromData([]float64{10, 20, 30}, 3) +sum, _ := m.Add(row) // broadcast (2,3)+(3,) -> (2,3) + +t := m.Transpose() // zero-copy (3,2) view +cols, _ := m.SumAxis(0, false) // sum down each column -> [3 5 7] + +// NumPy basic-indexing views (share data): +col0, _ := m.Slice(ndarray.All(), ndarray.A(0)) // m[:,0] -> [0 3] + +// linear algebra +b, _ := ndarray.Arange(0, 6, 1) +b, _ = b.Reshape(3, 2) +prod, _ := m.MatMul(b) // (2,3)·(3,2) -> (2,2)
Logos and icons for the organization, in SVG / PNG / JPG / ICO / ICNS across colour, white and black variants.
+NumPy is the lingua franca of numerical computing, but in Go the choices are gonum (matrix-centric, amd64-only assembly) or a C extension. go-ndarray brings the n-dimensional array vocabulary — shapes, strided views, broadcasting, ufuncs, reductions and linear algebra — to Go with no cgo, cross-compiling to a static binary everywhere. The hot paths are multicore, and SIMD on amd64 and arm64.
CGO_ENABLED=0 across the org. No cgo, no BLAS shim.
Gated in CI, differentially checked against numpy.
Row-major strided arrays, NumPy broadcasting, and NumPy basic-indexing Slice returning strided views that share data.
Workspace arena for loopsBind the inputs with ws.Use, compute as usual, ws.Reset() at the end of each pass: results stop costing the garbage collector anything. On a Zen 3, x + y on 1 024 elements drops from 2.6 to 0.38 µs (2.1× NumPy).
go-asmgen SIMD kernels on amd64 (SSE2, AVX2/FMA picked at run time) and arm64 (NEON); riscv64, loong64, ppc64le, s390x and the 32-bit targets run the same pure-Go code those kernels are tested against.
Exp/LogPorts of Arm's optimized-routines: worst 0.504 / 0.508 ULP against a 300-bit reference, and correct where Go's amd64 math.Exp returns +Inf (golang/go#81995) and math.Log is wrong on subnormals (golang/go#56600).
The suite runs on amd64, arm64 and 386 natively and on riscv64/loong64/ppc64le/s390x/arm under qemu, on Linux, macOS and Windows, and compiles for every GOOS/GOARCH pair Go supports; v0.2.0 was also run on real amd64, arm64, ppc64le, riscv64 and loong64 hardware.
Ruby has no cgo-free ndarray (Numo::NArray and NMatrix are C extensions) and gonum's optimized assembly is amd64-only. go-ndarray pairs a portable pure-Go core with multicore fan-out and SIMD kernels.
Exp and Log are MIT-licensed ports of Arm's optimized-routines.
CGO_ENABLED=0 across the org. No cgo, no BLAS shim.numpy.Sum/Mean/Max at 4 Mi (2.3–4.5×), SumAxis(1) (2.2×), MaxAxis(1) (1.7×), Exp from 256 Ki elements (2.4–5.6×) and MatMul against single-threaded OpenBLAS (3.7–5.9× from 512²); slower against 16-thread OpenBLAS (MatMul 0.55× at 1024², Dot/mat·vec 0.16×) and on allocating elementwise forms outside a Workspace. In a Workspace, x + y on 1 024 elements drops from 2.6 to 0.38 µs (2.1× NumPy). On Apple silicon the packed GEMM reaches tuned-BLAS parity at 1024² and beats the pure-Go gonum 4–10×.Exp/Log. Ports of Arm's optimized-routines: worst 0.504 / 0.508 ULP against a 300-bit reference, and correct where Go's amd64 math.Exp returns +Inf (golang/go#81995) and math.Log is wrong on subnormals (golang/go#56600).GOOS/GOARCH pair Go supports; v0.2.0 was also run on real amd64, arm64, ppc64le, riscv64 and loong64 hardware.Exp and Log are MIT-licensed ports of Arm's optimized-routines.Sum/Mean/Max at 4 Mi (NumPy 2.5.3, 16-core Zen 3)MatMul from 512² (Zen 3)Exp/Log, ports of Arm's optimized-routinesMeasured, wins and losses. Against NumPy 2.5.3 + OpenBLAS 0.3.34 on a 16-core AMD Zen 3: faster on whole-array Sum/Mean/Max at 4 Mi (2.3–4.5×), SumAxis(1) (2.2×), MaxAxis(1) (1.7×), Exp from 256 Ki elements (2.4–5.6×) and MatMul against single-threaded OpenBLAS (3.7–5.9× from 512²); slower against 16-thread OpenBLAS (MatMul 0.55× at 1024², Dot/mat·vec 0.16×) and on allocating elementwise forms outside a Workspace. On Apple silicon the packed GEMM reaches tuned-BLAS parity at 1024² and beats the pure-Go gonum 4–10×.
{{ .blurb | safeHTML }}
+No cgo, no BLAS shim. A portable pure-Go core, multicore, with SIMD kernels on amd64 and arm64 and a Workspace arena that takes the garbage collector out of loops. Faster than NumPy on whole-array and row reductions, on large Exp and on MatMul against single-threaded BLAS, slower against 16-thread BLAS — the numbers are on the performance page.