Skip to content

Commit fe7c4d0

Browse files
authored
Merge branch 'branch-25.04' into r2-score-compat
2 parents 96c9e7d + 272c686 commit fe7c4d0

10 files changed

Lines changed: 101 additions & 19 deletions

File tree

.github/CODEOWNERS

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ CMakeLists.txt @rapidsai/cuml-cmake-codeowners
1212
#CI code owners
1313
/.github/ @rapidsai/ci-codeowners
1414
/ci/ @rapidsai/ci-codeowners
15-
/.pre-commit-config.yaml @rapidsai/ci-codeowners
1615

1716
#packaging code owners
18-
/.devcontainer/ @rapidsai/packaging-codeowners
19-
/conda/ @rapidsai/packaging-codeowners
20-
/dependencies.yaml @rapidsai/packaging-codeowners
21-
/build.sh @rapidsai/packaging-codeowners
22-
pyproject.toml @rapidsai/packaging-codeowners
17+
/.pre-commit-config.yaml @rapidsai/packaging-codeowners
18+
/.devcontainer/ @rapidsai/packaging-codeowners
19+
/conda/ @rapidsai/packaging-codeowners
20+
dependencies.yaml @rapidsai/packaging-codeowners
21+
/build.sh @rapidsai/packaging-codeowners
22+
pyproject.toml @rapidsai/packaging-codeowners

.pre-commit-config.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ repos:
6565
pass_filenames: false
6666
language: python
6767
- repo: https://github.com/rapidsai/pre-commit-hooks
68-
rev: v0.4.0
68+
rev: v0.5.0
6969
hooks:
7070
- id: verify-copyright
7171
files: |
@@ -80,6 +80,8 @@ repos:
8080
cpp/src/tsne/cannylab/bh[.]cu$|
8181
python/cuml/cuml/_thirdparty
8282
- id: verify-alpha-spec
83+
- id: verify-codeowners
84+
args: [--fix, --project-prefix=cuml]
8385
- repo: https://github.com/rapidsai/dependency-file-generator
8486
rev: v1.17.0
8587
hooks:
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
2-
# Copyright (c) 2024, NVIDIA CORPORATION.
2+
# Copyright (c) 2024-2025, NVIDIA CORPORATION.
33

44
# Support invoking run_cuml_singlegpu_pytests.sh outside the script directory
55
cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../python/cuml/cuml/tests/experimental/accel
66

7-
python -m pytest -p cuml.experimental.accel --cache-clear "$@" .
7+
python -m pytest -p cuml.accel --cache-clear "$@" .

python/cuml/cuml/accel/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#
2+
# Copyright (c) 2025, NVIDIA CORPORATION.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
from cuml.experimental.accel import (
18+
install,
19+
load_ipython_extension,
20+
pytest_load_initial_conftests,
21+
)

python/cuml/cuml/accel/__main__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#
2+
# Copyright (c) 2025, NVIDIA CORPORATION.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
from cuml.experimental.accel.__main__ import main
18+
19+
20+
if __name__ == "__main__":
21+
main()

python/cuml/cuml/internals/api_decorators.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,32 @@ def _find_arg(sig, arg_name, default_position):
5555

5656
# Check for default name in input args
5757
if arg_name in sig.parameters:
58-
return arg_name, params.index(arg_name)
58+
param = sig.parameters[arg_name]
59+
return arg_name, params.index(arg_name), param.default
5960
# Otherwise use argument in list by position
6061
elif arg_name is ...:
6162
index = int(_has_self(sig)) + default_position
62-
return params[index], index
63+
param = params[index]
64+
return param, index, sig.parameters[param].default
6365
else:
6466
raise ValueError(f"Unable to find parameter '{arg_name}'.")
6567

6668

67-
def _get_value(args, kwargs, name, index):
69+
def _get_value(args, kwargs, name, index, default_value):
6870
"""Determine value for a given set of args, kwargs, name and index."""
6971
try:
7072
return kwargs[name]
7173
except KeyError:
7274
try:
7375
return args[index]
7476
except IndexError:
75-
raise IndexError(
76-
f"Specified arg idx: {index}, and argument name: {name}, "
77-
"were not found in args or kwargs."
78-
)
77+
if default_value is not inspect._empty:
78+
return default_value
79+
else:
80+
raise IndexError(
81+
f"Specified arg idx: {index}, and argument name: {name}, "
82+
"were not found in args or kwargs."
83+
)
7984

8085

8186
def _make_decorator_function(
@@ -166,7 +171,7 @@ def wrapper(*args, **kwargs):
166171
if self_val is None:
167172
assert input_val is not None
168173
out_type = iu.determine_array_type(input_val)
169-
elif input_val is None:
174+
elif input_val is None or input_val is inspect._empty:
170175
out_type = self_val.output_type
171176
if out_type == "input":
172177
out_type = self_val._input_type

python/cuml/cuml/internals/input_utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2019-2024, NVIDIA CORPORATION.
2+
# Copyright (c) 2019-2025, NVIDIA CORPORATION.
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -530,6 +530,8 @@ def input_to_host_array(
530530

531531

532532
def input_to_host_array_with_sparse_support(X):
533+
if X is None:
534+
return None
533535
try:
534536
if scipy_sparse.isspmatrix(X):
535537
return X

python/cuml/cuml/neighbors/nearest_neighbors.pyx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2019-2024, NVIDIA CORPORATION.
2+
# Copyright (c) 2019-2025, NVIDIA CORPORATION.
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import math
2828
import cuml.internals
2929
from cuml.internals.base import UniversalBase
3030
from cuml.common.array_descriptor import CumlArrayDescriptor
31+
from cuml.internals import api_base_return_generic
3132
from cuml.internals.array import CumlArray
3233
from cuml.internals.array_sparse import SparseCumlArray
3334
from cuml.common.doc_utils import generate_docstring
@@ -691,6 +692,9 @@ class NearestNeighbors(UniversalBase,
691692
if out_type in {'cupy', 'numpy', 'numba'}:
692693
I_ndarr = I_ndarr[:, 1:]
693694
D_ndarr = D_ndarr[:, 1:]
695+
elif out_type == "cuml":
696+
I_ndarr = CumlArray.from_input(I_ndarr[:, 1:], force_contiguous=True)
697+
D_ndarr = CumlArray.from_input(D_ndarr[:, 1:], force_contiguous=True)
694698
else:
695699
I_ndarr.drop(I_ndarr.columns[0], axis=1)
696700
D_ndarr.drop(D_ndarr.columns[0], axis=1)

python/cuml/cuml/tests/experimental/accel/test_basic_estimators.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,18 @@ def test_proxy_facade():
173173
assert original_value == proxy_value
174174

175175

176+
def test_defaults_args_only_methods():
177+
# Check that estimator methods that take no arguments work
178+
# These are slightly weird because basically everything else takes
179+
# a X as input.
180+
X = np.random.rand(1000, 3)
181+
y = X[:, 0] + np.sin(6 * np.pi * X[:, 1]) + 0.1 * np.random.randn(1000)
182+
183+
nn = NearestNeighbors(metric="chebyshev", n_neighbors=3)
184+
nn.fit(X[:, 0].reshape((-1, 1)), y)
185+
nn.kneighbors()
186+
187+
176188
def test_kernel_ridge():
177189
rng = np.random.RandomState(42)
178190

python/cuml/cuml/tests/experimental/accel/test_pipeline.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
KNeighborsClassifier,
3232
KNeighborsRegressor,
3333
)
34+
from sklearn.preprocessing import Normalizer
3435
from sklearn.pipeline import Pipeline, make_pipeline
3536
from sklearn.datasets import make_classification, make_regression
3637
from sklearn.model_selection import train_test_split
3738
from sklearn.metrics import accuracy_score, mean_squared_error
3839
from umap import UMAP
3940
import hdbscan
4041
import numpy as np
42+
import scipy as sp
4143

4244

4345
@pytest.fixture
@@ -154,3 +156,16 @@ def test_automatic_step_naming():
154156

155157
assert "pca" in pipeline.named_steps
156158
assert "logisticregression" in pipeline.named_steps
159+
160+
161+
def test_pipeline_adding_none_value_as_labels(classification_data):
162+
X_train, _, _, _ = classification_data
163+
X_train = sp.sparse.csr_matrix(X_train)
164+
165+
# Since cuML's TruncatedSVD does not handle sparse data,
166+
# the task will be automatically dispatched to Scikit-Learn.
167+
# If no labels are provided, Scikit-Learn's pipeline adds
168+
# y=None as the default labels.
169+
170+
pipeline = make_pipeline(TruncatedSVD(n_components=20))
171+
pipeline.fit_transform(X_train)

0 commit comments

Comments
 (0)