Skip to content

Commit 3b38586

Browse files
michalharakalclaude
andcommitted
release: 0.34.0 — URI data sources, bf16 StableHLO export, NEON K-quant 2.07×
Bumps VERSION_NAME 0.33.0 -> 0.34.0. Bundles the develop changes since 0.33.0: the new skainet-data-source module (URI-backed sources, HF auth, raw format parsers, suspend data pipeline DSL) + dataset operation views and richer batches (#784/#785), the bf16-native DSL -> StableHLO export path and the pluggable per-phase/per-target compile-optimization seam (#788/#791), NEON K-quant matmul perf (block-outer order + fused Q8 int8 dot, 2.07x Q4_K on Cortex-A55) with aarch64 board verification (#786/#787), LayerNorm f32 normalization + rank-0 tensor-type emission fixes, macOS host build fix (#789), Code of Conduct (#790), and the offline markup-antora docs image (#781). Minor bump (not patch): new published module skainet-data-source; all data-api additions are default-bearing (no source-incompatible changes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent c92d587 commit 3b38586

3 files changed

Lines changed: 97 additions & 76 deletions

File tree

CHANGELOG.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,91 @@
22

33
## [Unreleased]
44

5+
## [0.34.0] - 2026-07-05
6+
7+
### Added
8+
9+
- **New module `sk.ainet.core:skainet-data-source` — URI-backed data sources.** One declarative way to
10+
get raw data into SKaiNET from `file://`, `https://`, and Hugging Face (`hf://owner/repo/path` and
11+
`hf+https://…`) URIs: `DataSource` contracts + `DataSourceUriParser`, a `DefaultDataSourceResolver`
12+
(JVM: `JvmDataSourceResolver` with artifact materialization/caching via `CachePolicy`), streaming of
13+
source artifacts with kotlinx-io, and parameterizable Hugging Face auth (token provider — no
14+
hard-coded credentials). (PRs #784, #785)
15+
- **Raw dataset parsers + suspendable data pipeline DSL.** `DataFormatParser` implementations for CSV,
16+
TSV, JSON arrays/objects, and JSON Lines (`.jsonl` / `.ndjson`) produce schema-carrying `RawDataset`s;
17+
`rawDataset { from(…); format(…); cachePolicy(…) }` builds a dataset straight from a source URI, and
18+
`dataPipeline<T>()` chains named, schema-aware `dataTransformer` stages as a suspend pipeline.
19+
See the new [data sources getting-started tutorial](docs/modules/ROOT/pages/tutorials/data-sources-getting-started.adoc). (PR #785)
20+
- **Dataset operation views and richer batches (`skainet-data-api`).** `Dataset` gains deterministic
21+
seeded `shuffle(seed)`, `split(ratio, seed, stratified)` (label-stratified splitting), `filter` /
22+
index-based views, optional `inputShape`/`outputShape` metadata, and batch/epoch `Flow`s. `DataBatch`
23+
now carries sample `indices` and a `metadata` map, and supports `slice(range)` over the leading batch
24+
dimension. All additions have defaults — existing `Dataset` implementations keep compiling; the bundled
25+
MNIST / Fashion-MNIST / CIFAR-10 loaders support indexed (non-contiguous) batches, are routed through
26+
the source layer, and unsupported platform targets now fail with a clear
27+
`DatasetLoaderUnsupportedTargetException`. (PR #785)
28+
- **bf16-native DSL → StableHLO export path.** A model authored in bf16 in the NN DSL now exports
29+
StableHLO whose weights reach the matmuls as bf16 (required by NPUs that reject fp32 weights). Adds
30+
`DtypeForwardPropagationPass` (unifies the graph's float dtype end-to-end, coercing float sources when
31+
`targetFloatDtype` is set), a width-matched `-inf` bit pattern for softmax/attention max-reduce
32+
identities, valid `stablehlo.convert` function-form emission, and BF16 support in
33+
`DenseTensorDataFactory.zeros/placeholder`. Verified: a DSL-authored bf16 Moonshine encoder traces to
34+
all-bf16 StableHLO and compiles to an aarch64 llvm-cpu vmfb. (PRs #788, #791)
35+
- **Pluggable per-phase, per-target compile optimization (`skainet-compile-opt`).** The seam that keeps
36+
hardware knowledge out of the agnostic compiler core: `CompilePhase { TAPE, DAG, STABLE_HLO }`,
37+
`TargetOptimizer` (per-phase pass provider), the `TargetOptimizers` registry, and
38+
`dagPipelineFor(target, corePasses)`. The StableHLO emitter additionally accepts an optional target id
39+
and `OpGranularityPolicy` (+ `FusedOpAllowList`) so per-target fused-vs-decomposed emission decisions
40+
are possible; everything defaults to the previous behavior — emission is byte-identical when unused. (PR #791)
41+
- **`KernelProfile` diagnostics (`skainet-backend-cpu`).** Always-on accumulating profiler over the three
42+
`DefaultCpuOps.matmul` dispatch paths (quant-NEON / fp32-scalar / generic), read via
43+
`KernelProfile.report()` — used to localize on-device decode cost.
44+
- **Contributor Covenant 3.0 Code of Conduct**, with GitHub private vulnerability reporting as the
45+
contact channel. (PR #790)
46+
47+
### Performance
48+
49+
- **Native CPU K-quant matmul: 2.07× Q4_K on Cortex-A55.** Two levers, validated against the Panama
50+
reference and on-board: (1) block-outer / output-row-inner loop order so block-major weight bytes are
51+
read strictly sequentially (the dominant win on in-order cores — the old order made every weight read
52+
a cold cache miss), applied to Q4_K, Q5_K, Q6_K, and Q8_0; (2) ggml-style fused Q8 activation
53+
quantization + int8 dot path (`vdotq_s32` on dotprod targets, scalar fallback otherwise) for Q4_K and
54+
Q6_K. TinyLlama Q4_K_M on-board decode improved 1.50× end-to-end. Note: the fused int8 path is
55+
deliberately lossy (activation quantization, ~1–3% worst-case on uniform-random fixtures); parity
56+
tests gate on aggregate `RMS(error)/RMS(signal) < 0.03` instead of bit-exactness. (PR #787)
57+
- **NEON kernels verified on real aarch64.** Shared `nativeTest` suite now runs the matmul parity tests
58+
on linuxX64 and linuxArm64 (cross-built binary under the bundled qemu-aarch64, overridable to a real
59+
board); all fp32/q4k/q5k/q6k/q8_0 kernels pass on QEMU and on a physical Cortex-A55, with objdump
60+
confirming genuine SIMD (`udot`/`sdot`/`fmla`), not the scalar fallback. (PR #786)
61+
62+
### Fixed
63+
64+
- **LayerNorm normalization computed in f32 regardless of model dtype.** A bf16 variance (sum of many
65+
bf16 squares) loses enough precision that `sqrt(var + eps)` can produce NaN, and some accelerator
66+
backends miscompile the low-precision decomposed reduce. Mean/variance/std/divide are now upcast to
67+
f32 (standard PyTorch/JAX practice); the gamma/beta affine stays in the model dtype. No-op for f32
68+
models. (PR #791)
69+
- **Rank-0 tensor types emit as `tensor<elem>`.** The StableHLO type mapper unconditionally inserted the
70+
`x` shape separator, so scalars produced the malformed `tensor<xbf16>` that `iree-compile` rejects. (PR #791)
71+
- **Green `./gradlew build` on macOS hosts.** Refreshed lagging binary-compatibility API dumps (additive
72+
only) and gated the linuxX64/linuxArm64 Kotlin/Native test-link/run tasks off non-Linux hosts (the
73+
CMake host build emits Mach-O objects that cannot cross-link into a Linux ELF); klib compilation and
74+
publishing untouched, the native NEON parity suite still runs on Linux CI / QEMU / hardware. (PR #789)
75+
76+
### Docs
77+
78+
- **Antora docs image consolidated to the offline `markup-antora` build.** One image shared across the
79+
SKaiNET docs projects: offline Mermaid rendering to inline SVG at build time (no Kroki, no network),
80+
content-hash diagram caching, rootless-safe, with a build-time Mermaid smoke test. (PR #781)
81+
- Data source URIs and the data loader APIs documented, including a new
82+
`data-sources-getting-started` tutorial; README reworked to frame StableHLO/MLIR as one of several
83+
sibling code-generation backends (next to Arduino/C99 and Minerva) lowering the same `ComputeGraph`. (PR #776)
84+
85+
### Dependencies
86+
87+
- Gradle wrapper 9.6.0 → 9.6.1, logback-classic 1.5.36 → 1.5.37, JUnit Jupiter 6.1.0 → 6.1.1,
88+
kotlinx-io-core 0.9.0 → 0.9.1. (PRs #777#780)
89+
590
## [0.33.0] - 2026-06-29
691

792
### Added

README.md

Lines changed: 11 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Add the core dependencies (Gradle Kotlin DSL):
3636
```kotlin
3737
dependencies {
3838
// Recommended: import the umbrella BOM and drop versions on the engine modules.
39-
implementation(platform("sk.ainet:skainet-bom:0.33.0"))
39+
implementation(platform("sk.ainet:skainet-bom:0.34.0"))
4040

4141
implementation("sk.ainet.core:skainet-lang-core")
4242
implementation("sk.ainet.core:skainet-backend-cpu")
@@ -254,6 +254,7 @@ val withoutLabel = dataPipeline<RawDataset>()
254254
.execute(raw)
255255
```
256256

257+
- Start with the [data sources getting started guide](docs/modules/ROOT/pages/tutorials/data-sources-getting-started.adoc)
257258

258259
### Edge AI: Arduino / C99 Export
259260

@@ -280,80 +281,15 @@ val withoutLabel = dataPipeline<RawDataset>()
280281

281282
---
282283

283-
## What's New in 0.33.0
284-
285-
- **GRU — the first recurrent layer.** `nn.Gru` (`[B,S,D]->[B,S,H]`, PyTorch gate order) composed from
286-
existing primitives and unrolled over the static sequence at trace time, so it runs eagerly, trains
287-
through the standard tape, and exports to StableHLO with no dedicated converter. Plus a `gru(…)`
288-
network-DSL builder. (PR #772, issue #217)
289-
- **`upsample2d` Bilinear + StableHLO export** for both Nearest and Bilinear — everything lowers to fixed
290-
reshape/broadcast/`dot_general` (no `custom_call`), unblocking resize/FPN-style export. (PR #771)
291-
- **Autodiff correctness + coverage.** Fixes a silent gradient-drop for `elu`/`leakyRelu`/`permute`
292-
(backward rules existed but were never wired into the trace dispatch), makes `cos`/`sin`/`tril`/
293-
`gather`/`indexSelect`/`unfold`/`convTranspose1d` differentiable, and adds a KSP-generated coverage
294-
guard so a differentiable op can no longer ship without a wired backward. (PR #774)
295-
- **Norms compile on stock IREE.** `layerNorm`/`rmsNorm`/`batchNorm` now lower to real `stablehlo.reduce`
296-
instead of export-only `custom_call`s. (PR #769)
297-
- **Breaking:** `TensorOps.sin`/`cos`/`convTranspose1d` are now abstract — backends implementing
298-
`TensorOps` directly must override them (both bundled backends already do).
299-
300-
## What's New in 0.32.4
301-
302-
- **Streaming detokenization keeps word spaces (`Tokenizer.decodeToken`).** Decoding generated tokens
303-
one at a time no longer runs words together (`"the process"``"theprocess"`). The new
304-
`decodeToken(id)` keeps each SentencePiece piece's leading space (llama.cpp `token_to_piece`
305-
semantics); `decode(IntArray)` still strips the single sequence-leading space as before.
306-
307-
## What's New in 0.32.3
308-
309-
- **Graph-output pruning for export (`ComputeGraph.prunedToOutputs`).** Trims a traced decoder's
310-
StableHLO/IREE export to just the designated outputs (e.g. the logits), eliminating the dozens of
311-
dangling per-layer tensors and dead op subgraphs a full trace otherwise emits as `func` returns —
312-
via new `OutputDesignatedGraph` (compile-dag) + `prunedToOutputs` (compile-opt) running
313-
`DeadCodeEliminationPass`. (PR #760)
314-
- **SDPA causal mask** now emits a large finite fill (`-1e30`) instead of `-inf`, matching
315-
`buildSlidingCausalMask` and avoiding a `-inf` splat in the exported IR (numerically equivalent
316-
after softmax). (`AttentionOperationsConverter`)
317-
318-
## What's New in 0.32.2
319-
320-
- **`ExecutionContext.isRecording`.** A default-`false` flag (overridden by the graph/tape context)
321-
so a module with an eager fast-path that bypasses `ops.*` — e.g. RoPE's raw-array INTERLEAVED
322-
rotation — can detect tracing and emit a graph-traceable `ctx.ops.*` path instead, exporting to
323-
StableHLO while keeping the eager fast path. Backward-compatible. (PR #757)
324-
- **Docs:** Antora version-currency + broken-link fixes across all pages (PR #758).
325-
- **Dependency:** `ch.qos.logback:logback-classic` → 1.5.35 (#756).
326-
327-
## What's New in 0.32.1
328-
329-
- **GroupNorm compiles on stock IREE.** The 0.32.0 GroupNorm converter emitted `@reduce_mean` /
330-
`@reduce_variance` custom_calls that `iree-compile` can't lower; it now emits real `stablehlo.reduce`
331-
(variance as `E[x²] − E[x]²`, ddof=0), like `sum` / `mean` / `variance`. Verified end-to-end through
332-
the [`skainet-iree-conformance`](https://github.com/SKaiNET-developers/skainet-iree-conformance) harness
333-
(`iree-compile` + `iree-run-module` + numpy validate → PASS, `max_abs_err = 1.2e-7`). (PR #754)
334-
335-
### Recent releases
336-
337-
- **0.32.0****GroupNorm StableHLO converter** (#752): `groupNorm` lowers to real `stablehlo.*` ops; plus a SKEEP proposals docs module (#750), a quantization-process explanation (#747), and dependency bumps.
338-
339-
- **0.31.2**`RowDequantSource` + `ops.gather` row-dequant: a packed/oversized embedding (a Q-quantised `token_embd`) stays packed and is looked up via `ops.gather`, dequantising only the touched rows. (PR #741)
340-
- **0.31.0**`ops.transpose` lazily handles every packed matmul dtype (Q8_0/Q4_0 added, completing the Q4_K/Q5_K/Q6_K/Q5_0/Q5_1/Q8_0/Q4_0 set); `json-schema-validator` → 3.0.4. (PRs #736, #737, #733)
341-
342-
- **0.30.0** — First-class **Q5_K packed in-kernel dequant-matmul** across the CPU backends (`Q5_KBlockTensorData` + `Q5KMatmulKernel` SPI: scalar / Panama Vector / native-C), **hand-written ARM NEON kernels** (fp32/q8_0/q4k/q5k, `-march=armv8.2-a+fp16+dotprod`), and **Kotlin/Native consumption of the C kernels via cinterop** (`skainet-backend-native-cpu` static archive + `linuxX64`/`linuxArm64` `KernelProvider`). (PR #734)
343-
344-
- **0.29.1**`sk.ainet.core:skainet-compile-minerva` now publishes to Maven Central (packaging fix for the Minerva export module shipped in 0.29.0).
345-
- **0.29.0****Minerva secure-MCU export module**: an end-to-end pipeline that lowers a SKaiNET model through shared graph-export contracts → Minerva IR → an `.npz` compiler input → a libminerva-packaged secure MCU project bundle, with host-side runtime verification and fingerprinted manifest artifacts (runnable sample, examples, ONNX workflow, getting-started docs). Plus **packed-quant matmul kernels with Kotlin/Native parity** (Q5_0/Q5_1/Q4_K/Q6_K — commonMain scalar + SPI, packed-quant dispatch in `DefaultCpuOpsBase`, Panama Vector for Q5_1/Q5_0 and Q6_K via the `KernelRegistry`), and an **auto-generated, CI-gated kernel × platform support matrix**. (PRs #697#726)
346-
- **0.28.1** — Kotlin DSL → StableHLO → IREE is green end-to-end for the whole conformance suite (7/7 models, 27/27 ops compile to a `vmfb`): `inferDagOutputSpecs` now infers correct output shapes for shape-changing ops, and `reduce_window` (pooling) emits IREE's generic region form. (PRs #674, #676)
347-
- **0.28.0** — Four StableHLO export bugs fixed (reshape #666, concatenate #667, constants/reductions #663, `HloGenerator` tracing #668) plus non-JVM image runtime support (#671). (PRs #664, #670, #671)
348-
- **0.27.0** — A full gemma3 network lowers to StableHLO and compiles to an IREE `vmfb` (zero op gaps, verified by `GemmaTraceTest`): new `scaledDotProductAttention` (with causal + explicit additive mask), `permute`, `narrow`, and multi-output `split` converters, plus boxing-free `FloatArray` weight externalization for `.irpa` baking. (PRs #661 et al.)
349-
- **0.26.0** — Q4_0 promoted to a first-class quantized format across the provider stack, `tanh` as a first-class activation primitive, and a CPU tensor `convert` op, plus test/build/CI hygiene. (PRs #648#651, #631, #636)
350-
- **0.25.0** — BF16 and Q8_0 matmul kernels end-to-end across the provider stack, autograd completeness for `pow`/`log` and the conv/pool/upsample/split family, the hybrid adaptive dtype-constraint DSL, the `@DarcValidated` operator-doc flag, and the SentencePiece special-token splitter. (PRs #595, #605#628)
351-
- **0.23.0** — Real-model GGUFs no longer OOM at network construction (lazy `TensorDataFactory.placeholder(...)`); Kotlin/Native can finally load GGUFs over 2 GiB via the new POSIX-`pread`-backed `PosixPreadRandomAccessSource`. (Issues #587, #589; PRs #588, #591)
352-
- **0.22.2**`sk.ainet:skainet-bom` now resolves from Maven Central (earlier versions shipped at the wrong coordinates). (Issue #584)
353-
- **0.22.1**`StreamingShardedSafeTensorsReader.loadTensorStorageMapped` for zero-copy reads of multi-shard tensors above the 2 GB JVM `ByteArray` limit. (PR #582)
354-
- **0.22.0** — Native (FFM) CPU kernel provider: **4–6× faster Q4_K matmul, 1.5–1.8× FP32 SGEMM** vs Panama Vector; auto-selected via `KernelRegistry.bestAvailable()`. (PR #571)
355-
356-
See [CHANGELOG.md](CHANGELOG.md) for the full release history.
284+
## What's New in 0.34.0
285+
286+
- **URI-backed data sources** — new `skainet-data-source` module: `file://`, `https://`, and Hugging Face URIs, raw-format parsers (CSV/TSV/JSON/JSONL), suspendable data pipelines
287+
- **Dataset views and richer batches** — seeded shuffle, stratified split, filter views, batch/epoch flows, batch indices + metadata
288+
- **bf16-native DSL → StableHLO export** — weights reach the matmuls as bf16, verified down to an aarch64 vmfb
289+
- **Pluggable per-phase, per-target compile optimization** (`TargetOptimizers`, `OpGranularityPolicy`)
290+
- **2.07× Q4_K NEON matmul on Cortex-A55** — plus LayerNorm statistics now computed in f32 (bf16-safe)
291+
292+
See [CHANGELOG.md](CHANGELOG.md) for details and the full release history.
357293

358294
---
359295

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
GROUP=sk.ainet.core
2-
VERSION_NAME=0.33.0
2+
VERSION_NAME=0.34.0
33
POM_DESCRIPTION=SKaiNET
44

55
POM_URL=https://github.com/SKaiNET-developers/skainet/

0 commit comments

Comments
 (0)