-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
AbstractInterpreter: implement findsup for OverlayMethodTable
#44448
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
Conversation
base/compiler/methodtable.jl
Outdated
| min_valid[] = typemin(UInt) | ||
| max_valid[] = typemax(UInt) |
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.
technically not legal to reset this, but is perfectly acceptable not to
| min_valid[] = typemin(UInt) | |
| max_valid[] = typemax(UInt) |
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 decided to make a duplicated call to findsup here.
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.
ah, makes sense
though note it is mandatory to preserve the lookup min_valid/max_valid regardless of whether you get a result
note 2 that it is also always mandatory to execute the "fall back to the internal method table" code, unless you can prove that the results are fully covered
3716665 to
246b900
Compare
base/compiler/methodtable.jl
Outdated
|
|
||
| function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=typemax(Int)) | ||
| result = _findall(sig, table.mt, table.world, limit) | ||
| result === missing || isempty(result) || return result |
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.
If this part of the result is missing, then the total result must also be missing
Though I find the change between false and missing to be somewhat odd for the API–you don't get less by adding more. Perhaps we should use something consistent such as nothing? (even true might be a better choice, since it means we found too many matches)
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, I think nothing or missing would be better, since they are easier to be handled by Conditional? Given that such case means "too many matches", missing sounds a bit counter-intuitive.
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.
246b900 to
219f08d
Compare
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
219f08d to
c86d43a
Compare
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Now `jl_gf_invoke_lookup` accepts an optional overlayed method table, but actual code execution (as done by JuliaInterpreter) doesn't need to care about it at this moment.
Now `jl_gf_invoke_lookup` accepts an optional overlayed method table, but actual code execution (as done by JuliaInterpreter) doesn't need to care about it at this moment.
| result = _findall(sig, table.mt, table.world, limit) | ||
| result === missing && return missing | ||
| if !isempty(result) | ||
| if all(match->match.fully_covers, result) |
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.
It only matters if result[end].fully_covers
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 check my understanding.
We can just look at result[end].fully_covers since:
jl_matching_methodsreturns matching methods in order of speciality
(and so the last match is always the most general case)- if the last match
fully_covers, it means this call is assured to be
dispatched to the last match when it's not dispatched with the other matches
| WorldRange(min(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world), | ||
| max(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)), |
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.
you need the max of the min_worlds and the min of the max_worlds
| result.ambig | fallback_result.ambig) | ||
| end | ||
| end | ||
| # fall back to the internal method table |
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.
Even if the result is empty, you are still required to return the valid_worlds data from the (failed) lookup
| (result.method, WorldRange(min_valid[], max_valid[])) | ||
| result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), | ||
| sig, mt, world, min_valid, max_valid)::Union{MethodMatch, Nothing} | ||
| return result === nothing ? result : (result, WorldRange(min_valid[], max_valid[])) |
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 conservatively correct currently (since we return Any), but it would be more correct to return the tuple unconditionally, since the WorldRange applies to the lookup, regardless of the result.
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
#44511) - respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
#44511) - respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
…44478) Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Previously
findsupdoesn't supportOverlayMethodTableat all.This hasn't been recognized since
abstract_invokedidn't usethe
method_tableinterface properly until #44389 ,but now we need this support.
xref: JuliaGPU/GPUCompiler.jl#303 (comment)