diff --git a/CHANGELOG.md b/CHANGELOG.md index 75eb4890..437ebf49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,57 @@ +# t4a-faer 0.26.0 (tensor4all fork; with t4a-faer-traits 0.24.2) + +Changes since `t4a-faer` 0.25.2 (tag `faer-v0.25.2`). Numbers are tensor4all/faer issues or PRs; each change has its row in `PATCHSET.md`. + +## Breaking: threadteam is the only parallel route (#97) + +`Par::Rayon(NonZeroUsize)`, `Par::rayon(nthreads)`, `ParShape::Rayon(NonZeroUsize)` and +`ParShape::rayon(nthreads)` are removed, together with the spindle path and the Rayon cost model. +`Par::Seq` and `Par::Team` remain. To migrate: + +- a one-off parallel call: `faer::team::with_team(n, |par| { /* faer calls with par */ })` replaces + `Par::rayon(n)`; +- repeated parallel work: build a `threadteam::Pool` and `Team` once and lend `Par::Team(..)` to each + call, `par.reborrow()` for successive calls (see "parallelism" in `README.md`); +- a workspace query: pass `par.shape()` (or `ParShape::Seq`) where `ParShape::rayon(n)` was used. + +A build without the `threadteam` feature has `Par::Seq` only. + +## New + +- `faer::linalg::matmul::matmul_with_conj_uninit` and `MatUninitMut`: a matrix product into + `MaybeUninit` storage, returned as an initialized `MatMut`; prior contents are never read + (#136, requested upstream as sarah-quinones/faer-rs#269). + +## Correctness + +- Nonsymmetric EVD: the input is scaled into range as `?GEEV` does (#112); the eigenvector back + substitution clamps relative to the eigenvalue, so residuals no longer grow with n (#112); the real + Schur deflation-window sort always ends (#144); the 2 x 2 block solves of the real back + substitution follow `?LALN2` (#145). +- SVD: the rotation path finishes when dqds does not converge (#110); a retained Ritz pair of the + partial SVD carries its residual estimate through the restart (#108). +- LU: the full-pivoting search breaks ties by column then row, independent of the SIMD width (#105, #106). +- Products with a diagonal read the depth in either direction (#113). +- Sparse LU reports an exact zero pivot as `LuError::NumericSingular` in both backends (#132). +- Krylov solvers: the final residual is reported on `NoConvergence`, and BiCGSTAB stops at the last + finite iterate after a breakdown (#133, #134). + +## Parallelism and performance + +- Every region runs at the widest width that pays, on a sub-team of that width (#91); the team + dispatch cost is read from threadteam (#104). +- No heap allocation inside a parallel region (#111). +- Layout copies split along the destination's major dimension, first touch in parallel (#99). +- SVD: blocked bidiagonalization, dqds shift and a padded work copy (#52). + +## Dependencies and toolchain + +- `threadteam` 0.1.3 (#107 wait fix) and `t4a-private-gemm-x86` 0.1.27 (#113). +- MSRV is Rust 1.89 (`rust-version = "1.89.0"` in both crates). +- AVX-512 (`x86-v4`) no longer needs the nightly compiler but stays opt-in: enable the `x86-v4` + feature (`nightly` is kept as its old name). +- `t4a-faer-traits` 0.24.2 only adds `rust-version`. + # 0.24 - add missing scratch space functions for matrix-free eigen/svd solvers - allow sparse-dense/dense-sparse matmuls to accept both CSC and CSR matrices diff --git a/Cargo.lock b/Cargo.lock index 35448a6b..d79eee42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2676,7 +2676,7 @@ dependencies = [ [[package]] name = "t4a-faer" -version = "0.25.2" +version = "0.26.0" dependencies = [ "aligned-vec", "amd", @@ -2727,7 +2727,7 @@ dependencies = [ [[package]] name = "t4a-faer-traits" -version = "0.24.1" +version = "0.24.2" dependencies = [ "bytemuck", "dyn-stack", diff --git a/PATCHSET.md b/PATCHSET.md index ea5ca014..35c9ad66 100644 --- a/PATCHSET.md +++ b/PATCHSET.md @@ -53,7 +53,7 @@ gate has changed and two kinds of adoption are now in the ledger. | Workspace | `faer-ffi` is excluded (the C API and its cbindgen build are unused by tensor4all). | | Upstream base | Synced with Codeberg `0ecd846` (2026-10-17) by a merge commit, so `upstream/main` is an ancestor of this branch. Those nine upstream commits since the previous base `ddbd2ae` (the sparse CSC example doc, `MatMut::from_row_major_slice_with_stride_mut`'s strides, the CG/BiCGSTAB uninitialized read) were written upstream by Paul and Connor Smith and had already been cherry-picked here on 2026-10-22 in `9f3dc58`, `ae9b979` and `064016e` (their messages name Codeberg #305, #326 and `1b2d9a9`; the tests `codeberg_305`/`codeberg_326` came with them). The direction is upstream to fork, not the reverse: nothing was fed back upstream. The cherry-picked content is byte-identical to upstream's, so the sync changes no file -- the merged tree hash equals the pre-merge tree hash. Later syncs record the new base here. | | Publication | crates.io, in the order `t4a-faer-traits` then `t4a-faer`. Releases are tagged `faer-v` and published by hand from a clean checkout of the tag; a `v` tag would also start `publish.yml`. A version that is already on crates.io is skipped, so a release that bumps only one crate still succeeds. | -| Released | Latest: `t4a-faer 0.25.2` with `t4a-faer-traits 0.24.1`, published from the commit tagged `faer-v0.25.2` (see the release section at the end). The published `src/**` is byte-identical to the tagged commit, so that commit is the revision a consumer pins. A later commit needs a new version. Earlier releases carry their own `faer-v` tags. | +| Released | Latest: `t4a-faer 0.26.0` with `t4a-faer-traits 0.24.2`, published from the commit tagged `faer-v0.26.0` (see the release section at the end). The published `src/**` is byte-identical to the tagged commit, so that commit is the revision a consumer pins. A later commit needs a new version. Earlier releases carry their own `faer-v` tags. | | LICENSE | A `LICENSE` copy lives in each crate directory so the published archive ships the MIT text (`license-file` next to `license` makes Cargo warn). | ## Experiments @@ -260,3 +260,12 @@ merge commit of the version-bump PR, tagged `faer-v0.25.2`. The release carries - #83 triangular_solve: exact solves with subnormal pivots (#74). Evidence lives in each PR and its ledger row above; this release adds no code. + +## Released: `t4a-faer` 0.26.0 (2026-10-29) + +`t4a-faer` 0.26.0 with `t4a-faer-traits` 0.24.2 (only `rust-version = "1.89.0"` is new in +`faer-traits/`). Published from the merge commit of the version-bump PR, tagged `faer-v0.26.0`, which +also marks the `t4a-faer-traits` 0.24.2 source. The minor version moves because #97 removed +`Par::Rayon`, `Par::rayon`, `ParShape::Rayon` and `ParShape::rayon` (`README.md`: published versions +follow semver). `CHANGELOG.md` lists the changes since `faer-v0.25.2` and the migration; the evidence +lives in each PR and its ledger row above. This release adds no code. diff --git a/faer-traits/Cargo.toml b/faer-traits/Cargo.toml index 44e4b170..56cfe775 100644 --- a/faer-traits/Cargo.toml +++ b/faer-traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "t4a-faer-traits" -version = "0.24.1" +version = "0.24.2" edition = "2021" rust-version = "1.89.0" authors = ["sarah quiƱones "] diff --git a/faer/Cargo.toml b/faer/Cargo.toml index 7c294abb..d46ded0a 100644 --- a/faer/Cargo.toml +++ b/faer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "t4a-faer" -version = "0.25.2" +version = "0.26.0" edition = "2021" authors = ["sarah quiƱones "] description = "Temporary tensor4all fork of faer: an AI-driven experiment build for tenferro-rs." @@ -37,7 +37,7 @@ dyn-stack = { version = "0.13.2", default-features = false, features = ["core-er pulp = { version = "0.22.2", default-features = false, features = ["x86-v3"] } equator = { version = "0.6.0" } -faer-traits = { package = "t4a-faer-traits", path = "../faer-traits", version = "0.24.1", default-features = false } +faer-traits = { package = "t4a-faer-traits", path = "../faer-traits", version = "0.24.2", default-features = false } gemm = { version = "0.19.0", default-features = false } nano-gemm = { version = "0.2.2", default-features = false }