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

Fix numba.typed.List extend for singleton and empty iterable #5517

Merged
merged 5 commits into from Apr 23, 2020

Conversation

esc
Copy link
Member

@esc esc commented Apr 7, 2020

Fixes #5152

esc added 2 commits April 7, 2020 09:53
Fixes numba#5152

An implicit assumption was being made about the length of the iterable
when refining with extend. Specifically, this assumtion was that the
iterable has lenth >= 2. The code would however fail if the length is 1,
so this commit fixes that. Tests included.
This allows an untyped List to be extended with an empty iterable in the
interpreter. This is results in a NO-OP and is probably unlikely to
occur often in practice but is fixed for completeness. Tests included.
@esc esc added this to the Numba 0.50RC milestone Apr 7, 2020
@esc esc added this to In progress in numba.typed.List Apr 7, 2020
@stuartarchibald stuartarchibald changed the title Fix numba.typed.List extend for sinngleton and empty iterable Fix numba.typed.List extend for singleton and empty iterable Apr 7, 2020
A `numba.typed.List` that is refined failed to extend on an empty
iterable. This fixes that to be a NO-OP and includes tests.
@@ -729,6 +729,33 @@ def impl():
got = impl()
self.assertEqual(expected, got)

def test_extend_singleton(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Where's the singleton? Do you mean, "container holding single value"?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, I was under the impression, that the term 'singleton' could be used to describe such a construct, but perhaps I was mistaken. Is there something shorter than "container holding single value"?

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems, overwhelmingly, singleton refers to the singleton pattern, with the exception of tuple, https://docs.python.org/3/library/stdtypes.html#tuple.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for looking into this. So it seems that use of the term 'singleton' in this context is perhaps permissible. In any case to avoid any future ambiguities I think it will be best to rename the test, how about 'single_value_container'?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@esc esc added bug 4 - Waiting on reviewer Waiting for reviewer to respond to author and removed 3 - Ready for Review labels Apr 12, 2020
@stuartarchibald stuartarchibald added 4 - Waiting on author Waiting for author to respond to review and removed bug 4 - Waiting on reviewer Waiting for reviewer to respond to author labels Apr 13, 2020
The 'term' singleton may not have been the appropriate choice here.
@esc esc 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 14, 2020
@esc
Copy link
Member Author

esc commented Apr 14, 2020

@stuartarchibald this one is fixed up too and ready for the next round of reviews.

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.

I've taken a look at the patch. Few comments to resolve but looks like this should fix the issue. Thanks.

Comment on lines +744 to +748
# Extending an unrefined list with an empty iterable doesn't work in a
# jit compiled function as the list remains untyped.
l = List()
l.extend(tuple())
self.assertEqual(len(l), 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this behaviour a good idea? What about JIT transparency etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, if you put this in a JIT compiled function, you get:

Invalid use of Function(<function impl_extend at 0x7f5648715c10>) with argument(s) of type(s): (ListType[undefined], Tuple())
 * parameterized
In definition 0:
    TypingError: extend argument must be iterable

empty tuples are iterable, this is a bit confusing. I think it's arising because an empty tuple is typed as Tuple at present, which is not iterable for Numba's purposes.

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 only UniTuple is iterable. I struggled with this one for some time and came to the conclusion that this is a corner case that only works outside of a jit context.

Copy link
Member Author

Choose a reason for hiding this comment

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

So, even if tuple() would be something iterable, the function would not compile as the list can not be refined.

Comment on lines 367 to 372
self.append(iterable[0])
return _extend(self, iterable[1:])
return _extend(self, iterable)
# Iterable has more values to extend from
if iterable_length > 1:
return _extend(self, iterable[1:])
else:
return self
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this just be:

            self._initialise_list(iterable[0])
            return _extend(self, iterable)

i.e. init type, then extend, is there a need to append then slice from 1?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this can be significantly simplified.

This simplifies the logic needed to implement `extend`.
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.

Thanks for the fixes, looks good.

@stuartarchibald stuartarchibald added 5 - Ready to merge Review and testing done, is ready to merge and removed 4 - Waiting on reviewer Waiting for reviewer to respond to author labels Apr 22, 2020
@esc
Copy link
Member Author

esc commented Apr 22, 2020

@stuartarchibald awesome, thanks for the review!

@sklam sklam merged commit 1dabbf6 into numba:master Apr 23, 2020
@esc
Copy link
Member Author

esc commented Apr 24, 2020

thanks for merge

@esc esc moved this from In progress to Done in numba.typed.List May 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5 - Ready to merge Review and testing done, is ready to merge
Projects
Development

Successfully merging this pull request may close these issues.

typed list fails to refine with tuple in interpreter
3 participants