Skip to content

FIX sklearn sample_weights checks for cupy and numpy<2 - #102

Open
kroq-gar78 wants to merge 1 commit into
gallantlab:mainfrom
kroq-gar78:fix-cupy-sample_weights
Open

FIX sklearn sample_weights checks for cupy and numpy<2#102
kroq-gar78 wants to merge 1 commit into
gallantlab:mainfrom
kroq-gar78:fix-cupy-sample_weights

Conversation

@kroq-gar78

@kroq-gar78 kroq-gar78 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

This PR fixes the following failing tests:

FAILED himalaya/kernel_ridge/tests/test_sklearn_api_kernel.py::test_check_estimator[cupy-KernelRidge_()-check_sample_weights_not_an_array] - TypeError: Unsupported type <class 'numpy.ndarray'>
FAILED himalaya/kernel_ridge/tests/test_sklearn_api_kernel.py::test_check_estimator[cupy-KernelRidge_()-check_sample_weights_list] - TypeError: Unsupported type <class 'numpy.ndarray'>
FAILED himalaya/kernel_ridge/tests/test_sklearn_api_kernel.py::test_check_estimator[cupy-KernelRidge_()-check_sample_weights_shape] - TypeError: Unsupported type <class 'numpy.ndarray'>
FAILED himalaya/kernel_ridge/tests/test_sklearn_api_kernel.py::test_check_estimator[cupy-KernelRidge_()-check_sample_weights_not_overwritten] - TypeError: Unsupported type <class 'numpy.ndarray'>

that had this traceback:

himalaya/kernel_ridge/_sklearn_api.py:248: in fit                                                                           
    sw = backend.asarray(sw, device=self.dual_coef_.device if hasattr(self.dual_coef_, 'device') else None)
    self.dual_coef_ = self.dual_coef_ * sw                                                                                  
cupy/_core/core.pyx:1799: in cupy._core.core._ndarray_base.__array_ufunc__                                                                                                                                                                              
    ???                                                                                                                                                                                                                                                 
cupy/_core/_kernel.pyx:1285: in cupy._core._kernel.ufunc.__call__                                                                                                                                                                                           ???                                                       
cupy/_core/_kernel.pyx:159: in cupy._core._kernel._preprocess_args                                                                                                                                                                                      
    ???                                                       
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _                                                                                                                       
                                                                                                                                                                                                                                                        >   ???                                                       
E   TypeError: Unsupported type <class 'numpy.ndarray'>

The device moving logic fails since np.ndarray doesn't support .device below version 2. This logic was introduced with the MPS backend, so we should probably test that backend before merging.

This was not an issue for numpy>2.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the device-matching logic for sample weights in himalaya/kernel_ridge/_sklearn_api.py by checking if the dual coefficients are on the GPU and moving the weights to the CPU if not. The reviewer suggests a cleaner, branchless approach using getattr(self.dual_coef_, "device", "cpu") with backend.asarray to preserve explicit device-matching behavior across multi-GPU setups and maintain compatibility with older NumPy versions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +247 to +248
if not backend.is_in_gpu(self.dual_coef_):
sw = backend.to_cpu(sw)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Instead of checking is_in_gpu and calling to_cpu, we can use getattr(self.dual_coef_, "device", "cpu") to get the device of self.dual_coef_ (defaulting to "cpu" for NumPy < 2 which lacks the .device attribute). This is cleaner, avoids branching, and preserves the explicit device-matching behavior of backend.asarray on multi-GPU setups.

Suggested change
if not backend.is_in_gpu(self.dual_coef_):
sw = backend.to_cpu(sw)
device = getattr(self.dual_coef_, "device", "cpu")
sw = backend.asarray(sw, device=device)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since this only ever moves to the CPU, and there are no device IDs for 'cpu', I think the current check is actually safer.

Comment on lines +1177 to +1178
if not backend.is_in_gpu(self.dual_coef_):
sw = backend.to_cpu(sw)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Instead of checking is_in_gpu and calling to_cpu, we can use getattr(self.dual_coef_, "device", "cpu") to get the device of self.dual_coef_ (defaulting to "cpu" for NumPy < 2 which lacks the .device attribute). This is cleaner, avoids branching, and preserves the explicit device-matching behavior of backend.asarray on multi-GPU setups.

Suggested change
if not backend.is_in_gpu(self.dual_coef_):
sw = backend.to_cpu(sw)
device = getattr(self.dual_coef_, "device", "cpu")
sw = backend.asarray(sw, device=device)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See previous comment.

@kroq-gar78
kroq-gar78 marked this pull request as ready for review June 16, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant