Support subclassing proxy estimators - #8041
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughReplaces subclass-based proxy detection with a metaclass-driven approach ( Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 9/10 reviews remaining, refill in 6 minutes. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
python/cuml/cuml_accel_tests/test_estimator_proxy.py (1)
891-923: ⚡ Quick winPlease cover the
_parameter_constraintsmutation path directly.This test proves the new MRO/type semantics, but it never exercises the actual breakage from
#7971: a downstream subclass copying or updating sklearn class metadata inherited from the proxy. A small follow-up assertion thatSub._parameter_constraintscan be copied/updated without hitting the proxy descriptor would turn this into a direct regression test for the imblearn import failure.As per coding guidelines "Update unit tests when making code changes".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@python/cuml/cuml_accel_tests/test_estimator_proxy.py` around lines 891 - 923, Add a targeted assertion that exercises the _parameter_constraints mutation path: after defining Sub(Base) and creating sub_model, attempt to copy/update Sub._parameter_constraints (e.g., assign a shallow copy or update dict/list) and assert it succeeds without triggering the proxy descriptor; reference the existing symbols Sub, Base, and _parameter_constraints and ensure the test checks that modifying Sub._parameter_constraints does not raise and results in the expected mutated value (so the new assertion directly reproduces the mutation path exercised in the imblearn import failure).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@python/cuml/cuml/accel/estimator_proxy.py`:
- Around line 135-144: The metaclass ProxyBaseMeta.__new__ omits **kwargs
causing subclass declarations with metaclass keyword args to raise TypeError;
update the __new__ method signature to def __new__(cls, name, bases, ns,
**kwargs) and forward those kwargs to super().__new__(cls, name, bases, ns,
**kwargs), keeping the existing logic that replaces base classes via
getattr(base, "_cpu_class", base) when isinstance(base, ProxyBaseMeta) so
composition with other metaclasses (and their __init_subclass__ handling) works
correctly.
---
Nitpick comments:
In `@python/cuml/cuml_accel_tests/test_estimator_proxy.py`:
- Around line 891-923: Add a targeted assertion that exercises the
_parameter_constraints mutation path: after defining Sub(Base) and creating
sub_model, attempt to copy/update Sub._parameter_constraints (e.g., assign a
shallow copy or update dict/list) and assert it succeeds without triggering the
proxy descriptor; reference the existing symbols Sub, Base, and
_parameter_constraints and ensure the test checks that modifying
Sub._parameter_constraints does not raise and results in the expected mutated
value (so the new assertion directly reproduces the mutation path exercised in
the imblearn import failure).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: e2b36d58-6990-4c5c-baf5-a82692d7a20e
📒 Files selected for processing (2)
python/cuml/cuml/accel/estimator_proxy.pypython/cuml/cuml_accel_tests/test_estimator_proxy.py
255fdf2 to
a068cb7
Compare
This adds support for subclassing proxy estimators in `cuml.accel`. Subclasses of these estimators are _not_ accelerated, since a subclass of a sklearn estimator may be built on the internals (and not the proxied public interface). To accomplish this, we add a new `ProxyBaseMeta` metaclass for `ProxyBase`. This metaclass detects when a subclass of a concrete proxy estimator is made, and swaps out the proxy classes for the concrete CPU classes instead in the subclass's MRO. It also overrides `__subclasscheck__` and `__instancecheck__` to ensure that even though the proxy class isn't in the MRO, subclasses and instances still report properly for `isinstance` and `issubclass`. This has the downside that metaclasses don't compose as well as `__init_subclass__`. The metaclass of a new class must be a (non-strict) subclass of the metaclass of all base classes. This addition means that if a user subclasses a proxy estimator and also adds in another custom metaclass, they'll still get an error. To avoid this for common cases, `ProxyBaseMeta` derives from `abc.ABCMeta`, which is maybe the most common user-used metaclass. Doing this lets `imblearn` be imported and used with `cuml.accel` active. It's a best-effort fix, and I think should be sufficient for _most_ use cases.
a068cb7 to
9e75b28
Compare
csadorf
left a comment
There was a problem hiding this comment.
LGTM! Thanks for working through this!
|
/merge |
This adds support for subclassing proxy estimators in
cuml.accel. Subclasses of these estimators are not accelerated, since a subclass of a sklearn estimator may be built on the internals (and not the proxied public interface).To accomplish this, we add a new
ProxyBaseMetametaclass forProxyBase. This metaclass detects when a subclass of a concrete proxy estimator is made, and swaps out the proxy classes for the concrete CPU classes instead in the subclass's MRO. It also overrides__subclasscheck__and__instancecheck__to ensure that even though the proxy class isn't in the MRO, subclasses and instances still report properly forisinstanceandissubclass.This has the downside that metaclasses don't compose as well as
__init_subclass__. The metaclass of a new class must be a (non-strict) subclass of the metaclass of all base classes. This addition means that if a user subclasses a proxy estimator and also adds in another custom metaclass, they'll still get an error. To avoid this for common cases,ProxyBaseMetaderives fromabc.ABCMeta, which is maybe the most common user-used metaclass.Doing this lets
imblearnbe imported and used withcuml.accelactive. It's a best-effort fix, and I think should be sufficient for most use cases.Fixes #7971.