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

Introduce context.call_overload and raise dynamic exception in guard_match_core_dims #9524

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

guilhermeleobas
Copy link
Collaborator

PR is separated into four commits:

  • 02d0d45: Add overload_method(UniTuple, '__str__') and tests
  • 0be554f: Add context.call_overload
  • 2c4324e: Update guard_match_core_dims to call an overload that can emit a dynamic exception
  • cd14d40: remove tupleobj.py from .flake8

@guilhermeleobas guilhermeleobas force-pushed the guilhermeleobas/gufunc_call_overload branch from cd14d40 to 9dc97bd Compare April 5, 2024 18:47
@guilhermeleobas guilhermeleobas changed the title Introduce context.call_overload Introduce context.call_overload and raise dynamic exception in guard_match_core_dims Apr 5, 2024
@guilhermeleobas guilhermeleobas force-pushed the guilhermeleobas/gufunc_call_overload branch from d388c18 to 7d50fe1 Compare April 5, 2024 19:55
@gmarkall
Copy link
Member

gmarkall commented Apr 8, 2024

Checking - is this still a draft?

@guilhermeleobas guilhermeleobas marked this pull request as ready for review April 8, 2024 14:31
@guilhermeleobas
Copy link
Collaborator Author

Oh, sorry! It's ready for review.

@gmarkall gmarkall requested a review from sklam April 9, 2024 14:22
@gmarkall gmarkall added this to the 0.61.0-rc1 milestone Apr 9, 2024
Copy link
Contributor

@stuartarchibald stuartarchibald left a comment

Choose a reason for hiding this comment

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

Many thanks for the patch @guilhermeleobas, it's good to see that the dynamic exceptions work can enhance error messages like this. I've made a few comments inline, my greatest concerns at present are ensuring that the call_overload API is appropriate and also that the error messages being generated are as clear and informative as possible. Thanks again!

docs/upcoming_changes/9524.new_feature.rst Outdated Show resolved Hide resolved
docs/upcoming_changes/9524.new_feature.rst Outdated Show resolved Hide resolved
@@ -904,6 +904,15 @@ def call_internal_no_propagate(self, builder, fndesc, sig, args):
sig.args, args)
return status, res

def call_overload(self, builder, impl, sig, args):
Copy link
Contributor

Choose a reason for hiding this comment

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

I've written an almost identical call_overload locally as part of a large ufunc refactoring effort. I elected for it to take sig.args / an argument tuple opposed to a signature. When an overload is resolved, the return type is a function of the implementation, opposed to what is prescribed by a signature, this API perhaps suggests otherwise?

numba/cpython/tupleobj.py Outdated Show resolved Hide resolved
@lower_constant(types.Tuple)
@lower_constant(types.NamedTuple)
def unituple_constant(context, builder, ty, pyval):
def unituple_constant_(context, builder, ty, pyval):
Copy link
Contributor

Choose a reason for hiding this comment

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

Why has this gained an underscore at the end?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

flake8, I believe

@@ -297,7 +302,8 @@ def raise_impl(self_shape, other_shape):
)
tup = (context.make_tuple(builder, sig.args[0], self.shape),
context.make_tuple(builder, sig.args[1], other.shape),)
context.compile_internal(builder, raise_impl, sig, tup)
context.typing_context.refresh()
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does the typing context need refreshing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Function is declared inside the scope of guard_match_core_dim. If the typing context is not refreshed, Numba fails at a later stage:

  File "/Users/guilhermeleobas/git/numba/numba/np/npyimpl.py", line 624, in numpy_gufunc_kernel
    arg_a.guard_match_core_dims(ufunc, arg_b, idx_a, idx_b)
  File "/Users/guilhermeleobas/git/numba/numba/np/npyimpl.py", line 308, in guard_match_core_dims
    context.call_overload(builder, raise_impl, sig, tup)
  File "/Users/guilhermeleobas/git/numba/numba/core/base.py", line 911, in call_overload
    fnty = self.typing_context.resolve_value_type(impl)
  File "/Users/guilhermeleobas/git/numba/numba/core/typing/context.py", line 397, in resolve_value_type
    raise typeof_exc
ValueError: Cannot determine Numba type of <class 'function'>

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. If it's possible for the call_overload function to fail due to inconsistent state in the typing registries, should a typing context refresh be made unconditionally at the start of the the call_overload function implementation to prevent this from ever happening?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Wouldn't that be too slow? Refreshing the typing context is not needed if the function is declared in the global scope.

Comment on lines 739 to 741
msg = ('operand 0 has a mismatch with operand 1 one of its core '
'dimension(s), with bar signature (n),(n) -> () '
'(shape (5, 3, 2) is different from (3))')
Copy link
Contributor

Choose a reason for hiding this comment

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

The information content is a great improvement, but I'm struggling to understand what this means in its current form. Is it possible to match the NumPy message (and maybe enhance it with shape info/function names)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've changed the exception message to match NumPy. That would probably be less confusing(?)

@stuartarchibald stuartarchibald added 4 - Waiting on author Waiting for author to respond to review and removed 3 - Ready for Review labels Apr 24, 2024
@guilhermeleobas guilhermeleobas added 4 - Waiting on reviewer Waiting for reviewer to respond to author and removed 4 - Waiting on author Waiting for author to respond to review labels Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4 - Waiting on reviewer Waiting for reviewer to respond to author
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants