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
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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<T>` 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
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion PATCHSET.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<faer version>` and published by hand from a clean checkout of the tag; a `v<faer version>` 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<version>` 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<version>` 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
Expand Down Expand Up @@ -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.
2 changes: 1 addition & 1 deletion faer-traits/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 <sarah@veganb.tw>"]
Expand Down
4 changes: 2 additions & 2 deletions faer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "t4a-faer"
version = "0.25.2"
version = "0.26.0"
edition = "2021"
authors = ["sarah quiñones <sarah@veganb.tw>"]
description = "Temporary tensor4all fork of faer: an AI-driven experiment build for tenferro-rs."
Expand Down Expand Up @@ -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 }
Expand Down
Loading