-
-
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
fix evalpoly type instability and 0-length case #56707
base: master
Are you sure you want to change the base?
Conversation
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'm not sure if opening this PR was polite, considering a newcomer submitted #56699 trying to fix the same issue, and the issue is marked as "good first issue". In any case, that PR is now closed, so here are some comments.
(I hadn't noticed the other PR until after I submitted this one, unfortunately.) |
CI failures look unrelated. |
Yay, green. Good to merge? |
why is triage added here? |
Because it's been ready to merge for 2 months and needs someone to review it? Is there a better label? |
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 makes the existing use of @generated
on line 95 invalid because the two branches now return different types:
julia> evalpoly(1.0, (1,))
1
julia> Base.Math._evalpoly(1.0, (1,))
1.0
julia> @less evalpoly(1, (1,))
function evalpoly(x, p::Tuple)
if @generated
N = length(p.parameters::Core.SimpleVector)
ex = :(p[end])
for i in N-1:-1:1
ex = :(muladd(x, $ex, p[$i]))
end
ex
else
_evalpoly(x, p)
end
end
Oh ye gods, børked rebase. |
Git history is messed up now. |
Co-authored-by: Neven Sajko <[email protected]>
Co-authored-by: Neven Sajko <[email protected]>
Co-authored-by: Neven Sajko <[email protected]>
Co-authored-by: Neven Sajko <[email protected]>
c6852d2
to
05cfd26
Compare
Should be fixed now. |
@LilithHafner, I fixed the issue with the |
Currently getting:
This could be fixed by replacing So maybe this PR is blocked by JuliaLang/LinearAlgebra.jl#1161 being fixed within LinearAlgebra.jl? |
This now breaks the identity julia> evalpoly(:sploo, (:bork,))
:bork # now throws
julia> evalpoly(1.0, (true,))::Bool
true # now 1.0
julia> evalpoly(rand(2,2), (1,))
1 # This should possibly be Float64[1 0; 0 1] now throws According to the docstring, I think that "breakage" is a bugfix. |
Not sure why this identity should be expected from the definition?
I guess you agree with the new behavior? |
If you write out a polynomial in the form
Yes, I do. Regardless of the above. |
This is not the definition that is given in the docs for (Note also that the definition right-multiplies |
There were CI failures, e.g.
|
Blocked by JuliaLang/LinearAlgebra.jl#1161 as noted above. |
@@ -94,7 +94,7 @@ julia> evalpoly(2, (1, 2, 3)) | |||
function evalpoly(x, p::Tuple) | |||
if @generated | |||
N = length(p.parameters::Core.SimpleVector) | |||
ex = :(p[end]) | |||
ex = :(oftype(one(x) * p[end], p[end])) |
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 worry a bit about this causing performance regressions (especially in cases where multiplication is not cheap), but I also get that it's likely important.
Ideally we'd be able to do something in the type domain here rather than an actual multiplication, but oh well i guess. This is probably less brittle, and won't regress in most cases.
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.
Hopefully the compiler can optimize out one(x) * p[end]
in most cases, and just compute the type, since the result is not used.
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.
Only if the multiplication is simple enough and free of side effects like memory allocation? If the scalar is eg a BigInt it may not be able to optimize this away?
A few fixes/improvements to the
evalpoly
function:evalpoly(x,())
gives unhelpful error. #56699: returns zero for an empty tuple or array of coefficientsevalpoly(x, ::Vector)
@inbounds
annotationex
that was-copy-pasted from the macro version (whereex
referred to an expression) but makes no sense here for the numeric sum.Probably should be backported.