-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add BLAS.get_num_threads #36360
Merged
Merged
add BLAS.get_num_threads #36360
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
bea54cc
add BLAS.get_num_threads
jw3126 2de23cd
fix
jw3126 0e6f8fb
fix
jw3126 9f396c2
fix
jw3126 e84c258
fix
jw3126 9a0edcb
warn if get/set of num_bals_threads fails
jw3126 f6daa79
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 8b2c8c4
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 a15f851
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 826d8ff
fix
jw3126 ce61636
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 b38afaa
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 0ee0efa
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 8e4fedd
fix
jw3126 33a95d5
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 35cf5a6
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 bc370b4
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 dd455b5
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 abd2084
fix
jw3126 b8e9055
fix
jw3126 9eabcb6
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 920b90b
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 b011dc6
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 95ccdf9
Update stdlib/LinearAlgebra/test/blas.jl
jw3126 72ef30e
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 4cf2628
Update stdlib/LinearAlgebra/test/blas.jl
jw3126 bb69931
Update stdlib/LinearAlgebra/test/blas.jl
jw3126 06550d6
Update stdlib/LinearAlgebra/src/blas.jl
jw3126 b6aa076
improve docstrings
jw3126 c524c53
add to NEWS.md
jw3126 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,27 +106,101 @@ end | |
|
||
openblas_get_config() = strip(unsafe_string(ccall((@blasfunc(openblas_get_config), libblas), Ptr{UInt8}, () ))) | ||
|
||
function guess_vendor() | ||
# like determine_vendor, but guesses blas in some cases | ||
# where determine_vendor returns :unknown | ||
ret = vendor() | ||
if Sys.isapple() && (ret == :unknown) | ||
ret = :osxblas | ||
end | ||
ret | ||
end | ||
|
||
|
||
""" | ||
set_num_threads(n) | ||
set_num_threads(n::Integer) | ||
set_num_threads(::Nothing) | ||
|
||
Set the number of threads the BLAS library should use. | ||
Set the number of threads the BLAS library should use equal to `n::Integer`. | ||
|
||
Also accepts `nothing`, in which case julia tries to guess the default number of threads. | ||
Passing `nothing` is discouraged and mainly exists for the following reason: | ||
|
||
On exotic variants of BLAS, `nothing` may be returned by `get_num_threads()`. | ||
Thus on exotic variants of BLAS, the following pattern may fail to set the number of threads: | ||
|
||
```julia | ||
old = get_num_threads() | ||
set_num_threads(1) | ||
@threads for i in 1:10 | ||
# single-threaded BLAS calls | ||
end | ||
set_num_threads(old) | ||
``` | ||
Because `set_num_threads` accepts `nothing`, this code can still run | ||
on exotic variants of BLAS without error. Warnings will be raised instead. | ||
|
||
!!! compat "Julia 1.6" | ||
`set_num_threads(::Nothing)` requires at least Julia 1.6. | ||
""" | ||
function set_num_threads(n::Integer) | ||
blas = vendor() | ||
if blas === :openblas | ||
return ccall((:openblas_set_num_threads, libblas), Cvoid, (Int32,), n) | ||
elseif blas === :openblas64 | ||
return ccall((:openblas_set_num_threads64_, libblas), Cvoid, (Int32,), n) | ||
elseif blas === :mkl | ||
set_num_threads(n)::Nothing = _set_num_threads(n) | ||
|
||
function _set_num_threads(n::Integer; _blas = guess_vendor()) | ||
if _blas === :openblas || _blas == :openblas64 | ||
return ccall((@blasfunc(openblas_set_num_threads), libblas), Cvoid, (Cint,), n) | ||
elseif _blas === :mkl | ||
# MKL may let us set the number of threads in several ways | ||
return ccall((:MKL_Set_Num_Threads, libblas), Cvoid, (Cint,), n) | ||
end | ||
|
||
# OSX BLAS looks at an environment variable | ||
@static if Sys.isapple() | ||
elseif _blas === :osxblas | ||
# OSX BLAS looks at an environment variable | ||
ENV["VECLIB_MAXIMUM_THREADS"] = n | ||
else | ||
@assert _blas === :unknown | ||
@warn "Failed to set number of BLAS threads." maxlog=1 | ||
end | ||
return nothing | ||
end | ||
|
||
_tryparse_env_int(key) = tryparse(Int, get(ENV, key, "")) | ||
|
||
function _set_num_threads(::Nothing; _blas = guess_vendor()) | ||
n = something( | ||
_tryparse_env_int("OPENBLAS_NUM_THREADS"), | ||
_tryparse_env_int("OMP_NUM_THREADS"), | ||
max(1, Sys.CPU_THREADS ÷ 2), | ||
) | ||
_set_num_threads(n; _blas) | ||
end | ||
|
||
""" | ||
get_num_threads() | ||
|
||
Get the number of threads the BLAS library is using. | ||
|
||
On exotic variants of `BLAS` this function can fail, which is indicated by returning `nothing`. | ||
|
||
!!! compat "Julia 1.6" | ||
`get_num_threads` requires at least Julia 1.6. | ||
""" | ||
get_num_threads(;_blas=guess_vendor())::Union{Int, Nothing} = _get_num_threads() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for reporting, I will fix it! |
||
|
||
function _get_num_threads(; _blas = guess_vendor())::Union{Int, Nothing} | ||
if _blas === :openblas || _blas === :openblas64 | ||
return Int(ccall((@blasfunc(openblas_get_num_threads), libblas), Cint, ())) | ||
elseif _blas === :mkl | ||
return Int(ccall((:mkl_get_max_threads, libblas), Cint, ())) | ||
elseif _blas === :osxblas | ||
key = "VECLIB_MAXIMUM_THREADS" | ||
nt = _tryparse_env_int(key) | ||
if nt === nothing | ||
@warn "Failed to read environment variable $key" maxlog=1 | ||
else | ||
return nt | ||
end | ||
else | ||
@assert _blas === :unknown | ||
end | ||
@warn "Could not get number of BLAS threads. Returning `nothing` instead." maxlog=1 | ||
return nothing | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like an unusual API, I would prefer
set_num_threads()
instead ofset_num_threads(nothing)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to allow the pattern
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will still work if you make the signature
set_num_threads(n=nothing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me allowing
nothing
is a hack to allow the above pattern on strange platforms. It is not a thing I would encourage or that I think needs more convenient syntax.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine if you have code like
set_num_threads()
it is more likely you forgot to pass the number of threads, than that you really want to invoke thenothing
method.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should define
set_num_threads() = set_num_threads(nothing)
. It would send a wrong message thatset_num_threads(nothing)
is somehow a reasonable default. But it's not. It is the last resort that exists only for supporting the rollback use case.But this is not clear from the current docstring. I think it's better to clarify this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps clearest to show the pattern which motivates this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fredrikekre Does the argument here makes sense? It'd be nice if you can have a look at the docstring.