Skip to content

use default BLAS number of threads instead of setting it to Threads.nthreads(). - #274

Merged
JakobAsslaender merged 1 commit into
masterfrom
ESPIRIT_BLAS_Threads
Mar 12, 2026
Merged

use default BLAS number of threads instead of setting it to Threads.nthreads().#274
JakobAsslaender merged 1 commit into
masterfrom
ESPIRIT_BLAS_Threads

Conversation

@JakobAsslaender

Copy link
Copy Markdown
Member

We used to always use Threads.nthreads() for the first ESPIRIT SVD, but our benchmarks indicate that this is slower than using the 10 default threads of BLAS. We could force the number of threads to something more meaningful (10 or less), or give the user the option to just set globally the number of threads, assuming that most people will use the default, which is not bad. This PR implements the latter, which is also the much cleaner code. LMK what you think!

@codecov

codecov Bot commented Mar 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.99%. Comparing base (71feb31) to head (2ccc869).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master     #274       +/-   ##
===========================================
+ Coverage   59.96%   74.99%   +15.02%     
===========================================
  Files         101      103        +2     
  Lines        5326     5419       +93     
===========================================
+ Hits         3194     4064      +870     
+ Misses       2132     1355      -777     
Flag Coverage Δ
MRIBase 50.19% <ø> (ø)
MRICoilSensitivities 93.01% <100.00%> (-0.06%) ⬇️
MRIFiles 78.59% <ø> (?)
MRIOperators 40.56% <ø> (ø)
MRIReco 42.41% <0.00%> (+0.03%) ⬆️
MRISampling 0.35% <ø> (ø)
MRISimulation 63.07% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nHackel

nHackel commented Mar 12, 2026

Copy link
Copy Markdown
Member

I think this change is fine, especially since its backed with a benchmark. Could you comment the benchmark input sizes and maybe even the speed up in this PR, so we can have a comparision if we ever want to revisit this?

I wouldn't consider this a breaking change, so we can release a patch release for coil sensitivies. Ping me if you want me to do it

@JakobAsslaender

Copy link
Copy Markdown
Member Author

Great! Below is a benchmark, where Nx and Ny correspond to kernel_size = (6, 6, 6), calib_size = (32, 32, 24), and 20 coils (3D).

On our HPC, this is certainly an extreme example:

julia -t auto
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.12.5 (2026-02-09)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org release
|__/                   |

julia> using LinearAlgebra

julia> using BenchmarkTools

julia> Threads.nthreads()
32

julia> BLAS.get_num_threads()
16

julia> T = ComplexF32;

julia> Nx = 13851;

julia> Ny = 4320;

julia> A = randn(T, Nx, Ny);

julia> @btime svd!(A);
  16.355 s (19 allocations: 1.31 GiB)

julia> BLAS.set_num_threads(Threads.nthreads())

julia> A = randn(T, Nx, Ny);

julia> @btime svd!(A);
  835.167 s (19 allocations: 1.31 GiB)

On my Mac:

 julia -t auto 
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.12.5 (2026-02-09)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org release
|__/                   |

julia> using LinearAlgebra

julia> using BenchmarkTools

julia> Threads.nthreads()
16

julia> BLAS.get_num_threads()
8

julia> T = ComplexF32;

julia> Nx = 13851;

julia> Ny = 4320;

julia> A = randn(T, Nx, Ny);

julia> @btime svd!(A);
  34.956 s (19 allocations: 1.31 GiB)

julia> BLAS.set_num_threads(Threads.nthreads())

julia> A = randn(T, Nx, Ny);

julia> @btime svd!(A);
  120.478 s (19 allocations: 1.31 GiB)

Of course, this is N in [1, 2], but I found this behavior pretty reproducible, and I would assume that the gap gets even bigger for smaller sizes of A, for example, in 2D.

Would you be so kind as to do a patch release? I still haven't figured out the sub-module system...

@JakobAsslaender
JakobAsslaender merged commit 97755ce into master Mar 12, 2026
43 of 45 checks passed
@JakobAsslaender
JakobAsslaender deleted the ESPIRIT_BLAS_Threads branch March 12, 2026 19:35
@nHackel

nHackel commented Mar 12, 2026

Copy link
Copy Markdown
Member

Oh wow that's a large difference. I'll do release when I'm at work tomorrow!

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.

2 participants