-
-
Notifications
You must be signed in to change notification settings - Fork 25.9k
MAINT Introduce dispatchers for PairwiseDistancesReductions
#23515
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
MAINT Introduce dispatchers for PairwiseDistancesReductions
#23515
Conversation
Those interfaces are meant to be used in the Python code, decoupling the actual implementation from the Python code. This allows changing all the private implementation while maintaining a contract for the Python callers. Each interface extending the base `PairwiseDistancesReduction` interface must implement the :meth:`compute` classmethod. Under the hood, such a function must only define the logic to dispatch at runtime to the correct dtype-specialized `PairwiseDistancesReduction` implementation based on the dtype of X and of Y. This refactoring will ease other dtype support such as float32 support.
I am not opposed to that. There is a bunch of tests that fail. I did not investigate. Please feel free to ping me for a review once those are fixed. I don't know if fixing them has an impact on the design of the refactoring or not. |
PairwiseDistancesReductions
PairwiseDistancesReductions
PairwiseDistancesReductions
PairwiseDistancesReductions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with making a submodule in which the dispatchers are separated from the implementations.
As discussed irl, the dispatchers can probably be made standard python classes now (the implementations doesn't need to inherit from PairwiseDistanceReduction
.
… with some ASCII art. 🎨 Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
Co-authored-by: Jérémie du Boisberranger <jeremiedbb@users.noreply.github.com>
Done in cd49d8a. I've done the full private module refactoring (see jjerphan#14 which targets the branch of this PR). As this refactoring is quite large, I would submit it in another PR. @ogrisel think it's fine to have it integrated in this PR. Let me know whether I should introduce this refactoring in this PR or submit it in another PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class hierarchy design and the updated documentation look (very) good to me.
The top level dispatchers could be Python classes instead of Cython classes but we can change that later if we prefer. No strong opinion.
EDIT: this point was addressed in jjerphan#14
I think we can merge this PR to main
first (before doing the multi-file split of the module) if you or @jeremiedbb prefer. I don't mind either options.
Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
Note that this was addressed in this PR via cd49d8a (which is also present in the follow-up PR, jjerphan#14). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm overall happy with this type of refactor. Moving the Cython data structures down to the implementation, allowing for the dispatcher to be in regular Python makes sense to me.
@@ -764,11 +1160,11 @@ cdef class PairwiseDistancesArgKmin(PairwiseDistancesReduction): | ||
Y_start + j, | ||
) | ||
|
||
@final |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does removing the @final
here lead to any performance regressions for metrics that is not euclidean
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment. This needs to be assessed.
IIRC from my experiments, optimisations provided by @final
mainly comes on classes that do not make use of polymorphism (but we do use polymorphism here).
It's more a matter of implementation explicitness: the usage of @final
on methods indicates that this method is not overwritten in any subclass (similarly the usage of @final
on classes indicates that those classes aren't extended).
In overall, I think we must check for any performance regression before merging this PR.
I'm ok with merging this PR first and follow up with reorganizing into a submodule. |
Co-authored-by: Jérémie du Boisberranger <jeremiedbb@users.noreply.github.com> Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
No regression on a machine with 256 threads for the
|
No regression on a machine with 256 threads for the
|
Thanks for checking the performance. +1 again for merge on my side. @thomasjpfan @jeremiedbb anything else? |
I removed the blocker label as it's meant to only be used to label bugs that should be fixed before making a specific release. Here is this not a bug (it's a performance improvement) and its not blocking any particular release. It's blocking progress on follow-up PRs but we don't have a label for that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Let's merge
Thanks @jjerphan. I guess you can now make a PR targeting main out of jjerphan#14 |
Thanks. The follow-up is reviewable: #23724 |
…-learn#23515) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Jérémie du Boisberranger <jeremiedbb@users.noreply.github.com> Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com>
Reference Issues/PRs
Logic extracted from #22590 mainly to discuss design independently from 32bit support.
What does this implement/fix? Explain your changes.
This PR introduces Python interfaces.
Those dispatcher are meant to be used in the Python code, decoupling the actual implementation from the Python code. This allows changing all the private implementation while maintaining a contract for the Python callers.
Each dispatcher extending the base
PairwiseDistancesReduction
dispatcher must implement thecompute
classmethod.Under the hood, such a function must only define the logic to dispatch at runtime to the correct dtype-specialized
PairwiseDistancesReduction
implementation based on the dtype of X and of Y.This refactoring will ease other dtype support such as float32 support and implementations are mostly left unchanged (a few empty callback have been introduced based on some changes made to
GEMMTermComputer64
).Remarks / points to discuss
GEMMTermComputer
has been suffixed, moved upward in the file and extended a bit for consistency and to introduce new dtype-specific implementation more easily.Regarding naming: currently, interfaces took the name of previous implementations and new implementations are solely suffixed with
64
. I think this naming could be improved.I think it's time to create a private submodule consisting of several files for
PairwiseDistancesReductions
.