-
-
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
Refine LimitedAccuracy's ⊑ semantics #48045
Conversation
base/compiler/typelimits.jl
Outdated
issimplertype(lattice, typeb, typea) && return LimitedAccuracy(typeb, causesb) | ||
elseif suba | ||
issimplertype(lattice, typeb, typea) && return LimitedAccuracy(typeb, causesb) | ||
causes = causesnb |
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.
causesb
base/compiler/typelimits.jl
Outdated
causes = causesnb | ||
# `a`'s causes may be discarded | ||
elseif subb | ||
causes = causesb |
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.
symmetry?
causes = causesb | |
issimplertype(lattice, typea, typeb) && return LimitedAccuracy(typea, causesa) | |
causes = causesa |
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.
The issimplertype test is below, but yes this should have been causesa
.
base/compiler/typelattice.jl
Outdated
@@ -368,7 +404,8 @@ ignorelimited(typ::LimitedAccuracy) = typ.typ | |||
function ⊑(lattice::InferenceLattice, @nospecialize(a), @nospecialize(b)) | |||
if isa(b, LimitedAccuracy) | |||
if !isa(a, LimitedAccuracy) | |||
return false | |||
# epsilon smaller | |||
return ⊑(widenlattice(lattice), a, b.typ) && !⊑(widenlattice(lattice), b.typ, a) | |||
end | |||
if b.causes ⊈ a.causes | |||
return false |
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 should reflect the epsilon case too, though I think that means refactoring part of this code for better ordering than this
return false | |
if ⊑(widenlattice(lattice), a.typ, b.typ) | |
return true | |
end | |
return false |
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 also must be reflected now in the type-complexity tests. Where this is meaning the comparison of the length of causes.)
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.
the type-complexity tests
You mean issimplertype
? In the current design, that's not reached for LimitedAccuracy and before we were just passing those arguments through ignorelimited
.
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.
Yeah. It seems a little odd for tmerge_fast_path not to be legal anymore for this type, but I guess that looks right. We should perhaps assert there since we know LimitedAccuracy may be handled wrong there now?
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.
We were correct before, since it was already implied by the precondition of suba or subb. That assumed implication is no longer valid after this change.
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.
Let me remove the ignorelimited
in issimplertype then. We'll get an appropriate assertion if somebody accidentally uses it.
@nanosoldier |
Your package evaluation job has completed - possible new issues were detected. A full report can be found here. |
As discussed in #48030, this is a different attempt to fix the semantics of LimitedAccuracy. This fixes the same test case as #48030, but keeps `LimitedAccuracy` ε smaller than its wrapped lattice element. The primary change here is that now all lattice elements that are strictly `⊑ T` are now also `⊑ LimitedAccuracy(T)`, whereas before that was only true for other `LimitedAccuracy` elements. Quoting the still relevant parts of #48030's commit message: ``` I was investigating some suboptimal inference in Diffractor (which due to its recursive structure over the order of the taken derivative likes to tickle recursion limiting) and noticed that inference was performing some constant propagation, but then discarding the result. Upon further investigation, it turned out that inference had determined the function to be `LimitedAccuracy(...)`, but constprop found out it actually returned `Const`. Now, ordinarily, we don't constprop functions that inference determined to be `LimitedAccuracy`, but this function happened to have `@constprop :aggressive` annotated. Of course, if constprop determines that the function actually terminates, we do want to use that information. We could hardcode this in abstract_call_gf_by_type, but it made me take a closer look at the lattice operations for `LimitedAccuracy`, since in theory `abstract_call_gf_by_type` should prefer a more precise result. ```
Tests currently depend on JuliaLang/julia#48045 and JuliaLang/julia#48059, so we should either get those merged first, or mark them here as broken.
Co-authored-by: Shuhei Kadowaki <[email protected]>
I think this should be good to go. PkgEval looks good. |
|
||
# a and b's unlimited types are equal. | ||
isa(a, LimitedAccuracy) || return false # b is limited, so ε smaller | ||
return a.causes ⊆ b.causes |
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.
The old code used to have the inverse check here
return a.causes ⊆ b.causes | |
return b.causes ⊆ a.causes |
Was this supposed to get switched here? I think that is incorrect now, as the wider result should have fewer causes, but this does the opposite.
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.
Let me double check. I don't think I intended to switch it - it's possible I got my cases mixed up.
# Approximated types are lattice equal. Merge causes. | ||
if suba && subb | ||
causes = merge_causes(causesa, causesb) | ||
issimplertype(lattice, typeb, typea) && return LimitedAccuracy(typeb, causesb) |
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.
issimplertype(lattice, typeb, typea) && return LimitedAccuracy(typeb, causesb) | |
issimplertype(lattice, typeb, typea) && return LimitedAccuracy(typeb, causes) |
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 think symmetry and equality demands that you are not supposed to check issimplertype
in this case (see tmerge_fast_path
)
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.
Well, we are still changing the lattice element here potentially if the causes are different, but yes fair enough, I'll drop the issimplertype
check.
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.
Good point though. Is this new tmerge algorithm monotonic and convergent? In particular, this merge call here (with the heuristic towards shorter lengths but calling union if undecidable) seems like it might make inference non-terminating as it repeatedly merged and dropped causes lists here in a loop
As discussed in #48045: 1. Switch the order of `causes` inclusion to make wider elements have fewer causes. 2. Fix two typos 3. Restore property that equal ulimited types will be preserved (though with potentially updated `causes` lists).
* Hookup demand-driven forward mode to the Diffractor runtime Tests currently depend on JuliaLang/julia#48045 and JuliaLang/julia#48059, so we should either get those merged first, or mark them here as broken. * Mark test as broken
As discussed in #48045: 1. Switch the order of `causes` inclusion to make wider elements have fewer causes. 2. Fix two typos 3. Restore property that equal ulimited types will be preserved (though with potentially updated `causes` lists).
As discussed in #48030, this is a different attempt to fix the semantics of LimitedAccuracy. This fixes the same test case as #48030, but keeps
LimitedAccuracy
ε smaller than its wrapped lattice element. The primary change here is that now all lattice elements that are strictly⊑ T
are now also⊑ LimitedAccuracy(T)
, whereas before that was only true for otherLimitedAccuracy
elements.Quoting the still relevant parts of #48030's commit message: