scikit-learn-intelex 2024.3.0__py38-none-manylinux1_x86_64.whl → 2024.4.0__py38-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.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/METADATA +2 -2
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/RECORD +33 -30
- sklearnex/_device_offload.py +31 -4
- sklearnex/basic_statistics/__init__.py +2 -1
- sklearnex/basic_statistics/incremental_basic_statistics.py +288 -0
- sklearnex/basic_statistics/tests/test_incremental_basic_statistics.py +386 -0
- sklearnex/decomposition/pca.py +3 -6
- sklearnex/dispatcher.py +2 -2
- sklearnex/ensemble/_forest.py +68 -75
- sklearnex/linear_model/linear.py +275 -340
- sklearnex/linear_model/logistic_regression.py +50 -9
- sklearnex/linear_model/tests/test_linear.py +40 -5
- sklearnex/neighbors/_lof.py +53 -36
- sklearnex/neighbors/common.py +4 -1
- sklearnex/neighbors/knn_classification.py +37 -122
- sklearnex/neighbors/knn_regression.py +10 -117
- sklearnex/neighbors/knn_unsupervised.py +6 -78
- sklearnex/preview/cluster/k_means.py +5 -73
- sklearnex/preview/covariance/covariance.py +6 -5
- sklearnex/preview/covariance/tests/test_covariance.py +18 -5
- sklearnex/svm/_common.py +4 -7
- sklearnex/svm/nusvc.py +66 -50
- sklearnex/svm/nusvr.py +3 -49
- sklearnex/svm/svc.py +66 -51
- sklearnex/svm/svr.py +3 -49
- sklearnex/tests/_utils.py +14 -5
- sklearnex/tests/test_n_jobs_support.py +8 -2
- sklearnex/tests/test_patching.py +64 -54
- sklearnex/utils/__init__.py +2 -1
- sklearnex/utils/_namespace.py +97 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/LICENSE.txt +0 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/WHEEL +0 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/top_level.txt +0 -0
sklearnex/svm/nusvr.py
CHANGED
|
@@ -63,39 +63,6 @@ class NuSVR(sklearn_NuSVR, BaseSVR):
|
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
def fit(self, X, y, sample_weight=None):
|
|
66
|
-
"""
|
|
67
|
-
Fit the SVM model according to the given training data.
|
|
68
|
-
|
|
69
|
-
Parameters
|
|
70
|
-
----------
|
|
71
|
-
X : {array-like, sparse matrix} of shape (n_samples, n_features) \
|
|
72
|
-
or (n_samples, n_samples)
|
|
73
|
-
Training vectors, where `n_samples` is the number of samples
|
|
74
|
-
and `n_features` is the number of features.
|
|
75
|
-
For kernel="precomputed", the expected shape of X is
|
|
76
|
-
(n_samples, n_samples).
|
|
77
|
-
|
|
78
|
-
y : array-like of shape (n_samples,)
|
|
79
|
-
Target values (class labels in classification, real numbers in
|
|
80
|
-
regression).
|
|
81
|
-
|
|
82
|
-
sample_weight : array-like of shape (n_samples,), default=None
|
|
83
|
-
Per-sample weights. Rescale C per sample. Higher weights
|
|
84
|
-
force the classifier to put more emphasis on these points.
|
|
85
|
-
|
|
86
|
-
Returns
|
|
87
|
-
-------
|
|
88
|
-
self : object
|
|
89
|
-
Fitted estimator.
|
|
90
|
-
|
|
91
|
-
Notes
|
|
92
|
-
-----
|
|
93
|
-
If X and y are not C-ordered and contiguous arrays of np.float64 and
|
|
94
|
-
X is not a scipy.sparse.csr_matrix, X and/or y may be copied.
|
|
95
|
-
|
|
96
|
-
If X is a dense array, then the other methods will not support sparse
|
|
97
|
-
matrices as input.
|
|
98
|
-
"""
|
|
99
66
|
if sklearn_check_version("1.2"):
|
|
100
67
|
self._validate_params()
|
|
101
68
|
if sklearn_check_version("1.0"):
|
|
@@ -115,22 +82,6 @@ class NuSVR(sklearn_NuSVR, BaseSVR):
|
|
|
115
82
|
|
|
116
83
|
@wrap_output_data
|
|
117
84
|
def predict(self, X):
|
|
118
|
-
"""
|
|
119
|
-
Perform regression on samples in X.
|
|
120
|
-
|
|
121
|
-
For an one-class model, +1 (inlier) or -1 (outlier) is returned.
|
|
122
|
-
|
|
123
|
-
Parameters
|
|
124
|
-
----------
|
|
125
|
-
X : {array-like, sparse matrix} of shape (n_samples, n_features)
|
|
126
|
-
For kernel="precomputed", the expected shape of X is
|
|
127
|
-
(n_samples_test, n_samples_train).
|
|
128
|
-
|
|
129
|
-
Returns
|
|
130
|
-
-------
|
|
131
|
-
y_pred : ndarray of shape (n_samples,)
|
|
132
|
-
The predicted values.
|
|
133
|
-
"""
|
|
134
85
|
if sklearn_check_version("1.0"):
|
|
135
86
|
self._check_feature_names(X, reset=False)
|
|
136
87
|
return dispatch(
|
|
@@ -163,3 +114,6 @@ class NuSVR(sklearn_NuSVR, BaseSVR):
|
|
|
163
114
|
|
|
164
115
|
def _onedal_predict(self, X, queue=None):
|
|
165
116
|
return self._onedal_estimator.predict(X, queue=queue)
|
|
117
|
+
|
|
118
|
+
fit.__doc__ = sklearn_NuSVR.fit.__doc__
|
|
119
|
+
predict.__doc__ = sklearn_NuSVR.predict.__doc__
|
sklearnex/svm/svc.py
CHANGED
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
from scipy import sparse as sp
|
|
19
19
|
from sklearn.exceptions import NotFittedError
|
|
20
|
+
from sklearn.metrics import accuracy_score
|
|
20
21
|
from sklearn.svm import SVC as sklearn_SVC
|
|
21
22
|
from sklearn.utils.validation import _deprecate_positional_args
|
|
22
23
|
|
|
23
24
|
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
24
25
|
from daal4py.sklearn._utils import sklearn_check_version
|
|
26
|
+
from sklearnex.utils import get_namespace
|
|
25
27
|
|
|
26
28
|
from .._device_offload import dispatch, wrap_output_data
|
|
27
29
|
from .._utils import PatchingConditionsChain
|
|
@@ -34,7 +36,7 @@ from onedal.svm import SVC as onedal_SVC
|
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
@control_n_jobs(
|
|
37
|
-
decorated_methods=["fit", "predict", "_predict_proba", "decision_function"]
|
|
39
|
+
decorated_methods=["fit", "predict", "_predict_proba", "decision_function", "score"]
|
|
38
40
|
)
|
|
39
41
|
class SVC(sklearn_SVC, BaseSVC):
|
|
40
42
|
__doc__ = sklearn_SVC.__doc__
|
|
@@ -81,39 +83,6 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
81
83
|
)
|
|
82
84
|
|
|
83
85
|
def fit(self, X, y, sample_weight=None):
|
|
84
|
-
"""
|
|
85
|
-
Fit the SVM model according to the given training data.
|
|
86
|
-
|
|
87
|
-
Parameters
|
|
88
|
-
----------
|
|
89
|
-
X : {array-like, sparse matrix} of shape (n_samples, n_features) \
|
|
90
|
-
or (n_samples, n_samples)
|
|
91
|
-
Training vectors, where `n_samples` is the number of samples
|
|
92
|
-
and `n_features` is the number of features.
|
|
93
|
-
For kernel="precomputed", the expected shape of X is
|
|
94
|
-
(n_samples, n_samples).
|
|
95
|
-
|
|
96
|
-
y : array-like of shape (n_samples,)
|
|
97
|
-
Target values (class labels in classification, real numbers in
|
|
98
|
-
regression).
|
|
99
|
-
|
|
100
|
-
sample_weight : array-like of shape (n_samples,), default=None
|
|
101
|
-
Per-sample weights. Rescale C per sample. Higher weights
|
|
102
|
-
force the classifier to put more emphasis on these points.
|
|
103
|
-
|
|
104
|
-
Returns
|
|
105
|
-
-------
|
|
106
|
-
self : object
|
|
107
|
-
Fitted estimator.
|
|
108
|
-
|
|
109
|
-
Notes
|
|
110
|
-
-----
|
|
111
|
-
If X and y are not C-ordered and contiguous arrays of np.float64 and
|
|
112
|
-
X is not a scipy.sparse.csr_matrix, X and/or y may be copied.
|
|
113
|
-
|
|
114
|
-
If X is a dense array, then the other methods will not support sparse
|
|
115
|
-
matrices as input.
|
|
116
|
-
"""
|
|
117
86
|
if sklearn_check_version("1.2"):
|
|
118
87
|
self._validate_params()
|
|
119
88
|
if sklearn_check_version("1.0"):
|
|
@@ -133,22 +102,6 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
133
102
|
|
|
134
103
|
@wrap_output_data
|
|
135
104
|
def predict(self, X):
|
|
136
|
-
"""
|
|
137
|
-
Perform regression on samples in X.
|
|
138
|
-
|
|
139
|
-
For an one-class model, +1 (inlier) or -1 (outlier) is returned.
|
|
140
|
-
|
|
141
|
-
Parameters
|
|
142
|
-
----------
|
|
143
|
-
X : {array-like, sparse matrix} of shape (n_samples, n_features)
|
|
144
|
-
For kernel="precomputed", the expected shape of X is
|
|
145
|
-
(n_samples_test, n_samples_train).
|
|
146
|
-
|
|
147
|
-
Returns
|
|
148
|
-
-------
|
|
149
|
-
y_pred : ndarray of shape (n_samples,)
|
|
150
|
-
The predicted values.
|
|
151
|
-
"""
|
|
152
105
|
if sklearn_check_version("1.0"):
|
|
153
106
|
self._check_feature_names(X, reset=False)
|
|
154
107
|
return dispatch(
|
|
@@ -161,6 +114,22 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
161
114
|
X,
|
|
162
115
|
)
|
|
163
116
|
|
|
117
|
+
@wrap_output_data
|
|
118
|
+
def score(self, X, y, sample_weight=None):
|
|
119
|
+
if sklearn_check_version("1.0"):
|
|
120
|
+
self._check_feature_names(X, reset=False)
|
|
121
|
+
return dispatch(
|
|
122
|
+
self,
|
|
123
|
+
"score",
|
|
124
|
+
{
|
|
125
|
+
"onedal": self.__class__._onedal_score,
|
|
126
|
+
"sklearn": sklearn_SVC.score,
|
|
127
|
+
},
|
|
128
|
+
X,
|
|
129
|
+
y,
|
|
130
|
+
sample_weight=sample_weight,
|
|
131
|
+
)
|
|
132
|
+
|
|
164
133
|
if sklearn_check_version("1.0"):
|
|
165
134
|
|
|
166
135
|
@available_if(sklearn_SVC._check_proba)
|
|
@@ -193,6 +162,38 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
193
162
|
"""
|
|
194
163
|
return self._predict_proba(X)
|
|
195
164
|
|
|
165
|
+
@available_if(sklearn_SVC._check_proba)
|
|
166
|
+
def predict_log_proba(self, X):
|
|
167
|
+
"""Compute log probabilities of possible outcomes for samples in X.
|
|
168
|
+
|
|
169
|
+
The model need to have probability information computed at training
|
|
170
|
+
time: fit with attribute `probability` set to True.
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
X : array-like of shape (n_samples, n_features) or \
|
|
175
|
+
(n_samples_test, n_samples_train)
|
|
176
|
+
For kernel="precomputed", the expected shape of X is
|
|
177
|
+
(n_samples_test, n_samples_train).
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
T : ndarray of shape (n_samples, n_classes)
|
|
182
|
+
Returns the log-probabilities of the sample for each class in
|
|
183
|
+
the model. The columns correspond to the classes in sorted
|
|
184
|
+
order, as they appear in the attribute :term:`classes_`.
|
|
185
|
+
|
|
186
|
+
Notes
|
|
187
|
+
-----
|
|
188
|
+
The probability model is created using cross validation, so
|
|
189
|
+
the results can be slightly different than those obtained by
|
|
190
|
+
predict. Also, it will produce meaningless results on very small
|
|
191
|
+
datasets.
|
|
192
|
+
"""
|
|
193
|
+
xp, _ = get_namespace(X)
|
|
194
|
+
|
|
195
|
+
return xp.log(self.predict_proba(X))
|
|
196
|
+
|
|
196
197
|
else:
|
|
197
198
|
|
|
198
199
|
@property
|
|
@@ -200,6 +201,10 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
200
201
|
self._check_proba()
|
|
201
202
|
return self._predict_proba
|
|
202
203
|
|
|
204
|
+
def _predict_log_proba(self, X):
|
|
205
|
+
xp, _ = get_namespace(X)
|
|
206
|
+
return xp.log(self.predict_proba(X))
|
|
207
|
+
|
|
203
208
|
predict_proba.__doc__ = sklearn_SVC.predict_proba.__doc__
|
|
204
209
|
|
|
205
210
|
@wrap_output_data
|
|
@@ -257,7 +262,7 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
257
262
|
if method_name == "fit":
|
|
258
263
|
patching_status.and_conditions(conditions)
|
|
259
264
|
return patching_status
|
|
260
|
-
if method_name in ["predict", "predict_proba", "decision_function"]:
|
|
265
|
+
if method_name in ["predict", "predict_proba", "decision_function", "score"]:
|
|
261
266
|
conditions.append(
|
|
262
267
|
(hasattr(self, "_onedal_estimator"), "oneDAL model was not trained")
|
|
263
268
|
)
|
|
@@ -307,3 +312,13 @@ class SVC(sklearn_SVC, BaseSVC):
|
|
|
307
312
|
|
|
308
313
|
def _onedal_decision_function(self, X, queue=None):
|
|
309
314
|
return self._onedal_estimator.decision_function(X, queue=queue)
|
|
315
|
+
|
|
316
|
+
def _onedal_score(self, X, y, sample_weight=None, queue=None):
|
|
317
|
+
return accuracy_score(
|
|
318
|
+
y, self._onedal_predict(X, queue=queue), sample_weight=sample_weight
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
fit.__doc__ = sklearn_SVC.fit.__doc__
|
|
322
|
+
predict.__doc__ = sklearn_SVC.predict.__doc__
|
|
323
|
+
decision_function.__doc__ = sklearn_SVC.decision_function.__doc__
|
|
324
|
+
score.__doc__ = sklearn_SVC.score.__doc__
|
sklearnex/svm/svr.py
CHANGED
|
@@ -63,39 +63,6 @@ class SVR(sklearn_SVR, BaseSVR):
|
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
def fit(self, X, y, sample_weight=None):
|
|
66
|
-
"""
|
|
67
|
-
Fit the SVM model according to the given training data.
|
|
68
|
-
|
|
69
|
-
Parameters
|
|
70
|
-
----------
|
|
71
|
-
X : {array-like, sparse matrix} of shape (n_samples, n_features) \
|
|
72
|
-
or (n_samples, n_samples)
|
|
73
|
-
Training vectors, where `n_samples` is the number of samples
|
|
74
|
-
and `n_features` is the number of features.
|
|
75
|
-
For kernel="precomputed", the expected shape of X is
|
|
76
|
-
(n_samples, n_samples).
|
|
77
|
-
|
|
78
|
-
y : array-like of shape (n_samples,)
|
|
79
|
-
Target values (class labels in classification, real numbers in
|
|
80
|
-
regression).
|
|
81
|
-
|
|
82
|
-
sample_weight : array-like of shape (n_samples,), default=None
|
|
83
|
-
Per-sample weights. Rescale C per sample. Higher weights
|
|
84
|
-
force the classifier to put more emphasis on these points.
|
|
85
|
-
|
|
86
|
-
Returns
|
|
87
|
-
-------
|
|
88
|
-
self : object
|
|
89
|
-
Fitted estimator.
|
|
90
|
-
|
|
91
|
-
Notes
|
|
92
|
-
-----
|
|
93
|
-
If X and y are not C-ordered and contiguous arrays of np.float64 and
|
|
94
|
-
X is not a scipy.sparse.csr_matrix, X and/or y may be copied.
|
|
95
|
-
|
|
96
|
-
If X is a dense array, then the other methods will not support sparse
|
|
97
|
-
matrices as input.
|
|
98
|
-
"""
|
|
99
66
|
if sklearn_check_version("1.2"):
|
|
100
67
|
self._validate_params()
|
|
101
68
|
if sklearn_check_version("1.0"):
|
|
@@ -116,22 +83,6 @@ class SVR(sklearn_SVR, BaseSVR):
|
|
|
116
83
|
|
|
117
84
|
@wrap_output_data
|
|
118
85
|
def predict(self, X):
|
|
119
|
-
"""
|
|
120
|
-
Perform regression on samples in X.
|
|
121
|
-
|
|
122
|
-
For an one-class model, +1 (inlier) or -1 (outlier) is returned.
|
|
123
|
-
|
|
124
|
-
Parameters
|
|
125
|
-
----------
|
|
126
|
-
X : {array-like, sparse matrix} of shape (n_samples, n_features)
|
|
127
|
-
For kernel="precomputed", the expected shape of X is
|
|
128
|
-
(n_samples_test, n_samples_train).
|
|
129
|
-
|
|
130
|
-
Returns
|
|
131
|
-
-------
|
|
132
|
-
y_pred : ndarray of shape (n_samples,)
|
|
133
|
-
The predicted values.
|
|
134
|
-
"""
|
|
135
86
|
if sklearn_check_version("1.0"):
|
|
136
87
|
self._check_feature_names(X, reset=False)
|
|
137
88
|
return dispatch(
|
|
@@ -164,3 +115,6 @@ class SVR(sklearn_SVR, BaseSVR):
|
|
|
164
115
|
|
|
165
116
|
def _onedal_predict(self, X, queue=None):
|
|
166
117
|
return self._onedal_estimator.predict(X, queue=queue)
|
|
118
|
+
|
|
119
|
+
fit.__doc__ = sklearn_SVR.fit.__doc__
|
|
120
|
+
predict.__doc__ = sklearn_SVR.predict.__doc__
|
sklearnex/tests/_utils.py
CHANGED
|
@@ -30,6 +30,7 @@ from sklearn.neighbors._base import KNeighborsMixin
|
|
|
30
30
|
|
|
31
31
|
from onedal.tests.utils._dataframes_support import _convert_to_dataframe
|
|
32
32
|
from sklearnex import get_patch_map, patch_sklearn, sklearn_is_patched, unpatch_sklearn
|
|
33
|
+
from sklearnex.linear_model import LogisticRegression
|
|
33
34
|
from sklearnex.neighbors import (
|
|
34
35
|
KNeighborsClassifier,
|
|
35
36
|
KNeighborsRegressor,
|
|
@@ -95,6 +96,7 @@ SPECIAL_INSTANCES = {
|
|
|
95
96
|
KNeighborsClassifier(algorithm="brute"),
|
|
96
97
|
KNeighborsRegressor(algorithm="brute"),
|
|
97
98
|
NearestNeighbors(algorithm="brute"),
|
|
99
|
+
LogisticRegression(solver="newton-cg"),
|
|
98
100
|
]
|
|
99
101
|
}
|
|
100
102
|
|
|
@@ -102,10 +104,13 @@ SPECIAL_INSTANCES = {
|
|
|
102
104
|
def gen_models_info(algorithms):
|
|
103
105
|
output = []
|
|
104
106
|
for i in algorithms:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
|
|
108
|
+
if i in PATCHED_MODELS:
|
|
109
|
+
est = PATCHED_MODELS[i]
|
|
110
|
+
elif i in SPECIAL_INSTANCES:
|
|
111
|
+
est = SPECIAL_INSTANCES[i].__class__
|
|
112
|
+
else:
|
|
113
|
+
raise KeyError(f"Unrecognized sklearnex estimator: {i}")
|
|
109
114
|
|
|
110
115
|
methods = set()
|
|
111
116
|
candidates = set(
|
|
@@ -116,7 +121,11 @@ def gen_models_info(algorithms):
|
|
|
116
121
|
if issubclass(est, mixin):
|
|
117
122
|
methods |= candidates & set(method)
|
|
118
123
|
|
|
119
|
-
output += [[i, j] for j in methods]
|
|
124
|
+
output += [[i, j] for j in methods] if methods else [[i, None]]
|
|
125
|
+
|
|
126
|
+
# In the case that no methods are available, set method to None.
|
|
127
|
+
# This will allow estimators without mixins to still test the fit
|
|
128
|
+
# method in various tests.
|
|
120
129
|
return output
|
|
121
130
|
|
|
122
131
|
|
|
@@ -84,10 +84,16 @@ def test_n_jobs_support(caplog, estimator_class, n_jobs):
|
|
|
84
84
|
if method_name == "fit":
|
|
85
85
|
continue
|
|
86
86
|
method = getattr(estimator_instance, method_name)
|
|
87
|
-
|
|
87
|
+
argdict = inspect.signature(method).parameters
|
|
88
|
+
argnum = len(
|
|
89
|
+
[i for i in argdict if argdict[i].default == inspect.Parameter.empty]
|
|
90
|
+
)
|
|
91
|
+
if argnum == 0:
|
|
88
92
|
check_method(method=method, caplog=caplog)
|
|
89
|
-
|
|
93
|
+
elif argnum == 1:
|
|
90
94
|
check_method(X, method=method, caplog=caplog)
|
|
95
|
+
else:
|
|
96
|
+
check_method(X, Y, method=method, caplog=caplog)
|
|
91
97
|
# check if correct methods were decorated
|
|
92
98
|
check_methods_decoration(estimator_class)
|
|
93
99
|
check_methods_decoration(estimator_instance)
|
sklearnex/tests/test_patching.py
CHANGED
|
@@ -26,24 +26,7 @@ from inspect import signature
|
|
|
26
26
|
import numpy as np
|
|
27
27
|
import numpy.random as nprnd
|
|
28
28
|
import pytest
|
|
29
|
-
from
|
|
30
|
-
DTYPES,
|
|
31
|
-
PATCHED_FUNCTIONS,
|
|
32
|
-
PATCHED_MODELS,
|
|
33
|
-
SPECIAL_INSTANCES,
|
|
34
|
-
UNPATCHED_FUNCTIONS,
|
|
35
|
-
UNPATCHED_MODELS,
|
|
36
|
-
gen_dataset,
|
|
37
|
-
gen_models_info,
|
|
38
|
-
)
|
|
39
|
-
from sklearn.base import (
|
|
40
|
-
BaseEstimator,
|
|
41
|
-
ClassifierMixin,
|
|
42
|
-
ClusterMixin,
|
|
43
|
-
OutlierMixin,
|
|
44
|
-
RegressorMixin,
|
|
45
|
-
TransformerMixin,
|
|
46
|
-
)
|
|
29
|
+
from sklearn.base import BaseEstimator
|
|
47
30
|
|
|
48
31
|
from daal4py.sklearn._utils import sklearn_check_version
|
|
49
32
|
from onedal.tests.utils._dataframes_support import (
|
|
@@ -53,21 +36,39 @@ from onedal.tests.utils._dataframes_support import (
|
|
|
53
36
|
from sklearnex import is_patched_instance
|
|
54
37
|
from sklearnex.dispatcher import _is_preview_enabled
|
|
55
38
|
from sklearnex.metrics import pairwise_distances, roc_auc_score
|
|
39
|
+
from sklearnex.tests._utils import (
|
|
40
|
+
DTYPES,
|
|
41
|
+
PATCHED_FUNCTIONS,
|
|
42
|
+
PATCHED_MODELS,
|
|
43
|
+
SPECIAL_INSTANCES,
|
|
44
|
+
UNPATCHED_FUNCTIONS,
|
|
45
|
+
UNPATCHED_MODELS,
|
|
46
|
+
gen_dataset,
|
|
47
|
+
gen_models_info,
|
|
48
|
+
)
|
|
56
49
|
|
|
57
50
|
|
|
58
51
|
@pytest.mark.parametrize("dtype", DTYPES)
|
|
59
|
-
@pytest.mark.parametrize(
|
|
60
|
-
"dataframe, queue", get_dataframes_and_queues(dataframe_filter_="numpy")
|
|
61
|
-
)
|
|
52
|
+
@pytest.mark.parametrize("dataframe, queue", get_dataframes_and_queues())
|
|
62
53
|
@pytest.mark.parametrize("metric", ["cosine", "correlation"])
|
|
63
54
|
def test_pairwise_distances_patching(caplog, dataframe, queue, dtype, metric):
|
|
64
55
|
with caplog.at_level(logging.WARNING, logger="sklearnex"):
|
|
56
|
+
if dtype == np.float16 and queue and not queue.sycl_device.has_aspect_fp16:
|
|
57
|
+
pytest.skip("Hardware does not support fp16 SYCL testing")
|
|
58
|
+
elif dtype == np.float64 and queue and not queue.sycl_device.has_aspect_fp64:
|
|
59
|
+
pytest.skip("Hardware does not support fp64 SYCL testing")
|
|
60
|
+
elif queue and queue.sycl_device.is_gpu:
|
|
61
|
+
pytest.skip("pairwise_distances does not support GPU queues")
|
|
62
|
+
|
|
65
63
|
rng = nprnd.default_rng()
|
|
66
64
|
X = _convert_to_dataframe(
|
|
67
|
-
rng.random(size=1000),
|
|
65
|
+
rng.random(size=1000).reshape(1, -1),
|
|
66
|
+
sycl_queue=queue,
|
|
67
|
+
target_df=dataframe,
|
|
68
|
+
dtype=dtype,
|
|
68
69
|
)
|
|
69
70
|
|
|
70
|
-
_ = pairwise_distances(X
|
|
71
|
+
_ = pairwise_distances(X, metric=metric)
|
|
71
72
|
assert all(
|
|
72
73
|
[
|
|
73
74
|
"running accelerated version" in i.message
|
|
@@ -80,12 +81,13 @@ def test_pairwise_distances_patching(caplog, dataframe, queue, dtype, metric):
|
|
|
80
81
|
@pytest.mark.parametrize(
|
|
81
82
|
"dtype", [i for i in DTYPES if "32" in i.__name__ or "64" in i.__name__]
|
|
82
83
|
)
|
|
83
|
-
@pytest.mark.parametrize(
|
|
84
|
-
"dataframe, queue", get_dataframes_and_queues(dataframe_filter_="numpy")
|
|
85
|
-
)
|
|
84
|
+
@pytest.mark.parametrize("dataframe, queue", get_dataframes_and_queues())
|
|
86
85
|
def test_roc_auc_score_patching(caplog, dataframe, queue, dtype):
|
|
87
86
|
if dtype in [np.uint32, np.uint64] and sys.platform == "win32":
|
|
88
87
|
pytest.skip("Windows issue with unsigned ints")
|
|
88
|
+
elif dtype == np.float64 and queue and not queue.sycl_device.has_aspect_fp64:
|
|
89
|
+
pytest.skip("Hardware does not support fp64 SYCL testing")
|
|
90
|
+
|
|
89
91
|
with caplog.at_level(logging.WARNING, logger="sklearnex"):
|
|
90
92
|
rng = nprnd.default_rng()
|
|
91
93
|
X = _convert_to_dataframe(
|
|
@@ -112,14 +114,25 @@ def test_roc_auc_score_patching(caplog, dataframe, queue, dtype):
|
|
|
112
114
|
|
|
113
115
|
|
|
114
116
|
@pytest.mark.parametrize("dtype", DTYPES)
|
|
115
|
-
@pytest.mark.parametrize(
|
|
116
|
-
"dataframe, queue", get_dataframes_and_queues(dataframe_filter_="numpy")
|
|
117
|
-
)
|
|
117
|
+
@pytest.mark.parametrize("dataframe, queue", get_dataframes_and_queues())
|
|
118
118
|
@pytest.mark.parametrize("estimator, method", gen_models_info(PATCHED_MODELS))
|
|
119
119
|
def test_standard_estimator_patching(caplog, dataframe, queue, dtype, estimator, method):
|
|
120
120
|
with caplog.at_level(logging.WARNING, logger="sklearnex"):
|
|
121
121
|
est = PATCHED_MODELS[estimator]()
|
|
122
122
|
|
|
123
|
+
if queue:
|
|
124
|
+
if dtype == np.float16 and not queue.sycl_device.has_aspect_fp16:
|
|
125
|
+
pytest.skip("Hardware does not support fp16 SYCL testing")
|
|
126
|
+
elif dtype == np.float64 and not queue.sycl_device.has_aspect_fp64:
|
|
127
|
+
pytest.skip("Hardware does not support fp64 SYCL testing")
|
|
128
|
+
elif queue.sycl_device.is_gpu and estimator in [
|
|
129
|
+
"KMeans",
|
|
130
|
+
"ElasticNet",
|
|
131
|
+
"Lasso",
|
|
132
|
+
"Ridge",
|
|
133
|
+
]:
|
|
134
|
+
pytest.skip(f"{estimator} does not support GPU queues")
|
|
135
|
+
|
|
123
136
|
if estimator == "TSNE" and method == "fit_transform":
|
|
124
137
|
pytest.skip("TSNE.fit_transform is too slow for common testing")
|
|
125
138
|
elif (
|
|
@@ -129,15 +142,17 @@ def test_standard_estimator_patching(caplog, dataframe, queue, dtype, estimator,
|
|
|
129
142
|
and dtype in [np.uint32, np.uint64]
|
|
130
143
|
):
|
|
131
144
|
pytest.skip("Windows segmentation fault for Ridge.predict for unsigned ints")
|
|
132
|
-
elif not hasattr(est, method):
|
|
145
|
+
elif method and not hasattr(est, method):
|
|
133
146
|
pytest.skip(f"sklearn available_if prevents testing {estimator}.{method}")
|
|
147
|
+
|
|
134
148
|
X, y = gen_dataset(est, queue=queue, target_df=dataframe, dtype=dtype)
|
|
135
149
|
est.fit(X, y)
|
|
136
150
|
|
|
137
|
-
if method
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
151
|
+
if method:
|
|
152
|
+
if method != "score":
|
|
153
|
+
getattr(est, method)(X)
|
|
154
|
+
else:
|
|
155
|
+
est.score(X, y)
|
|
141
156
|
assert all(
|
|
142
157
|
[
|
|
143
158
|
"running accelerated version" in i.message
|
|
@@ -148,9 +163,7 @@ def test_standard_estimator_patching(caplog, dataframe, queue, dtype, estimator,
|
|
|
148
163
|
|
|
149
164
|
|
|
150
165
|
@pytest.mark.parametrize("dtype", DTYPES)
|
|
151
|
-
@pytest.mark.parametrize(
|
|
152
|
-
"dataframe, queue", get_dataframes_and_queues(dataframe_filter_="numpy")
|
|
153
|
-
)
|
|
166
|
+
@pytest.mark.parametrize("dataframe, queue", get_dataframes_and_queues())
|
|
154
167
|
@pytest.mark.parametrize("estimator, method", gen_models_info(SPECIAL_INSTANCES))
|
|
155
168
|
def test_special_estimator_patching(caplog, dataframe, queue, dtype, estimator, method):
|
|
156
169
|
# prepare logging
|
|
@@ -158,15 +171,24 @@ def test_special_estimator_patching(caplog, dataframe, queue, dtype, estimator,
|
|
|
158
171
|
with caplog.at_level(logging.WARNING, logger="sklearnex"):
|
|
159
172
|
est = SPECIAL_INSTANCES[estimator]
|
|
160
173
|
|
|
174
|
+
# Its not possible to get the dpnp/dpctl arrays to be in the proper dtype
|
|
175
|
+
if dtype == np.float16 and queue and not queue.sycl_device.has_aspect_fp16:
|
|
176
|
+
pytest.skip("Hardware does not support fp16 SYCL testing")
|
|
177
|
+
elif dtype == np.float64 and queue and not queue.sycl_device.has_aspect_fp64:
|
|
178
|
+
pytest.skip("Hardware does not support fp64 SYCL testing")
|
|
179
|
+
|
|
161
180
|
X, y = gen_dataset(est, queue=queue, target_df=dataframe, dtype=dtype)
|
|
162
181
|
est.fit(X, y)
|
|
163
182
|
|
|
164
|
-
if not hasattr(est, method):
|
|
183
|
+
if method and not hasattr(est, method):
|
|
165
184
|
pytest.skip(f"sklearn available_if prevents testing {estimator}.{method}")
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
185
|
+
|
|
186
|
+
if method:
|
|
187
|
+
if method != "score":
|
|
188
|
+
getattr(est, method)(X)
|
|
189
|
+
else:
|
|
190
|
+
est.score(X, y)
|
|
191
|
+
|
|
170
192
|
assert all(
|
|
171
193
|
[
|
|
172
194
|
"running accelerated version" in i.message
|
|
@@ -311,18 +333,6 @@ def test_if_estimator_inherits_sklearn(estimator):
|
|
|
311
333
|
), f"{estimator} does not inherit from the patched sklearn estimator"
|
|
312
334
|
else:
|
|
313
335
|
assert issubclass(est, BaseEstimator)
|
|
314
|
-
assert any(
|
|
315
|
-
[
|
|
316
|
-
issubclass(est, i)
|
|
317
|
-
for i in [
|
|
318
|
-
ClassifierMixin,
|
|
319
|
-
ClusterMixin,
|
|
320
|
-
OutlierMixin,
|
|
321
|
-
RegressorMixin,
|
|
322
|
-
TransformerMixin,
|
|
323
|
-
]
|
|
324
|
-
]
|
|
325
|
-
), f"{estimator} does not inherit a sklearn Mixin"
|
|
326
336
|
|
|
327
337
|
|
|
328
338
|
@pytest.mark.parametrize("estimator", UNPATCHED_MODELS.keys())
|
sklearnex/utils/__init__.py
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
# ===============================================================================
|
|
16
16
|
|
|
17
|
+
from ._namespace import get_namespace
|
|
17
18
|
from .validation import _assert_all_finite
|
|
18
19
|
|
|
19
|
-
__all__ = ["_assert_all_finite"]
|
|
20
|
+
__all__ = ["get_namespace", "_assert_all_finite"]
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
import numpy as np
|
|
18
|
+
|
|
19
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
20
|
+
|
|
21
|
+
from .._device_offload import dpnp_available
|
|
22
|
+
|
|
23
|
+
if sklearn_check_version("1.2"):
|
|
24
|
+
from sklearn.utils._array_api import get_namespace as sklearn_get_namespace
|
|
25
|
+
|
|
26
|
+
if dpnp_available:
|
|
27
|
+
import dpnp
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_namespace(*arrays):
|
|
31
|
+
"""Get namespace of arrays.
|
|
32
|
+
|
|
33
|
+
Introspect `arrays` arguments and return their common Array API
|
|
34
|
+
compatible namespace object, if any. NumPy 1.22 and later can
|
|
35
|
+
construct such containers using the `numpy.array_api` namespace
|
|
36
|
+
for instance.
|
|
37
|
+
|
|
38
|
+
This function will return the namespace of SYCL-related arrays
|
|
39
|
+
which define the __sycl_usm_array_interface__ attribute
|
|
40
|
+
regardless of array_api support, the configuration of
|
|
41
|
+
array_api_dispatch, or scikit-learn version.
|
|
42
|
+
|
|
43
|
+
See: https://numpy.org/neps/nep-0047-array-api-standard.html
|
|
44
|
+
|
|
45
|
+
If `arrays` are regular numpy arrays, an instance of the
|
|
46
|
+
`_NumPyApiWrapper` compatibility wrapper is returned instead.
|
|
47
|
+
|
|
48
|
+
Namespace support is not enabled by default. To enabled it
|
|
49
|
+
call:
|
|
50
|
+
|
|
51
|
+
sklearn.set_config(array_api_dispatch=True)
|
|
52
|
+
|
|
53
|
+
or:
|
|
54
|
+
|
|
55
|
+
with sklearn.config_context(array_api_dispatch=True):
|
|
56
|
+
# your code here
|
|
57
|
+
|
|
58
|
+
Otherwise an instance of the `_NumPyApiWrapper`
|
|
59
|
+
compatibility wrapper is always returned irrespective of
|
|
60
|
+
the fact that arrays implement the `__array_namespace__`
|
|
61
|
+
protocol or not.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
*arrays : array objects
|
|
66
|
+
Array objects.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
namespace : module
|
|
71
|
+
Namespace shared by array objects.
|
|
72
|
+
|
|
73
|
+
is_array_api : bool
|
|
74
|
+
True of the arrays are containers that implement the Array API spec.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
# sycl support designed to work regardless of array_api_dispatch sklearn global value
|
|
78
|
+
sycl_type = {type(x): x for x in arrays if hasattr(x, "__sycl_usm_array_interface__")}
|
|
79
|
+
|
|
80
|
+
if len(sycl_type) > 1:
|
|
81
|
+
raise ValueError(f"Multiple SYCL types for array inputs: {sycl_type}")
|
|
82
|
+
|
|
83
|
+
if sycl_type:
|
|
84
|
+
|
|
85
|
+
(X,) = sycl_type.values()
|
|
86
|
+
|
|
87
|
+
if hasattr(X, "__array_namespace__"):
|
|
88
|
+
return X.__array_namespace__(), True
|
|
89
|
+
elif dpnp_available and isinstance(X, dpnp.ndarray):
|
|
90
|
+
return dpnp, False
|
|
91
|
+
else:
|
|
92
|
+
raise ValueError(f"SYCL type not recognized: {sycl_type}")
|
|
93
|
+
|
|
94
|
+
elif sklearn_check_version("1.2"):
|
|
95
|
+
return sklearn_get_namespace(*arrays)
|
|
96
|
+
else:
|
|
97
|
+
return np, True
|
{scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/LICENSE.txt
RENAMED
|
File without changes
|