scikit-learn-intelex 2024.1.0__py311-none-manylinux1_x86_64.whl → 2024.2.0__py311-none-manylinux1_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of scikit-learn-intelex might be problematic. Click here for more details.
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.2.0.dist-info}/METADATA +2 -2
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.2.0.dist-info}/RECORD +38 -34
- sklearnex/cluster/dbscan.py +3 -3
- sklearnex/{preview/linear_model → covariance}/__init__.py +3 -3
- sklearnex/covariance/incremental_covariance.py +130 -0
- sklearnex/covariance/tests/test_incremental_covariance.py +143 -0
- sklearnex/dispatcher.py +19 -18
- sklearnex/ensemble/_forest.py +5 -10
- sklearnex/linear_model/__init__.py +1 -2
- sklearnex/linear_model/linear.py +3 -10
- sklearnex/{preview/linear_model → linear_model}/logistic_regression.py +19 -38
- sklearnex/linear_model/tests/test_logreg.py +70 -5
- sklearnex/neighbors/__init__.py +1 -1
- sklearnex/neighbors/_lof.py +167 -0
- sklearnex/neighbors/knn_classification.py +6 -9
- sklearnex/neighbors/knn_regression.py +6 -8
- sklearnex/neighbors/knn_unsupervised.py +5 -7
- sklearnex/neighbors/tests/test_neighbors.py +12 -11
- sklearnex/preview/__init__.py +1 -1
- sklearnex/preview/cluster/k_means.py +3 -8
- sklearnex/preview/covariance/covariance.py +46 -12
- sklearnex/preview/decomposition/pca.py +3 -5
- sklearnex/spmd/__init__.py +1 -0
- sklearnex/spmd/covariance/__init__.py +19 -0
- sklearnex/spmd/covariance/covariance.py +21 -0
- sklearnex/spmd/linear_model/__init__.py +2 -1
- sklearnex/spmd/linear_model/logistic_regression.py +21 -0
- sklearnex/svm/nusvc.py +5 -6
- sklearnex/svm/nusvr.py +3 -4
- sklearnex/svm/svc.py +5 -6
- sklearnex/svm/svr.py +3 -4
- sklearnex/tests/test_memory_usage.py +1 -4
- sklearnex/tests/test_monkeypatch.py +33 -20
- sklearnex/tests/test_n_jobs_support.py +71 -9
- sklearnex/tests/test_patching.py +19 -5
- sklearnex/neighbors/lof.py +0 -436
- sklearnex/preview/linear_model/tests/test_preview_logistic_regression.py +0 -59
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.2.0.dist-info}/LICENSE.txt +0 -0
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.2.0.dist-info}/WHEEL +0 -0
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.2.0.dist-info}/top_level.txt +0 -0
|
@@ -29,18 +29,15 @@ if daal_check_version((2023, "P", 200)):
|
|
|
29
29
|
check_is_fitted,
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
-
from daal4py.sklearn.
|
|
33
|
-
|
|
34
|
-
run_with_n_jobs,
|
|
35
|
-
sklearn_check_version,
|
|
36
|
-
)
|
|
32
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
33
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
37
34
|
from onedal.cluster import KMeans as onedal_KMeans
|
|
38
35
|
|
|
39
36
|
from ..._device_offload import dispatch, wrap_output_data
|
|
40
37
|
from ..._utils import PatchingConditionsChain
|
|
41
38
|
from ._common import BaseKMeans
|
|
42
39
|
|
|
43
|
-
@control_n_jobs
|
|
40
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
44
41
|
class KMeans(sklearn_KMeans, BaseKMeans):
|
|
45
42
|
__doc__ = sklearn_KMeans.__doc__
|
|
46
43
|
n_iter_, inertia_ = None, None
|
|
@@ -212,7 +209,6 @@ if daal_check_version((2023, "P", 200)):
|
|
|
212
209
|
|
|
213
210
|
return self
|
|
214
211
|
|
|
215
|
-
@run_with_n_jobs
|
|
216
212
|
def _onedal_fit(self, X, _, sample_weight, queue=None):
|
|
217
213
|
assert sample_weight is None
|
|
218
214
|
|
|
@@ -294,7 +290,6 @@ if daal_check_version((2023, "P", 200)):
|
|
|
294
290
|
X,
|
|
295
291
|
)
|
|
296
292
|
|
|
297
|
-
@run_with_n_jobs
|
|
298
293
|
def _onedal_predict(self, X, queue=None):
|
|
299
294
|
X = self._validate_data(
|
|
300
295
|
X, accept_sparse=False, reset=False, dtype=[np.float64, np.float32]
|
|
@@ -14,32 +14,47 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
# ===============================================================================
|
|
16
16
|
|
|
17
|
+
import warnings
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
17
20
|
from scipy import sparse as sp
|
|
18
21
|
from sklearn.covariance import EmpiricalCovariance as sklearn_EmpiricalCovariance
|
|
19
22
|
from sklearn.utils import check_array
|
|
20
23
|
|
|
21
|
-
from daal4py.sklearn.
|
|
24
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
25
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
22
26
|
from onedal.common.hyperparameters import get_hyperparameters
|
|
23
27
|
from onedal.covariance import EmpiricalCovariance as onedal_EmpiricalCovariance
|
|
28
|
+
from sklearnex import config_context
|
|
29
|
+
from sklearnex.metrics import pairwise_distances
|
|
24
30
|
|
|
25
|
-
from ..._device_offload import dispatch
|
|
31
|
+
from ..._device_offload import dispatch, wrap_output_data
|
|
26
32
|
from ..._utils import PatchingConditionsChain, register_hyperparameters
|
|
27
33
|
|
|
28
34
|
|
|
29
35
|
@register_hyperparameters({"fit": get_hyperparameters("covariance", "compute")})
|
|
30
|
-
@control_n_jobs
|
|
36
|
+
@control_n_jobs(decorated_methods=["fit", "mahalanobis"])
|
|
31
37
|
class EmpiricalCovariance(sklearn_EmpiricalCovariance):
|
|
32
38
|
__doc__ = sklearn_EmpiricalCovariance.__doc__
|
|
33
39
|
|
|
40
|
+
if sklearn_check_version("1.2"):
|
|
41
|
+
_parameter_constraints: dict = {
|
|
42
|
+
**sklearn_EmpiricalCovariance._parameter_constraints,
|
|
43
|
+
}
|
|
44
|
+
|
|
34
45
|
def _save_attributes(self):
|
|
35
46
|
assert hasattr(self, "_onedal_estimator")
|
|
36
|
-
self.
|
|
47
|
+
self._set_covariance(self._onedal_estimator.covariance_)
|
|
37
48
|
self.location_ = self._onedal_estimator.location_
|
|
38
49
|
|
|
39
50
|
_onedal_covariance = staticmethod(onedal_EmpiricalCovariance)
|
|
40
51
|
|
|
41
|
-
@run_with_n_jobs
|
|
42
52
|
def _onedal_fit(self, X, queue=None):
|
|
53
|
+
if X.shape[0] == 1:
|
|
54
|
+
warnings.warn(
|
|
55
|
+
"Only one sample available. You may want to reshape your data array"
|
|
56
|
+
)
|
|
57
|
+
|
|
43
58
|
onedal_params = {
|
|
44
59
|
"method": "dense",
|
|
45
60
|
"bias": True,
|
|
@@ -54,7 +69,7 @@ class EmpiricalCovariance(sklearn_EmpiricalCovariance):
|
|
|
54
69
|
patching_status = PatchingConditionsChain(
|
|
55
70
|
f"sklearn.covariance.{class_name}.{method_name}"
|
|
56
71
|
)
|
|
57
|
-
if method_name
|
|
72
|
+
if method_name in ["fit", "mahalanobis"]:
|
|
58
73
|
(X,) = data
|
|
59
74
|
patching_status.and_conditions(
|
|
60
75
|
[
|
|
@@ -62,10 +77,6 @@ class EmpiricalCovariance(sklearn_EmpiricalCovariance):
|
|
|
62
77
|
self.assume_centered == False,
|
|
63
78
|
"assume_centered parameter is not supported on oneDAL side",
|
|
64
79
|
),
|
|
65
|
-
(
|
|
66
|
-
self.store_precision == False,
|
|
67
|
-
"precision matrix calculation is not supported on oneDAL side",
|
|
68
|
-
),
|
|
69
80
|
(not sp.issparse(X), "X is sparse. Sparse input is not supported."),
|
|
70
81
|
]
|
|
71
82
|
)
|
|
@@ -79,9 +90,9 @@ class EmpiricalCovariance(sklearn_EmpiricalCovariance):
|
|
|
79
90
|
if sklearn_check_version("1.2"):
|
|
80
91
|
self._validate_params()
|
|
81
92
|
if sklearn_check_version("0.23"):
|
|
82
|
-
self._validate_data(X)
|
|
93
|
+
X = self._validate_data(X, force_all_finite=False)
|
|
83
94
|
else:
|
|
84
|
-
check_array(X)
|
|
95
|
+
X = check_array(X, force_all_finite=False)
|
|
85
96
|
|
|
86
97
|
dispatch(
|
|
87
98
|
self,
|
|
@@ -95,4 +106,27 @@ class EmpiricalCovariance(sklearn_EmpiricalCovariance):
|
|
|
95
106
|
|
|
96
107
|
return self
|
|
97
108
|
|
|
109
|
+
# expose sklearnex pairwise_distances if mahalanobis distance eventually supported
|
|
110
|
+
@wrap_output_data
|
|
111
|
+
def mahalanobis(self, X):
|
|
112
|
+
if sklearn_check_version("1.0"):
|
|
113
|
+
X = self._validate_data(X, reset=False)
|
|
114
|
+
else:
|
|
115
|
+
X = check_array(X)
|
|
116
|
+
|
|
117
|
+
precision = self.get_precision()
|
|
118
|
+
with config_context(assume_finite=True):
|
|
119
|
+
# compute mahalanobis distances
|
|
120
|
+
dist = pairwise_distances(
|
|
121
|
+
X, self.location_[np.newaxis, :], metric="mahalanobis", VI=precision
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
return np.reshape(dist, (len(X),)) ** 2
|
|
125
|
+
|
|
126
|
+
error_norm = wrap_output_data(sklearn_EmpiricalCovariance.error_norm)
|
|
127
|
+
score = wrap_output_data(sklearn_EmpiricalCovariance.score)
|
|
128
|
+
|
|
98
129
|
fit.__doc__ = sklearn_EmpiricalCovariance.fit.__doc__
|
|
130
|
+
mahalanobis.__doc__ = sklearn_EmpiricalCovariance.mahalanobis
|
|
131
|
+
error_norm.__doc__ = sklearn_EmpiricalCovariance.error_norm.__doc__
|
|
132
|
+
score.__doc__ = sklearn_EmpiricalCovariance.score.__doc__
|
|
@@ -23,7 +23,8 @@ from sklearn.base import BaseEstimator
|
|
|
23
23
|
from sklearn.utils.extmath import stable_cumsum
|
|
24
24
|
from sklearn.utils.validation import check_array, check_is_fitted
|
|
25
25
|
|
|
26
|
-
from daal4py.sklearn.
|
|
26
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
27
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
27
28
|
from onedal.utils import _check_array
|
|
28
29
|
|
|
29
30
|
from ..._device_offload import dispatch
|
|
@@ -43,7 +44,7 @@ from onedal.decomposition import PCA as onedal_PCA
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
@register_hyperparameters({"fit": get_hyperparameters("covariance", "compute")})
|
|
46
|
-
@control_n_jobs
|
|
47
|
+
@control_n_jobs(decorated_methods=["fit", "transform"])
|
|
47
48
|
class PCA(sklearn_PCA):
|
|
48
49
|
__doc__ = sklearn_PCA.__doc__
|
|
49
50
|
|
|
@@ -220,7 +221,6 @@ class PCA(sklearn_PCA):
|
|
|
220
221
|
def _onedal_gpu_supported(self, method_name, *data):
|
|
221
222
|
return self._onedal_supported(method_name, *data)
|
|
222
223
|
|
|
223
|
-
@run_with_n_jobs
|
|
224
224
|
def _onedal_fit(self, X, y=None, queue=None):
|
|
225
225
|
if self.n_components == "mle" or self.n_components is None:
|
|
226
226
|
onedal_n_components = min(X.shape)
|
|
@@ -244,11 +244,9 @@ class PCA(sklearn_PCA):
|
|
|
244
244
|
|
|
245
245
|
return U, S, V
|
|
246
246
|
|
|
247
|
-
@run_with_n_jobs
|
|
248
247
|
def _onedal_predict(self, X, queue=None):
|
|
249
248
|
return self._onedal_estimator.predict(X, queue)
|
|
250
249
|
|
|
251
|
-
@run_with_n_jobs
|
|
252
250
|
def _onedal_transform(self, X):
|
|
253
251
|
X = _check_array(X, dtype=[np.float64, np.float32], ensure_2d=True, copy=False)
|
|
254
252
|
|
sklearnex/spmd/__init__.py
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# Copyright 2024 Intel 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 .covariance import EmpiricalCovariance
|
|
18
|
+
|
|
19
|
+
__all__ = ["EmpiricalCovariance"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# Copyright 2024 Intel 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 onedal.spmd.covariance import EmpiricalCovariance
|
|
18
|
+
|
|
19
|
+
# TODO:
|
|
20
|
+
# Currently it uses `onedal` module interface.
|
|
21
|
+
# Add sklearnex dispatching.
|
|
@@ -15,5 +15,6 @@
|
|
|
15
15
|
# ==============================================================================
|
|
16
16
|
|
|
17
17
|
from .linear_model import LinearRegression
|
|
18
|
+
from .logistic_regression import LogisticRegression
|
|
18
19
|
|
|
19
|
-
__all__ = ["LinearRegression"]
|
|
20
|
+
__all__ = ["LinearRegression", "LogisticRegression"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# Copyright 2024 Intel 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 onedal.spmd.linear_model import LogisticRegression
|
|
18
|
+
|
|
19
|
+
# TODO:
|
|
20
|
+
# Currently it uses `onedal` module interface.
|
|
21
|
+
# Add sklearnex dispatching.
|
sklearnex/svm/nusvc.py
CHANGED
|
@@ -18,7 +18,8 @@ from sklearn.exceptions import NotFittedError
|
|
|
18
18
|
from sklearn.svm import NuSVC as sklearn_NuSVC
|
|
19
19
|
from sklearn.utils.validation import _deprecate_positional_args
|
|
20
20
|
|
|
21
|
-
from daal4py.sklearn.
|
|
21
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
22
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
22
23
|
|
|
23
24
|
from .._device_offload import dispatch, wrap_output_data
|
|
24
25
|
from ._common import BaseSVC
|
|
@@ -29,7 +30,9 @@ if sklearn_check_version("1.0"):
|
|
|
29
30
|
from onedal.svm import NuSVC as onedal_NuSVC
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
@control_n_jobs
|
|
33
|
+
@control_n_jobs(
|
|
34
|
+
decorated_methods=["fit", "predict", "_predict_proba", "decision_function"]
|
|
35
|
+
)
|
|
33
36
|
class NuSVC(sklearn_NuSVC, BaseSVC):
|
|
34
37
|
__doc__ = sklearn_NuSVC.__doc__
|
|
35
38
|
|
|
@@ -229,7 +232,6 @@ class NuSVC(sklearn_NuSVC, BaseSVC):
|
|
|
229
232
|
X,
|
|
230
233
|
)
|
|
231
234
|
|
|
232
|
-
@run_with_n_jobs
|
|
233
235
|
def _onedal_fit(self, X, y, sample_weight=None, queue=None):
|
|
234
236
|
onedal_params = {
|
|
235
237
|
"nu": self.nu,
|
|
@@ -253,11 +255,9 @@ class NuSVC(sklearn_NuSVC, BaseSVC):
|
|
|
253
255
|
self._fit_proba(X, y, sample_weight, queue=queue)
|
|
254
256
|
self._save_attributes()
|
|
255
257
|
|
|
256
|
-
@run_with_n_jobs
|
|
257
258
|
def _onedal_predict(self, X, queue=None):
|
|
258
259
|
return self._onedal_estimator.predict(X, queue=queue)
|
|
259
260
|
|
|
260
|
-
@run_with_n_jobs
|
|
261
261
|
def _onedal_predict_proba(self, X, queue=None):
|
|
262
262
|
if getattr(self, "clf_prob", None) is None:
|
|
263
263
|
raise NotFittedError(
|
|
@@ -272,6 +272,5 @@ class NuSVC(sklearn_NuSVC, BaseSVC):
|
|
|
272
272
|
with config_context(**cfg):
|
|
273
273
|
return self.clf_prob.predict_proba(X)
|
|
274
274
|
|
|
275
|
-
@run_with_n_jobs
|
|
276
275
|
def _onedal_decision_function(self, X, queue=None):
|
|
277
276
|
return self._onedal_estimator.decision_function(X, queue=queue)
|
sklearnex/svm/nusvr.py
CHANGED
|
@@ -17,14 +17,15 @@
|
|
|
17
17
|
from sklearn.svm import NuSVR as sklearn_NuSVR
|
|
18
18
|
from sklearn.utils.validation import _deprecate_positional_args
|
|
19
19
|
|
|
20
|
-
from daal4py.sklearn.
|
|
20
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
21
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
21
22
|
from onedal.svm import NuSVR as onedal_NuSVR
|
|
22
23
|
|
|
23
24
|
from .._device_offload import dispatch, wrap_output_data
|
|
24
25
|
from ._common import BaseSVR
|
|
25
26
|
|
|
26
27
|
|
|
27
|
-
@control_n_jobs
|
|
28
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
28
29
|
class NuSVR(sklearn_NuSVR, BaseSVR):
|
|
29
30
|
__doc__ = sklearn_NuSVR.__doc__
|
|
30
31
|
|
|
@@ -142,7 +143,6 @@ class NuSVR(sklearn_NuSVR, BaseSVR):
|
|
|
142
143
|
X,
|
|
143
144
|
)
|
|
144
145
|
|
|
145
|
-
@run_with_n_jobs
|
|
146
146
|
def _onedal_fit(self, X, y, sample_weight=None, queue=None):
|
|
147
147
|
onedal_params = {
|
|
148
148
|
"C": self.C,
|
|
@@ -161,6 +161,5 @@ class NuSVR(sklearn_NuSVR, BaseSVR):
|
|
|
161
161
|
self._onedal_estimator.fit(X, y, sample_weight, queue=queue)
|
|
162
162
|
self._save_attributes()
|
|
163
163
|
|
|
164
|
-
@run_with_n_jobs
|
|
165
164
|
def _onedal_predict(self, X, queue=None):
|
|
166
165
|
return self._onedal_estimator.predict(X, queue=queue)
|
sklearnex/svm/svc.py
CHANGED
|
@@ -20,7 +20,8 @@ from sklearn.exceptions import NotFittedError
|
|
|
20
20
|
from sklearn.svm import SVC as sklearn_SVC
|
|
21
21
|
from sklearn.utils.validation import _deprecate_positional_args
|
|
22
22
|
|
|
23
|
-
from daal4py.sklearn.
|
|
23
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
24
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
24
25
|
|
|
25
26
|
from .._device_offload import dispatch, wrap_output_data
|
|
26
27
|
from .._utils import PatchingConditionsChain
|
|
@@ -32,7 +33,9 @@ if sklearn_check_version("1.0"):
|
|
|
32
33
|
from onedal.svm import SVC as onedal_SVC
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
@control_n_jobs
|
|
36
|
+
@control_n_jobs(
|
|
37
|
+
decorated_methods=["fit", "predict", "_predict_proba", "decision_function"]
|
|
38
|
+
)
|
|
36
39
|
class SVC(sklearn_SVC, BaseSVC):
|
|
37
40
|
__doc__ = sklearn_SVC.__doc__
|
|
38
41
|
|
|
@@ -258,7 +261,6 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
258
261
|
return patching_status
|
|
259
262
|
raise RuntimeError(f"Unknown method {method_name} in {class_name}")
|
|
260
263
|
|
|
261
|
-
@run_with_n_jobs
|
|
262
264
|
def _onedal_fit(self, X, y, sample_weight=None, queue=None):
|
|
263
265
|
onedal_params = {
|
|
264
266
|
"C": self.C,
|
|
@@ -282,11 +284,9 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
282
284
|
self._fit_proba(X, y, sample_weight, queue=queue)
|
|
283
285
|
self._save_attributes()
|
|
284
286
|
|
|
285
|
-
@run_with_n_jobs
|
|
286
287
|
def _onedal_predict(self, X, queue=None):
|
|
287
288
|
return self._onedal_estimator.predict(X, queue=queue)
|
|
288
289
|
|
|
289
|
-
@run_with_n_jobs
|
|
290
290
|
def _onedal_predict_proba(self, X, queue=None):
|
|
291
291
|
if getattr(self, "clf_prob", None) is None:
|
|
292
292
|
raise NotFittedError(
|
|
@@ -301,6 +301,5 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
301
301
|
with config_context(**cfg):
|
|
302
302
|
return self.clf_prob.predict_proba(X)
|
|
303
303
|
|
|
304
|
-
@run_with_n_jobs
|
|
305
304
|
def _onedal_decision_function(self, X, queue=None):
|
|
306
305
|
return self._onedal_estimator.decision_function(X, queue=queue)
|
sklearnex/svm/svr.py
CHANGED
|
@@ -17,14 +17,15 @@
|
|
|
17
17
|
from sklearn.svm import SVR as sklearn_SVR
|
|
18
18
|
from sklearn.utils.validation import _deprecate_positional_args
|
|
19
19
|
|
|
20
|
-
from daal4py.sklearn.
|
|
20
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
21
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
21
22
|
from onedal.svm import SVR as onedal_SVR
|
|
22
23
|
|
|
23
24
|
from .._device_offload import dispatch, wrap_output_data
|
|
24
25
|
from ._common import BaseSVR
|
|
25
26
|
|
|
26
27
|
|
|
27
|
-
@control_n_jobs
|
|
28
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
28
29
|
class SVR(sklearn_SVR, BaseSVR):
|
|
29
30
|
__doc__ = sklearn_SVR.__doc__
|
|
30
31
|
|
|
@@ -143,7 +144,6 @@ class SVR(sklearn_SVR, BaseSVR):
|
|
|
143
144
|
X,
|
|
144
145
|
)
|
|
145
146
|
|
|
146
|
-
@run_with_n_jobs
|
|
147
147
|
def _onedal_fit(self, X, y, sample_weight=None, queue=None):
|
|
148
148
|
onedal_params = {
|
|
149
149
|
"C": self.C,
|
|
@@ -162,6 +162,5 @@ class SVR(sklearn_SVR, BaseSVR):
|
|
|
162
162
|
self._onedal_estimator.fit(X, y, sample_weight, queue=queue)
|
|
163
163
|
self._save_attributes()
|
|
164
164
|
|
|
165
|
-
@run_with_n_jobs
|
|
166
165
|
def _onedal_predict(self, X, queue=None):
|
|
167
166
|
return self._onedal_estimator.predict(X, queue=queue)
|
|
@@ -94,10 +94,7 @@ def remove_duplicated_estimators(estimators_list):
|
|
|
94
94
|
return estimators_map.values()
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
BANNED_ESTIMATORS = (
|
|
98
|
-
"LocalOutlierFactor", # fails on ndarray_c for sklearn > 1.0
|
|
99
|
-
"TSNE", # too slow for using in testing on common data size
|
|
100
|
-
)
|
|
97
|
+
BANNED_ESTIMATORS = ("TSNE",) # too slow for using in testing on common data size
|
|
101
98
|
estimators = [
|
|
102
99
|
PreviewPCA,
|
|
103
100
|
TrainTestSplitEstimator,
|
|
@@ -45,8 +45,12 @@ def test_monkey_patching():
|
|
|
45
45
|
n = _classes[i][1]
|
|
46
46
|
|
|
47
47
|
sklearnex.unpatch_sklearn(t)
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
sklearn_class = getattr(p, n, None)
|
|
49
|
+
if sklearn_class is not None:
|
|
50
|
+
sklearn_class = sklearn_class.__module__
|
|
51
|
+
assert sklearn_class is None or sklearn_class.startswith(
|
|
52
|
+
"sklearn"
|
|
53
|
+
), "Unpatching has completed with error."
|
|
50
54
|
|
|
51
55
|
sklearnex.unpatch_sklearn()
|
|
52
56
|
|
|
@@ -55,8 +59,12 @@ def test_monkey_patching():
|
|
|
55
59
|
p = _classes[i][0]
|
|
56
60
|
n = _classes[i][1]
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
sklearn_class = getattr(p, n, None)
|
|
63
|
+
if sklearn_class is not None:
|
|
64
|
+
sklearn_class = sklearn_class.__module__
|
|
65
|
+
assert sklearn_class is None or sklearn_class.startswith(
|
|
66
|
+
"sklearn"
|
|
67
|
+
), "Unpatching has completed with error."
|
|
60
68
|
|
|
61
69
|
sklearnex.unpatch_sklearn()
|
|
62
70
|
|
|
@@ -85,7 +93,10 @@ def test_patch_by_list_simple():
|
|
|
85
93
|
|
|
86
94
|
assert RandomForestRegressor.__module__.startswith("sklearn")
|
|
87
95
|
assert KNeighborsRegressor.__module__.startswith("sklearn")
|
|
88
|
-
|
|
96
|
+
if daal_check_version((2024, "P", 1)):
|
|
97
|
+
assert LogisticRegression.__module__.startswith("sklearnex")
|
|
98
|
+
else:
|
|
99
|
+
assert LogisticRegression.__module__.startswith("daal4py")
|
|
89
100
|
assert SVC.__module__.startswith("sklearn")
|
|
90
101
|
|
|
91
102
|
sklearnex.unpatch_sklearn()
|
|
@@ -101,7 +112,10 @@ def test_patch_by_list_many_estimators():
|
|
|
101
112
|
|
|
102
113
|
assert RandomForestRegressor.__module__.startswith("sklearn")
|
|
103
114
|
assert KNeighborsRegressor.__module__.startswith("sklearn")
|
|
104
|
-
|
|
115
|
+
if daal_check_version((2024, "P", 1)):
|
|
116
|
+
assert LogisticRegression.__module__.startswith("sklearnex")
|
|
117
|
+
else:
|
|
118
|
+
assert LogisticRegression.__module__.startswith("daal4py")
|
|
105
119
|
assert SVC.__module__.startswith("daal4py") or SVC.__module__.startswith("sklearnex")
|
|
106
120
|
|
|
107
121
|
sklearnex.unpatch_sklearn()
|
|
@@ -119,7 +133,10 @@ def test_unpatch_by_list_many_estimators():
|
|
|
119
133
|
assert KNeighborsRegressor.__module__.startswith(
|
|
120
134
|
"daal4py"
|
|
121
135
|
) or KNeighborsRegressor.__module__.startswith("sklearnex")
|
|
122
|
-
|
|
136
|
+
if daal_check_version((2024, "P", 1)):
|
|
137
|
+
assert LogisticRegression.__module__.startswith("sklearnex")
|
|
138
|
+
else:
|
|
139
|
+
assert LogisticRegression.__module__.startswith("daal4py")
|
|
123
140
|
assert SVC.__module__.startswith("daal4py") or SVC.__module__.startswith("sklearnex")
|
|
124
141
|
|
|
125
142
|
sklearnex.unpatch_sklearn(["KNeighborsRegressor", "RandomForestRegressor"])
|
|
@@ -131,7 +148,11 @@ def test_unpatch_by_list_many_estimators():
|
|
|
131
148
|
|
|
132
149
|
assert RandomForestRegressor.__module__.startswith("sklearn")
|
|
133
150
|
assert KNeighborsRegressor.__module__.startswith("sklearn")
|
|
134
|
-
|
|
151
|
+
if daal_check_version((2024, "P", 1)):
|
|
152
|
+
assert LogisticRegression.__module__.startswith("sklearnex")
|
|
153
|
+
else:
|
|
154
|
+
assert LogisticRegression.__module__.startswith("daal4py")
|
|
155
|
+
|
|
135
156
|
assert SVC.__module__.startswith("daal4py") or SVC.__module__.startswith("sklearnex")
|
|
136
157
|
|
|
137
158
|
|
|
@@ -161,12 +182,11 @@ def test_preview_namespace():
|
|
|
161
182
|
from sklearn.cluster import DBSCAN
|
|
162
183
|
from sklearn.decomposition import PCA
|
|
163
184
|
from sklearn.ensemble import RandomForestClassifier
|
|
164
|
-
from sklearn.linear_model import LinearRegression
|
|
185
|
+
from sklearn.linear_model import LinearRegression
|
|
165
186
|
from sklearn.svm import SVC
|
|
166
187
|
|
|
167
188
|
return (
|
|
168
189
|
LinearRegression(),
|
|
169
|
-
LogisticRegression(),
|
|
170
190
|
PCA(),
|
|
171
191
|
DBSCAN(),
|
|
172
192
|
SVC(),
|
|
@@ -182,7 +202,7 @@ def test_preview_namespace():
|
|
|
182
202
|
|
|
183
203
|
assert _is_preview_enabled()
|
|
184
204
|
|
|
185
|
-
lr,
|
|
205
|
+
lr, pca, dbscan, svc, rfc = get_estimators()
|
|
186
206
|
assert "sklearnex" in rfc.__module__
|
|
187
207
|
|
|
188
208
|
if daal_check_version((2023, "P", 100)):
|
|
@@ -190,20 +210,14 @@ def test_preview_namespace():
|
|
|
190
210
|
else:
|
|
191
211
|
assert "daal4py" in lr.__module__
|
|
192
212
|
|
|
193
|
-
if daal_check_version((2024, "P", 1)):
|
|
194
|
-
assert "sklearnex" in log_reg.__module__
|
|
195
|
-
else:
|
|
196
|
-
assert "daal4py" in log_reg.__module__
|
|
197
|
-
|
|
198
213
|
assert "sklearnex.preview" in pca.__module__
|
|
199
214
|
assert "sklearnex" in dbscan.__module__
|
|
200
215
|
assert "sklearnex" in svc.__module__
|
|
201
216
|
sklearnex.unpatch_sklearn()
|
|
202
217
|
|
|
203
218
|
# no patching behavior
|
|
204
|
-
lr,
|
|
219
|
+
lr, pca, dbscan, svc, rfc = get_estimators()
|
|
205
220
|
assert "sklearn." in lr.__module__ and "daal4py" not in lr.__module__
|
|
206
|
-
assert "sklearn." in log_reg.__module__ and "daal4py" not in log_reg.__module__
|
|
207
221
|
assert "sklearn." in pca.__module__ and "daal4py" not in pca.__module__
|
|
208
222
|
assert "sklearn." in dbscan.__module__ and "daal4py" not in dbscan.__module__
|
|
209
223
|
assert "sklearn." in svc.__module__ and "daal4py" not in svc.__module__
|
|
@@ -213,13 +227,12 @@ def test_preview_namespace():
|
|
|
213
227
|
sklearnex.patch_sklearn()
|
|
214
228
|
assert not _is_preview_enabled()
|
|
215
229
|
|
|
216
|
-
lr,
|
|
230
|
+
lr, pca, dbscan, svc, rfc = get_estimators()
|
|
217
231
|
if daal_check_version((2023, "P", 100)):
|
|
218
232
|
assert "sklearnex" in lr.__module__
|
|
219
233
|
else:
|
|
220
234
|
assert "daal4py" in lr.__module__
|
|
221
235
|
|
|
222
|
-
assert "daal4py" in log_reg.__module__
|
|
223
236
|
assert "daal4py" in pca.__module__
|
|
224
237
|
assert "sklearnex" in rfc.__module__
|
|
225
238
|
assert "sklearnex" in dbscan.__module__
|
|
@@ -14,18 +14,80 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
# ==============================================================================
|
|
16
16
|
|
|
17
|
+
import inspect
|
|
18
|
+
import logging
|
|
19
|
+
from multiprocessing import cpu_count
|
|
20
|
+
|
|
17
21
|
import pytest
|
|
22
|
+
from sklearn.base import BaseEstimator
|
|
23
|
+
from sklearn.datasets import make_classification
|
|
24
|
+
|
|
25
|
+
from sklearnex.dispatcher import get_patch_map
|
|
26
|
+
from sklearnex.svm import SVC, NuSVC
|
|
27
|
+
|
|
28
|
+
ESTIMATORS = set(
|
|
29
|
+
filter(
|
|
30
|
+
lambda x: inspect.isclass(x) and issubclass(x, BaseEstimator),
|
|
31
|
+
[value[0][0][2] for value in get_patch_map().values()],
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
X, Y = make_classification(n_samples=40, n_features=4, random_state=42)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize("estimator_class", ESTIMATORS)
|
|
39
|
+
@pytest.mark.parametrize("n_jobs", [None, -1, 1, 2])
|
|
40
|
+
def test_n_jobs_support(caplog, estimator_class, n_jobs):
|
|
41
|
+
def check_estimator_doc(estimator):
|
|
42
|
+
if estimator.__doc__ is not None:
|
|
43
|
+
assert "n_jobs" in estimator.__doc__
|
|
44
|
+
|
|
45
|
+
def check_n_jobs_entry_in_logs(caplog, function_name, n_jobs):
|
|
46
|
+
for rec in caplog.records:
|
|
47
|
+
if function_name in rec.message and "threads" in rec.message:
|
|
48
|
+
expected_n_jobs = n_jobs if n_jobs > 0 else cpu_count() + 1 + n_jobs
|
|
49
|
+
logging.info(f"{function_name}: setting {expected_n_jobs} threads")
|
|
50
|
+
if f"{function_name}: setting {expected_n_jobs} threads" in rec.message:
|
|
51
|
+
return True
|
|
52
|
+
# False if n_jobs is set and not found in logs
|
|
53
|
+
return n_jobs is None
|
|
18
54
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
55
|
+
def check_method(*args, method, caplog):
|
|
56
|
+
method(*args)
|
|
57
|
+
assert check_n_jobs_entry_in_logs(caplog, method.__name__, n_jobs)
|
|
22
58
|
|
|
23
|
-
|
|
59
|
+
def check_methods_decoration(estimator):
|
|
60
|
+
funcs = {
|
|
61
|
+
i: getattr(estimator, i)
|
|
62
|
+
for i in dir(estimator)
|
|
63
|
+
if hasattr(estimator, i) and callable(getattr(estimator, i))
|
|
64
|
+
}
|
|
24
65
|
|
|
66
|
+
for func_name, func in funcs.items():
|
|
67
|
+
assert hasattr(func, "__onedal_n_jobs_decorated__") == (
|
|
68
|
+
func_name in estimator._n_jobs_supported_onedal_methods
|
|
69
|
+
), f"{estimator}.{func_name} n_jobs decoration does not match {estimator} n_jobs supported methods"
|
|
25
70
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
|
|
71
|
+
caplog.set_level(logging.DEBUG, logger="sklearnex")
|
|
72
|
+
estimator_kwargs = {"n_jobs": n_jobs}
|
|
73
|
+
# by default, [Nu]SVC.predict_proba is restricted by @available_if decorator
|
|
74
|
+
if estimator_class in [SVC, NuSVC]:
|
|
75
|
+
estimator_kwargs["probability"] = True
|
|
76
|
+
estimator_instance = estimator_class(**estimator_kwargs)
|
|
30
77
|
# check `n_jobs` parameter doc entry
|
|
31
|
-
|
|
78
|
+
check_estimator_doc(estimator_class)
|
|
79
|
+
check_estimator_doc(estimator_instance)
|
|
80
|
+
# check `n_jobs` log entry for supported methods
|
|
81
|
+
# `fit` call is required before other methods
|
|
82
|
+
check_method(X, Y, method=estimator_instance.fit, caplog=caplog)
|
|
83
|
+
for method_name in estimator_instance._n_jobs_supported_onedal_methods:
|
|
84
|
+
if method_name == "fit":
|
|
85
|
+
continue
|
|
86
|
+
method = getattr(estimator_instance, method_name)
|
|
87
|
+
if len(inspect.signature(method).parameters) == 0:
|
|
88
|
+
check_method(method=method, caplog=caplog)
|
|
89
|
+
else:
|
|
90
|
+
check_method(X, method=method, caplog=caplog)
|
|
91
|
+
# check if correct methods were decorated
|
|
92
|
+
check_methods_decoration(estimator_class)
|
|
93
|
+
check_methods_decoration(estimator_instance)
|