-
Notifications
You must be signed in to change notification settings - Fork 66
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
Check operations in @turbo
automatically with can_avx
; if failure, switch to @inbounds @fastmath
#431
Conversation
I'm not sure if f(x) = exp(x)
can_avx(f) this would return |
#430 (comment) |
Codecov ReportBase: 86.35% // Head: 83.70% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #431 +/- ##
==========================================
- Coverage 86.35% 83.70% -2.66%
==========================================
Files 37 37
Lines 9310 9336 +26
==========================================
- Hits 8040 7815 -225
- Misses 1270 1521 +251
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
For example: julia> using SpecialFunctions, VectorizationBase, SLEEFPirates
julia> can_turbo(f::F, ::Val{NARGS}) where {F,NARGS} = Base.promote_op(f, ntuple(Returns(Vec{2,Int}), Val(NARGS))...) !== Union{}
can_turbo (generic function with 1 method)
julia> can_turbo(+, Val(1))
true
julia> can_turbo(exp, Val(1))
true
julia> f(x) = exp(x)
f (generic function with 1 method)
julia> can_turbo(f, Val(1))
true
julia> can_turbo(gamma, Val(1))
false This isn't necessarilly precise, but should work well in practice. |
What is the best way to get |
|
Awesome, thanks! Everything is implemented, and added a few tests too. Let me know what you think. Also, let me know if you'd rather have |
I'm not sure why the tests are failing - did I miss a (probably would be good to refactor away the shotgun surgery in the future, if possible) |
Okay, Currently, it's dropping |
I tried to add
Traceback |
Okay, I think I found them all. (I would definitely recommend making a dedicated type for Let me know how this PR looks. |
Seems to be breaking imports.
shuffles load/stores | 4442 257 4699 1m15.4s These nightly failures happen on the |
Add special functions to |
Seeing this issue now: Test threw exception
Expression: LoopVectorization.can_turbo(f2, Val(1))
UndefVarError: Returns not defined
Stacktrace:
[1] can_turbo(f::var"#f2#2", #unused#::Val{1})
@ LoopVectorization ~/work/LoopVectorization.jl/LoopVectorization.jl/src/condense_loopset.jl:913
[2] macro expansion
@ ~/work/LoopVectorization.jl/LoopVectorization.jl/test/safe_turbo.jl:21 [inlined]
[3] macro expansion
@ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
[4] top-level scope
@ ~/work/LoopVectorization.jl/LoopVectorization.jl/test/safe_turbo.jl:4 I guess this is from the |
I'm traveling for the rest of this week unfortunately, so I won't be online much. I can retry this weekend though. Let me know if you have any clues as to why this breaks. Also, feel free to push to the branch (and potentially merge) as you wish. |
|
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 an example workaround for Returns
not existing yet.
Co-authored-by: Chris Elrod <[email protected]>
Co-authored-by: Chris Elrod <[email protected]>
Have you looked into Safe @turbo: Error During Test at /home/runner/work/LoopVectorization.jl/LoopVectorization.jl/test/safe_turbo.jl:8
Got exception outside of a @test
UndefVarError: #f###6### not defined ? |
I couldn't figure that one out, was hoping you would have some idea. I tried defining the function inside and outside of the test set, and ensuring that each function has a unique name, but that error persists. I assume it's some weird test syntax quirk. |
Nice!! Thanks |
Thanks for all the work on this! |
This solves #430 and prevents the StackOverflowError from appearing in #232. cc @timholy @chriselrod. Thanks to @chriselrod for walking me through how to implement this with detailed instructions.
Basically this will check all instructions in a
@turbo
loop (if thesafe=true
kwarg is set -true
false
by default) withArrayInterface.can_avx
. If any operation isfalse
, then the check will fail and@inbounds @fastmath
will be used instead, which will also print a warning message unlesswarn_check_arg=false
.Note that
safe=true
safe=false
by defaultso this is technically not needed.Before this change, this code would result in a mysterious
StackOverflowError
, sincegamma
does not have an AVX version implemented.As described in #430, this change is useful for cases where the user can pass an arbitrary operator - one still wants
@turbo
to work if that operator can be AVX'd, but default to@inbounds @fastmath
otherwise.Minor additional changes: I refactored
can_avx.jl
, and includedSpecialFunctions.gamma
as an operator which cannot currently be AVX'd.