Skip to content
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

AbstractInterpreter: implement findsup for OverlayMethodTable #44448

Merged
merged 1 commit into from
Mar 7, 2022

Conversation

aviatesk
Copy link
Member

@aviatesk aviatesk commented Mar 4, 2022

Previously findsup doesn't support OverlayMethodTable at all.
This hasn't been recognized since abstract_invoke didn't use
the method_table interface properly until #44389 ,
but now we need this support.

xref: JuliaGPU/GPUCompiler.jl#303 (comment)

base/compiler/methodtable.jl Outdated Show resolved Hide resolved
base/reflection.jl Outdated Show resolved Hide resolved
Comment on lines 110 to 111
min_valid[] = typemin(UInt)
max_valid[] = typemax(UInt)
Copy link
Member

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

Suggested change
min_valid[] = typemin(UInt)
max_valid[] = typemax(UInt)

Copy link
Member Author

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.

Copy link
Member

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

end

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
Copy link
Member

@vtjnash vtjnash Mar 5, 2022

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)

Copy link
Member Author

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aviatesk added a commit that referenced this pull request Mar 6, 2022
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.
aviatesk added a commit that referenced this pull request Mar 7, 2022
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.
aviatesk added a commit that referenced this pull request Mar 7, 2022
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.
@aviatesk aviatesk merged commit 9a48dc1 into master Mar 7, 2022
@aviatesk aviatesk deleted the avi/overlayedfindsup branch March 7, 2022 04:16
aviatesk added a commit that referenced this pull request Mar 7, 2022
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.
aviatesk added a commit to JuliaDebug/JuliaInterpreter.jl that referenced this pull request Mar 7, 2022
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.
aviatesk added a commit to JuliaDebug/JuliaInterpreter.jl that referenced this pull request Mar 7, 2022
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)
Copy link
Member

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

Copy link
Member Author

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_methods returns 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

Comment on lines +66 to +67
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)),
Copy link
Member

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
Copy link
Member

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[]))
Copy link
Member

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.

aviatesk added a commit that referenced this pull request Mar 8, 2022
- 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`
aviatesk added a commit that referenced this pull request Mar 9, 2022
- 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`
aviatesk added a commit that referenced this pull request Mar 9, 2022
- 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`
@aviatesk aviatesk mentioned this pull request Mar 9, 2022
47 tasks
aviatesk added a commit that referenced this pull request Mar 9, 2022
#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`
aviatesk added a commit that referenced this pull request Mar 9, 2022
#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`
aviatesk added a commit that referenced this pull request Mar 9, 2022
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.
aviatesk added a commit that referenced this pull request Mar 9, 2022
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.
@aviatesk aviatesk added the backport 1.8 Change should be backported to release-1.8 label Mar 14, 2022
aviatesk added a commit that referenced this pull request Mar 15, 2022
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.
@KristofferC KristofferC removed the backport 1.8 Change should be backported to release-1.8 label Mar 15, 2022
aviatesk added a commit that referenced this pull request Mar 16, 2022
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.
aviatesk added a commit that referenced this pull request May 6, 2022
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.
aviatesk added a commit that referenced this pull request Nov 28, 2022
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.
aviatesk added a commit that referenced this pull request Nov 28, 2022
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.
aviatesk added a commit that referenced this pull request Nov 28, 2022
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.
aviatesk added a commit that referenced this pull request Nov 29, 2022
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.
aviatesk added a commit that referenced this pull request Nov 29, 2022
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants