Skip to content

Perf Optimize spectral operations and backend dispatch - #42

Merged
bruAristimunha merged 8 commits into
spdlearn:mainfrom
lucas-heck:perf/spectral-kernels
Oct 19, 2026
Merged

bruAristimunha merged 8 commits into
spdlearn:mainfrom
lucas-heck:perf/spectral-kernels

Conversation

@lucas-heck

Copy link
Copy Markdown
Contributor

This PR reduces intermediate allocations, mainly by using PyTorch optimized operations, and backend dispatch overhead in a couple of layers:

  • Reconstruct matrices by scaling eigenvector columns instead of building diagonal tensors, preserving the CUDA intermediate layout.
  • Keep Loewner thresholds on-device and use dense masking on accelerators while retaining indexed updates on CPU.
  • Cache LogEig/ExpEig backend selection and restore it when loading checkpoints.

It also skips matrix-log clamping warnings for CUDA inputs requiring gradient, which might be a maintainer decision but this way it avoids synchronization during training (I don't mind changing back).

Validation:

  • Numerical tests and gradchecks passed on CPU and CUDA
  • Standalone GPU training benchmarks reduced median fit time by 4.6%/4.7% for SPDNet and 4.5%/5.6% for EEGSPDNet on two machines, respectively, while CPU training time was pretty much the same.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 64.70588% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
spd_learn/functional/autograd.py 56.25% 4 Missing and 3 partials ⚠️
spd_learn/modules/modeig.py 62.50% 1 Missing and 2 partials ⚠️
spd_learn/functional/core.py 75.00% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@bruAristimunha bruAristimunha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small details, and all good

Comment thread spd_learn/modules/modeig.py Outdated

@bruAristimunha bruAristimunha left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @lucas-heck, really nice work, and the benchmark numbers in the description help a lot.

I did a second full pass before merging:

  • Full test suite on all four open PRs merged together (#42 → #43 → #44 → #45): 825 passed, 147 skipped, plus the docs code blocks.
  • The non-CPU torch.where branch in modeig_backward only runs on accelerators, so CI does not cover it (that explains most of the codecov gap). I ran it on Apple MPS with a batch that includes repeated eigenvalues: matrix_log gradients match CPU to 6e-8.
  • LogEig / ExpEig: after load_state_dict from a checkpoint with a different autograd flag, the cached backend is correctly picked up.
  • gradcheck on batched float64 matrix_log passes.

Small, non-blocking notes:

  1. get_loewner_threshold conflicts with #45, which makes the threshold per matrix. I'll keep #45's version, since it is a superset of this one (tensor, on-device, per matrix).
  2. The CHANGELOG.md diff also reformats the old model/metric tables (whitespace only). That's harmless, just noise in the diff.
  3. The _use_autograd cache only updates on __init__ and load_state_dict. If someone changes autograd_ in place, it goes stale. That's fine as long as the buffer is treated as read-only.

Merging. Thanks again!

@bruAristimunha
bruAristimunha merged commit 202cdaf into spdlearn:main Oct 19, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants