Skip to content

perf: linalg SVD, Pinv, Lstsq, Eigh, QR, Eig allocate 90-276 times per 64x64 call #104

Open

Description

@tannevaled

The linalg decompositions allocate hundreds of times per call on a 64 x 64 matrix, where LAPACK through NumPy allocates a handful of workspaces. The count grows with the matrix side, so the cost is per column or per row, not per call.

Witness (allocation counts, exact under any load; clone at c7b9263, bench/ of the W3 refbench PR)

go test -run TestPerf -perf.record -cpu 1 (GOMAXPROCS=1), 64 x 64 float64:

row allocs per call
linalg.Lstsq / LstsqRcond (64 x 8 right-hand side) 276
linalg.SVD (full_matrices=False) 265
linalg.Pinv / PinvRcond 255
linalg.Eigh 166
linalg.QR 93
linalg.Eig 89
for comparison: linalg.Det / Eigvals / Cholesky 25 / 25 / 20

Pinv and Lstsq rest on SVD (linalg/lstsq.go:35,146, linalg/svd.go:693), so the SVD path is the first place to look. The next measurement should repeat the table at 128 x 128 to confirm the count scales with the side (not run here: only the 64 x 64 counts are recorded).

To do

  • Find the per-column / per-row allocations in the SVD, Eigh, QR and Eig paths and hoist them out of the loops (one workspace per call).
  • Timing is deferred (1-minute load was 8 to 80 when this was filed); this issue is filed on the allocation witness alone.

🤖 Generated with Claude Code

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions