Skip to content

PCA.fit: gemm covariance offers a further 1.8x-3.6x but breaks bit-identical fitted state #361

Description

@godofecht

Follow-up from #211 (PR #350). Measured and deliberately NOT shipped there, because #211 scoped itself to allocation/cache/symmetry work and required the fitted state to stay bit-identical.

The measurement

PR #350 got PCA.fit to roughly 2.3x-2.9x by hoisting allocations, computing only the covariance upper triangle, and replacing accessor calls with direct row-major indexing, all while preserving every arithmetic expression term for term.

A prototype that instead forms the covariance with a single cblas_sgemm was built purely to measure it, then reverted:

shape origin/main PR #350 gemm prototype
20000x8 -> 4 6.90 ms 2.26 ms 1.24 ms
4000x64 -> 16 110.97 ms 38.00 ms 10.44 ms
400x200 -> 8 196.16 ms 76.33 ms 43.07 ms

So a further 1.8x-3.6x on top of what #350 already banks.

Why it was not taken

The fitted state stops being bit-identical. explained_variance[0] moves from 3176.930419922 to 3176.930908203 — a few f32 ulps from gemm's different accumulation order.

That matters more for PCA than for most estimators. benchmarks/parity_contract.json gives PCA the strictest contract in the repo: explained-variance ratios, singular values, reconstruction error AND sign-aligned components. Eigenvector signs are the real hazard, since a reordering that flips a sign breaks the contract outright rather than drifting within it.

What a follow-up needs to establish

If the drift turns out to be contract-compatible, this is one of the larger remaining wins in the top 20. If it is not, that is worth recording explicitly so nobody re-derives the prototype a third time.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions