Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## [Unreleased]

## [0.62.4] - 2026-10-25

Headline: **the arm64 release — the JVM on macOS sends its dense FP32 products to Accelerate, and the native dense
FP32 kernels get register tiles on AArch64** (#1449, #1450, see *Changed*). `JvmBlas` never reached a BLAS (framework
looked up by its bare name, heap arrays passed to a downcall, both failures swallowed); it now resolves `cblas_sgemm`
from `skainet.cpu.blas.library`, the Accelerate framework by path, or the common Linux sonames, and `A · B` on heap or
segment operands and `x · Wᵀ` on a resident dense weight go to it above a small-work floor, on by default on macOS
only. `skainet_fp32_matmul` on AArch64 runs an 8 × 8 tile of lane-indexed FMAs over a packed panel in a 256-deep
k-block and `skainet_fp32_matmul_wt` a four-by-three tile, bit-identical across slices and threads, verified on Apple
silicon by the macOS CI leg; no arm64 numbers were measured for this release.

### Changed

- **Dense FP32 kernels get register tiles on AArch64** (`skainet-backend-native-cpu`, Apple silicon, Android arm64, Linux arm64): the NEON bodies of `skainet_fp32_matmul` and `skainet_fp32_matmul_wt` were the x86 story of a week ago — an outer-product loop that loaded and stored a row of C for every row of A, and a single four-lane chain per `x · Wᵀ` output that left most of a core's FMA pipes idle. The plain SGEMM now runs an 8 × 8 tile in sixteen `float32x4` accumulators with lane-indexed FMAs over a packed 8-column panel of B in a 256-deep k-block (4 × 8 and 1 × 8 tiles for the rows left over, a zero-padded panel and C stripe for the columns left over), and `x · Wᵀ` a tile of four weight rows by three activation rows in twelve chains. Every output takes its fused steps in ascending `p` whichever tile holds it, so sliced, threaded and whole calls stay bit-identical to each other; against the previous NEON numbers an output moves within rounding. Two Kotlin/Native tests run the tails and the block independence through cinterop on every native target, so the macOS CI leg exercises the lane on Apple silicon. No numbers from this change's author: measured on an arm64 host it is not — see the pull request for how to run the bench.
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ authors:
orcid: https://orcid.org/0009-0006-7981-4075
- name: SKaiNET-developers contributors
website: https://github.com/SKaiNET-developers
version: "0.62.3"
version: "0.62.4"
date-released: "2026-10-21"
license: MIT
repository-code: https://github.com/SKaiNET-developers/SKaiNET
Expand Down
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Add the core dependencies (Gradle Kotlin DSL):
```kotlin
dependencies {
// Recommended: import the umbrella BOM and drop versions on the engine modules.
implementation(platform("sk.ainet:skainet-bom:0.62.3"))
implementation(platform("sk.ainet:skainet-bom:0.62.4"))

implementation("sk.ainet.core:skainet-lang-core")
implementation("sk.ainet.core:skainet-backend-cpu")
Expand Down Expand Up @@ -308,7 +308,19 @@ val withoutLabel = dataPipeline<RawDataset>()

---

## What's New in 0.62.3
## What's New in 0.62.4

An arm64 release. On macOS the JVM's dense FP32 products — `A · B` on heap or segment-backed operands and `x · Wᵀ`
on a resident dense weight — now go to Accelerate's SGEMM by default, which runs on the matrix units of Apple
silicon and threads itself; `JvmBlas` had never reached a BLAS before (the framework lookup and the heap downcall
both failed silently), and `-Dskainet.cpu.blas.enabled=false` restores the bundled kernels. Elsewhere the default
stays off and `skainet.cpu.blas.library` names an OpenBLAS or reference BLAS to use. The native dense FP32 kernels
get register tiles on AArch64 (Apple silicon, Android arm64, Linux arm64): an 8 × 8 tile of lane-indexed FMAs over a
packed panel of B for `A · B` and a four-by-three tile for `x · Wᵀ`, bit-identical across slices, threads and whole
calls, exercised on Apple silicon by the macOS CI leg. Both are unmeasured on arm64 in this release; the pull
requests (#1449, #1450) say how to run the bench.

### Carried from 0.62.3

A load-time and kernel release. `StreamingGGUFReader` decodes the GGUF metadata from 64 KB blocks instead of one
source read per value, and `TextFrontEnds.fromGguf` builds a SentencePiece tokenizer in one pass over the vocabulary
Expand Down Expand Up @@ -391,6 +403,11 @@ We love contributions! Whether it's a new operator, documentation, or a bug fix:

Browse the full codebase documentation on [DeepWiki](https://deepwiki.com/SKaiNET-developers/SKaiNET).

### Contributors (0.62.4)

- **Michal Harakal** ([@michalharakal](https://github.com/michalharakal)) — the Accelerate/BLAS routing of the JVM's
dense FP32 products, the AArch64 register tiles for the native dense FP32 kernels with their tests, and the release

### Contributors (0.62.3)

- **Michal Harakal** ([@michalharakal](https://github.com/michalharakal)) — the buffered GGUF metadata reader, the
Expand Down Expand Up @@ -527,7 +544,7 @@ from it). Ready-to-paste BibTeX:
author = {Harakal, Michal and {SKaiNET-developers contributors}},
title = {{SKaiNET}: A {Kotlin} Multiplatform {AI} Framework},
year = {2026},
note = {Version 0.62.3. MIT License},
note = {Version 0.62.4. MIT License},
howpublished = {\url{https://github.com/SKaiNET-developers/SKaiNET}}
}
```
Expand Down
2 changes: 1 addition & 1 deletion docs/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ asciidoc:
framework_name: SKaiNET
# Current SKaiNET release — bump once per release; referenced as
# {skainet_version} in dependency snippets (blocks need subs="attributes+").
skainet_version: 0.62.3
skainet_version: 0.62.4
ksp_version: 2.2.21-2.0.5
dokka_version: 2.1.0
asciidoctorj_version: 3.0.0
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= Kernel × platform support matrix
:description: Which compute-kernel provider serves each weight format on each KMP target.

Generated from `kernel-support.json` (version `0.62.3`) by `KernelSupportMatrixTest` — registry introspection of the registered `KernelProvider` implementations. Do not edit by hand; run `./gradlew generateKernelMatrix` to refresh.
Generated from `kernel-support.json` (version `0.62.4`) by `KernelSupportMatrixTest` — registry introspection of the registered `KernelProvider` implementations. Do not edit by hand; run `./gradlew generateKernelMatrix` to refresh.

Each cell is the best (highest-priority) provider that serves `Float32 × format` `matmul` on that platform: *native-ffm* / *native-jni* / *native-cinterop* (100) → *panama-vector* / *wasm-simd128* (50) → *scalar* (0). An empty cell (`—`) means no provider carries a kernel there (the format is dequant-to-FP32 only). The JS/WASM column assumes `WasmSimd.install()` has run; without the sidecar it is the scalar floor.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= AI-NET Operators Reference

Generated from version `0.62.3` on 2026-10-25
Generated from version `0.62.4` on 2026-10-25

== Operators by Modality

Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/reference/ops-status-matrix.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= Operator Coverage Matrix
:description: Cross-backend status for every operator function in SKaiNET.

Generated from `operators.json` version `0.62.3` on 2026-10-25.
Generated from `operators.json` version `0.62.4` on 2026-10-25.

Rows are `Operator.function` pairs. A gap is marked in source with `@NotImplemented(reason = …, issue = …)` (or `@InProgress`) and shows up here as ❌ (or 🚧) linked to its tracking issue; the PR that closes the gap removes the annotation. See xref:contributing/issue-taxonomy.adoc[Issue taxonomy] to pick one up.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ An Android project with Kotlin. Add the SKaiNET modules:
[source,kotlin]
----
dependencies {
implementation("sk.ainet.core:skainet-lang-core:0.62.3") // tensors, DSL, training
implementation("sk.ainet.core:skainet-backend-cpu:0.62.3") // CPU ops
implementation("sk.ainet.core:skainet-compile-dag:0.62.3") // autograd (training context)
implementation("sk.ainet.core:skainet-data-api:0.62.3") // Dataset / DataBatch
implementation("sk.ainet.core:skainet-data-simple:0.62.3") // embedded Iris
runtimeOnly("sk.ainet.core:skainet-backend-jni-cpu:0.62.3") // NEON kernels (see below)
implementation("sk.ainet.core:skainet-lang-core:0.62.4") // tensors, DSL, training
implementation("sk.ainet.core:skainet-backend-cpu:0.62.4") // CPU ops
implementation("sk.ainet.core:skainet-compile-dag:0.62.4") // autograd (training context)
implementation("sk.ainet.core:skainet-data-api:0.62.4") // Dataset / DataBatch
implementation("sk.ainet.core:skainet-data-simple:0.62.4") // embedded Iris
runtimeOnly("sk.ainet.core:skainet-backend-jni-cpu:0.62.4") // NEON kernels (see below)
}
----

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP=sk.ainet.core
VERSION_NAME=0.62.3
VERSION_NAME=0.62.4
POM_DESCRIPTION=SKaiNET

POM_URL=https://github.com/SKaiNET-developers/skainet/
Expand Down
Loading