Skip to content

Add numpy argpartition function support - #8732

Merged
sklam merged 5 commits into
numba:mainfrom
rragundez:np-argpartition
Feb 25, 2023
Merged

sklam merged 5 commits into
numba:mainfrom
rragundez:np-argpartition

Conversation

@rragundez

@rragundez rragundez commented Jan 28, 2023 •

Copy link
Copy Markdown

Add numpy argpartition function support.

I used some of the implementation of partition. Something to note it that I modified the already existing _partition_factory to add an optional argument if the user would need np.argpartition instead of np.partition, as you will see in the code it doesn't look the most pretty, but it was either that or write a _argpartition_factory function which has exactly the same logic it just swaps index elements at the same time it swaps the array with the values being sorted.

Let me know if you prefer to leave it as is or go the duplication route. I think this is the best compromise to not repeat code and have a single source of truth of partition logic.

Solves #2445
#4074 would need to be updated.

cheers

@kc611 kc611 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @rragundez , Thank you for the PR 😄 . Your contributions to Numba are highly appreciated.

I gave the PR an initial review and it mostly LGTM!

A few points to note:

  1. The logic does seem a bit off within the _partition_factory/_partition, but as you mentioned and from a maintainer's point of view, it's less code to manage and reuses existing logic so it does makes sense to keep it this way.

  2. The np.argpartition, based on the existing np.partition logic does seem to deviate from NumPy behaviour, they are implemented using different algorithms (see #3320 (comment) for original np.partition implementation discussion) and whilst this might seem a bit implicit, since the ordering of the elements in the two partitions is supposed to be undefined, but it might be a good idea to mention the behaviour in the docs that the outputs may deviate from NumPy.

@kc611 kc611 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A small suggestion regarding default function arguments.

On this note is there any particular reason you went with the default argument for idx being np.arange(0) ?

Comment thread numba/np/arraymath.py Outdated
Comment thread numba/np/arraymath.py Outdated
Comment thread numba/np/arraymath.py Outdated
@rragundez

rragundez commented Jan 30, 2023 •

Copy link
Copy Markdown
Author

@kc611 Thanks for your review and feedback.
I also do not like it at all, but since the function is passed to register_jitable it needs to make sense of the types of the variables and if left with default as None it cannot make sense of the None type and the array of type int64 which I or idx can become. So I decided to use the np.arange(0) as default value which is an empty array of type int64.
Does that make sense? Let me know what you think.

@guilhermeleobas guilhermeleobas added 4 - Waiting on reviewer Waiting for reviewer to respond to author and removed 3 - Ready for Review labels Jan 31, 2023
@rragundez

Copy link
Copy Markdown
Author

@kc611 Hi, did you have time to check my remark? perhaps I am wrong but that behaviour I describe is what I noticed when developing the PR.

@kc611

kc611 commented Feb 7, 2023 •

Copy link
Copy Markdown
Contributor

Hi @rragundez, apologies for the delay. Following a small internal discussion, it'd be better for us to go with None as default argument. The reason being; having mutable default arguments is generally not recommended for Python functions due to the kind of unexpected behaviours it leads to, down the line.

Additionally, the type inference within Numba is expected to figure out if the argument type is None and prune the branches accordingly during compile time.

@kc611 kc611 added 4 - Waiting on author Waiting for author to respond to review and removed 4 - Waiting on reviewer Waiting for reviewer to respond to author labels Feb 7, 2023
@rragundez

Copy link
Copy Markdown
Author

@kc611 Yeap, agree with the Python anti-pattern. I will make the changes and let's see what the the CI says, hopefully I made come mistake when testing and it will be able to resolve the None type.

@rragundez

rragundez commented Feb 7, 2023 •

Copy link
Copy Markdown
Author

@kc611 done, please review. I think the CI is failing with an issue related to what I mentioned above, let me know what should I do to solve it or if I should revert back. Thanks.

@rragundez

Copy link
Copy Markdown
Author

@kc611 By the way I just remembered that indeed is a bad practice to set default parameters that are mutable but even though numpy arrays are mutable, an array of size 0 is immutable because it has no elements to change, and numpy arrays are of fixed size, therefore the default value of an int array of size zero is immutable. Let me know if this makes sense and how you would like me to proceed.

@rragundez
rragundez requested review from kc611 and removed request for sklam and stuartarchibald February 10, 2023 08:51

@kc611 kc611 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @rragundez , Thank you for making the changes. 😃 . I think the reason for failure is that Numba isn't able to infer I as None during compile time and ends up trying to lower the branches with argpartition boolean. A way around this would be to make argpartition a compile time constant instead of runtime, this would make sure branch pruner absolutely removes the branches with the given boolean so that they aren't lowered into IR.

I agree that an array of size 0 is immutable because it has no elements to change, but we can actually change it's attributes making it a 'mutable as a structure'. 🙂 However, the issue at hand is that this practice is generally not recommended and even more so in Numba because it might lead to weird and unexpected IR issues down the line, even if it seems to work just fine right now.

Comment thread numba/np/arraymath.py Outdated
Comment thread numba/np/arraymath.py Outdated
Comment thread numba/np/arraymath.py
Comment thread numba/np/arraymath.py
Comment thread numba/np/arraymath.py Outdated
@rragundez

Copy link
Copy Markdown
Author

@kc611 thanks for the feedback. I made the requested changes and the CI is passing now. Please review.

@kc611 kc611 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @rragundez, these changes LGTM!

@rragundez

Copy link
Copy Markdown
Author

@kc611 Thanks for the approval. I cannot merge though, still says "Merging is blocked Merging can be performed automatically with 1 approving review."

@rragundez

Copy link
Copy Markdown
Author

Hi @kc611, can you help me understand if this PR will be able to be merged? Thanks.

@stuartarchibald stuartarchibald 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 Feb 23, 2023
@kc611 kc611 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 Effort - medium Medium size effort needed labels Feb 23, 2023
@sklam sklam added this to the Numba 0.57 RC milestone Feb 25, 2023
@sklam
sklam merged commit de4cd6c into numba:main Feb 25, 2023
@rragundez
rragundez deleted the np-argpartition branch February 25, 2023 01:06
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 numpy

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants