Repository navigation
Support for boxing SliceLiteral type - #7714
Conversation
guilhermeleobas
left a comment
There was a problem hiding this comment.
Hi Nick, thanks for working on this.
|
Think this needs fixing: from numba import njit
z = slice(1, 2, 3)
@njit
def foo():
return z
foo()via: diff --git a/numba/core/pythonapi.py b/numba/core/pythonapi.py
index 79ca776..6dad042 100644
--- a/numba/core/pythonapi.py
+++ b/numba/core/pythonapi.py
@@ -663,7 +663,7 @@ class PythonAPI(object):
# Concrete slice API
#
def slice_new(self, start, stop, step):
- fnty = Type.function(self.pyobj, [self.pyobj, self.pyobj, self.pyobj])
+ fnty = ir.FunctionType(self.pyobj, [self.pyobj, self.pyobj, self.pyobj])
fn = self._get_function(fnty, name="PySlice_New")
return self.builder.call(fn, [start, stop, step]) |
|
Thanks @stuartarchibald. I fixed the issue. In addition, I found a couple other places where Type was still used so I fixed them in this PR as well. |
stuartarchibald
left a comment
There was a problem hiding this comment.
Thanks for the patch @njriasan and for reviewing @guilhermeleobas. I've given this a bit more of a review and left some comments in line, most should be relatively quick to resolve. Thanks again.
| slice_lit = typ.literal_value | ||
| slice_fields = [] | ||
| for field_name in ("start", "stop", "step"): | ||
| field_obj = getattr(slice_lit, field_name) | ||
| field_val = ( | ||
| c.pyapi.make_none() | ||
| if field_obj is None | ||
| else c.pyapi.from_native_value( | ||
| types.literal(field_obj), field_obj, c.env_manager | ||
| ) | ||
| ) | ||
| slice_fields.append(field_val) | ||
| slice_val = c.pyapi.slice_new(*slice_fields) | ||
| for field_obj in slice_fields: | ||
| c.pyapi.decref(field_obj) | ||
| return slice_val |
There was a problem hiding this comment.
Something like this might also work?
@box(types.SliceLiteral)
def box_slice_literal(typ, val, c):
py_ctor, py_args = typ.literal_value.__reduce__()
serialized_ctor = c.pyapi.serialize_object(py_ctor)
serialized_args = c.pyapi.serialize_object(py_args)
ctor = c.pyapi.unserialize(serialized_ctor)
args = c.pyapi.unserialize(serialized_args)
obj = c.pyapi.call(ctor, args)
c.pyapi.decref(ctor)
c.pyapi.decref(args)
return objavoids needing to add slice_new to the pyapi too.
There was a problem hiding this comment.
@stuartarchibald I'm happy to update this code if you would like but I don't understand why this change is necessary/preferred. Is there a concern that creating native literals will have gaps/performs worse?
@njriasan many thanks for fixing the other places where |
|
@stuartarchibald I made all of the requested changes except the serialization change to boxing because I don't understand the benefit of the change. I'm happy to refactor the code but I'd like to understand the reason for the change. I also made one additional change to |
I think it would be good to add a test using the reproducer from #7714 (comment) -- if feasible. |
I managed to consult Stuart in an OOB conversation today and the idea is that the suggested code is simpler and easier to maintain. There are not many references to clean up and we don't need to add the |
esc
left a comment
There was a problem hiding this comment.
I'm helping out with the review in order for the PR to make it into 0.56 -- I reviewed all the comments and checked that all of @stuartarchibald 's comments have been addressed, except the comment about the core boxing implementation. I also left a comment regarding a potential test that could be added.
I think once these two changes have been made this is ready to merge. Thank you!!
PS: if you are running out of time, please do let me know, I'd be happy to volunteer to make the requested changes.
|
@esc I think I have addressed all of the comments. |
|
@njriasan thank you for the changes. I have given the following two commits a quick performance test: using And with So that would indicate a performance hit -- but since this is in the nano-second range, I am not sure how reproducible these microbenchmarks are and how influential they will be. |
|
@esc I think since a slice won't ever scale beyond 3 elements and we are talking about nanoseconds, this is probably fine. However, I also don't consider the original implementation to be too complicated, so I would be fine with either decision. |
I just saw your message on gitter. I agree the performance difference seems fine. |
OK, awesome, marking as Ready To Merge (RTM) now. |
|
Thank you for the patch! |
Support boxing directly with a SliceLiteral. This fixes the example in #7707.