scikit-learn-intelex 2025.8.0__py39-none-manylinux_2_28_x86_64.whl → 2025.9.0__py39-none-manylinux_2_28_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.
- daal4py/_daal4py.cpython-39-x86_64-linux-gnu.so +0 -0
- daal4py/mb/__init__.py +19 -8
- daal4py/mb/logistic_regression_builders.py +17 -23
- daal4py/mpi_transceiver.cpython-39-x86_64-linux-gnu.so +0 -0
- daal4py/sklearn/linear_model/logistic_path.py +57 -128
- daal4py/sklearn/monkeypatch/tests/_models_info.py +5 -2
- daal4py/sklearn/utils/validation.py +2 -2
- onedal/_onedal_py_dpc.cpython-39-x86_64-linux-gnu.so +0 -0
- onedal/_onedal_py_host.cpython-39-x86_64-linux-gnu.so +0 -0
- onedal/_onedal_py_spmd_dpc.cpython-39-x86_64-linux-gnu.so +0 -0
- onedal/covariance/covariance.py +1 -8
- onedal/covariance/incremental_covariance.py +13 -18
- onedal/covariance/tests/test_covariance.py +3 -3
- onedal/datatypes/_data_conversion.py +3 -1
- onedal/datatypes/_dlpack.py +8 -5
- onedal/datatypes/tests/test_data.py +69 -1
- onedal/decomposition/incremental_pca.py +39 -40
- onedal/decomposition/pca.py +49 -125
- onedal/decomposition/tests/test_incremental_pca.py +11 -5
- onedal/linear_model/logistic_regression.py +20 -1
- onedal/neighbors/neighbors.py +5 -4
- onedal/spmd/neighbors/__init__.py +2 -2
- onedal/spmd/neighbors/neighbors.py +30 -0
- {scikit_learn_intelex-2025.8.0.dist-info → scikit_learn_intelex-2025.9.0.dist-info}/METADATA +84 -91
- {scikit_learn_intelex-2025.8.0.dist-info → scikit_learn_intelex-2025.9.0.dist-info}/RECORD +51 -51
- sklearnex/_config.py +0 -5
- sklearnex/covariance/incremental_covariance.py +139 -100
- sklearnex/covariance/tests/test_incremental_covariance.py +30 -0
- sklearnex/decomposition/pca.py +349 -219
- sklearnex/decomposition/tests/test_pca.py +56 -2
- sklearnex/linear_model/logistic_regression.py +115 -39
- sklearnex/linear_model/tests/test_logreg.py +110 -122
- sklearnex/preview/covariance/covariance.py +157 -25
- sklearnex/preview/decomposition/incremental_pca.py +251 -72
- sklearnex/preview/decomposition/tests/test_incremental_pca.py +55 -1
- sklearnex/spmd/covariance/covariance.py +7 -4
- sklearnex/spmd/covariance/tests/test_covariance_spmd.py +7 -4
- sklearnex/spmd/covariance/tests/test_incremental_covariance_spmd.py +7 -2
- sklearnex/spmd/decomposition/pca.py +6 -4
- sklearnex/spmd/decomposition/tests/test_incremental_pca_spmd.py +2 -2
- sklearnex/spmd/decomposition/tests/test_pca_spmd.py +19 -6
- sklearnex/spmd/neighbors/__init__.py +6 -2
- sklearnex/spmd/neighbors/tests/test_neighbors_spmd.py +136 -13
- sklearnex/svm/_common.py +71 -8
- sklearnex/tests/test_common.py +0 -1
- sklearnex/tests/test_memory_usage.py +1 -1
- sklearnex/tests/test_patching.py +7 -3
- sklearnex/utils/_array_api.py +65 -1
- {scikit_learn_intelex-2025.8.0.dist-info → scikit_learn_intelex-2025.9.0.dist-info}/LICENSE.txt +0 -0
- {scikit_learn_intelex-2025.8.0.dist-info → scikit_learn_intelex-2025.9.0.dist-info}/WHEEL +0 -0
- {scikit_learn_intelex-2025.8.0.dist-info → scikit_learn_intelex-2025.9.0.dist-info}/top_level.txt +0 -0
|
Binary file
|
daal4py/mb/__init__.py
CHANGED
|
@@ -53,15 +53,26 @@ def convert_model(model) -> "GBTDAALModel | LogisticDAALModel":
|
|
|
53
53
|
offers faster prediction methods.
|
|
54
54
|
"""
|
|
55
55
|
if isinstance(model, LogisticRegression):
|
|
56
|
+
# The multi_class keyword is removed in scikit-learn 1.8, and OvR functionality
|
|
57
|
+
# has been replaced by other estimators. Therefore checking for linear classifiers
|
|
58
|
+
# only dependent on the solver.
|
|
56
59
|
if model.classes_.shape[0] > 2:
|
|
57
|
-
if (model
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
64
|
-
|
|
60
|
+
if not hasattr(model, "multi_class"):
|
|
61
|
+
if model.solver == "liblinear":
|
|
62
|
+
raise TypeError(
|
|
63
|
+
"Supplied 'model' object is a linear classifier, but not multinomial logistic"
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
if (model.multi_class == "ovr") or (
|
|
67
|
+
model.multi_class == "auto" and model.solver == "liblinear"
|
|
68
|
+
):
|
|
69
|
+
raise TypeError(
|
|
70
|
+
"Supplied 'model' object is a linear classifier, but not multinomial logistic"
|
|
71
|
+
" (hint: pass multi_class='multinomial' to 'LogisticRegression')."
|
|
72
|
+
)
|
|
73
|
+
elif (model.classes_.shape[0] == 2) and (
|
|
74
|
+
getattr(model, "multi_class", "auto") == "multinomial"
|
|
75
|
+
):
|
|
65
76
|
raise TypeError(
|
|
66
77
|
"Supplied 'model' object is not a logistic regressor "
|
|
67
78
|
"(hint: pass multi_class='auto' to 'LogisticRegression')."
|
|
@@ -97,21 +97,6 @@ class LogisticDAALModel:
|
|
|
97
97
|
)
|
|
98
98
|
builder.set_beta(coefs, intercepts)
|
|
99
99
|
self._model = builder.model
|
|
100
|
-
self._alg_pred_class = logistic_regression_prediction(
|
|
101
|
-
nClasses=self.n_classes_,
|
|
102
|
-
fptype=self._fptype,
|
|
103
|
-
resultsToEvaluate="computeClassLabels",
|
|
104
|
-
)
|
|
105
|
-
self._alg_pred_prob = logistic_regression_prediction(
|
|
106
|
-
nClasses=self.n_classes_,
|
|
107
|
-
fptype=self._fptype,
|
|
108
|
-
resultsToEvaluate="computeClassProbabilities",
|
|
109
|
-
)
|
|
110
|
-
self._alg_pred_logprob = logistic_regression_prediction(
|
|
111
|
-
nClasses=self.n_classes_,
|
|
112
|
-
fptype=self._fptype,
|
|
113
|
-
resultsToEvaluate="computeClassLogProbabilities",
|
|
114
|
-
)
|
|
115
100
|
|
|
116
101
|
@property
|
|
117
102
|
def coef_(self):
|
|
@@ -121,6 +106,15 @@ class LogisticDAALModel:
|
|
|
121
106
|
def intercept_(self):
|
|
122
107
|
return self._model.Beta[:, 0]
|
|
123
108
|
|
|
109
|
+
def _logistic_regression_prediction(
|
|
110
|
+
self, X: np.ndarray, resultsToEvaluate: str
|
|
111
|
+
) -> classifier_prediction_result:
|
|
112
|
+
return logistic_regression_prediction(
|
|
113
|
+
nClasses=self.n_classes_,
|
|
114
|
+
fptype=self._fptype,
|
|
115
|
+
resultsToEvaluate=resultsToEvaluate,
|
|
116
|
+
).compute(X, self._model)
|
|
117
|
+
|
|
124
118
|
def predict(self, X) -> np.ndarray:
|
|
125
119
|
"""
|
|
126
120
|
Predict most probable class
|
|
@@ -133,7 +127,7 @@ class LogisticDAALModel:
|
|
|
133
127
|
The most probable class, as integer indexes
|
|
134
128
|
"""
|
|
135
129
|
return (
|
|
136
|
-
self.
|
|
130
|
+
self._logistic_regression_prediction(X, "computeClassLabels")
|
|
137
131
|
.prediction.reshape(-1)
|
|
138
132
|
.astype(int)
|
|
139
133
|
)
|
|
@@ -151,7 +145,9 @@ class LogisticDAALModel:
|
|
|
151
145
|
proba : array(n_samples, n_classes)
|
|
152
146
|
The predicted probabilities for each class.
|
|
153
147
|
"""
|
|
154
|
-
return self.
|
|
148
|
+
return self._logistic_regression_prediction(
|
|
149
|
+
X, "computeClassProbabilities"
|
|
150
|
+
).probabilities
|
|
155
151
|
|
|
156
152
|
predict_proba.__doc__ = predict_proba.__doc__.replace(r"%docstring_X%", _docstring_X)
|
|
157
153
|
|
|
@@ -166,7 +162,9 @@ class LogisticDAALModel:
|
|
|
166
162
|
log_proba : array(n_samples, n_classes)
|
|
167
163
|
The logarithms of the predicted probabilities for each class.
|
|
168
164
|
"""
|
|
169
|
-
return self.
|
|
165
|
+
return self._logistic_regression_prediction(
|
|
166
|
+
X, "computeClassLogProbabilities"
|
|
167
|
+
).logProbabilities
|
|
170
168
|
|
|
171
169
|
predict_log_proba.__doc__ = predict_log_proba.__doc__.replace(
|
|
172
170
|
r"%docstring_X%", _docstring_X
|
|
@@ -206,11 +204,7 @@ class LogisticDAALModel:
|
|
|
206
204
|
raise ValueError(
|
|
207
205
|
"Must request at least one of 'classes', 'proba', 'log_proba'."
|
|
208
206
|
)
|
|
209
|
-
return
|
|
210
|
-
nClasses=self.n_classes_,
|
|
211
|
-
fptype=self._fptype,
|
|
212
|
-
resultsToEvaluate=pred_request,
|
|
213
|
-
).compute(X, self._model)
|
|
207
|
+
return self._logistic_regression_prediction(X, pred_request)
|
|
214
208
|
|
|
215
209
|
predict_multiple.__doc__ = predict_multiple.__doc__.replace(
|
|
216
210
|
r"%docstring_X%", _docstring_X
|
|
Binary file
|
|
@@ -20,15 +20,14 @@ import numpy as np
|
|
|
20
20
|
import scipy.optimize as optimize
|
|
21
21
|
import scipy.sparse as sparse
|
|
22
22
|
import sklearn.linear_model._logistic as logistic_module
|
|
23
|
-
from sklearn.linear_model.
|
|
24
|
-
from sklearn.
|
|
25
|
-
|
|
26
|
-
check_consistent_length,
|
|
27
|
-
check_random_state,
|
|
28
|
-
compute_class_weight,
|
|
23
|
+
from sklearn.linear_model._logistic import _LOGISTIC_SOLVER_CONVERGENCE_MSG
|
|
24
|
+
from sklearn.linear_model._logistic import (
|
|
25
|
+
LogisticRegression as LogisticRegression_original,
|
|
29
26
|
)
|
|
27
|
+
from sklearn.linear_model._logistic import _check_solver
|
|
28
|
+
from sklearn.utils import check_array, check_consistent_length, check_random_state
|
|
30
29
|
from sklearn.utils.optimize import _check_optimize_result, _newton_cg
|
|
31
|
-
from sklearn.utils.validation import
|
|
30
|
+
from sklearn.utils.validation import check_is_fitted
|
|
32
31
|
|
|
33
32
|
import daal4py as d4p
|
|
34
33
|
|
|
@@ -44,35 +43,6 @@ from .logistic_loss import (
|
|
|
44
43
|
_daal4py_loss_and_grad,
|
|
45
44
|
)
|
|
46
45
|
|
|
47
|
-
if sklearn_check_version("1.1"):
|
|
48
|
-
from sklearn._loss.loss import HalfBinomialLoss, HalfMultinomialLoss
|
|
49
|
-
from sklearn.linear_model._linear_loss import LinearModelLoss
|
|
50
|
-
from sklearn.linear_model._logistic import _LOGISTIC_SOLVER_CONVERGENCE_MSG
|
|
51
|
-
from sklearn.linear_model._logistic import (
|
|
52
|
-
LogisticRegression as LogisticRegression_original,
|
|
53
|
-
)
|
|
54
|
-
from sklearn.linear_model._logistic import (
|
|
55
|
-
_check_multi_class,
|
|
56
|
-
_check_solver,
|
|
57
|
-
_fit_liblinear,
|
|
58
|
-
)
|
|
59
|
-
else:
|
|
60
|
-
from sklearn.linear_model._logistic import _LOGISTIC_SOLVER_CONVERGENCE_MSG
|
|
61
|
-
from sklearn.linear_model._logistic import (
|
|
62
|
-
LogisticRegression as LogisticRegression_original,
|
|
63
|
-
)
|
|
64
|
-
from sklearn.linear_model._logistic import (
|
|
65
|
-
_check_multi_class,
|
|
66
|
-
_check_solver,
|
|
67
|
-
_fit_liblinear,
|
|
68
|
-
_logistic_grad_hess,
|
|
69
|
-
_logistic_loss,
|
|
70
|
-
_logistic_loss_and_grad,
|
|
71
|
-
_multinomial_grad_hess,
|
|
72
|
-
_multinomial_loss,
|
|
73
|
-
_multinomial_loss_grad,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
46
|
if sklearn_check_version("1.7.1"):
|
|
77
47
|
from sklearn.utils.fixes import _get_additional_lbfgs_options_dict
|
|
78
48
|
else:
|
|
@@ -86,6 +56,25 @@ from sklearn.linear_model._logistic import _logistic_regression_path as lr_path_
|
|
|
86
56
|
from sklearn.preprocessing import LabelBinarizer, LabelEncoder
|
|
87
57
|
|
|
88
58
|
|
|
59
|
+
# This code is a patch for sklearn 1.8, which is related to https://github.com/scikit-learn/scikit-learn/pull/32073
|
|
60
|
+
# where the multi_class keyword is deprecated and this aspect is removed.
|
|
61
|
+
def _check_multi_class(multi_class, solver, n_classes):
|
|
62
|
+
"""Computes the multi class type, either "multinomial" or "ovr".
|
|
63
|
+
For `n_classes` > 2 and a solver that supports it, returns "multinomial".
|
|
64
|
+
For all other cases, in particular binary classification, return "ovr".
|
|
65
|
+
"""
|
|
66
|
+
if multi_class == "auto":
|
|
67
|
+
if solver in ("liblinear",):
|
|
68
|
+
multi_class = "ovr"
|
|
69
|
+
elif n_classes > 2:
|
|
70
|
+
multi_class = "multinomial"
|
|
71
|
+
else:
|
|
72
|
+
multi_class = "ovr"
|
|
73
|
+
if multi_class == "multinomial" and solver in ("liblinear",):
|
|
74
|
+
raise ValueError("Solver %s does not support a multinomial backend." % solver)
|
|
75
|
+
return multi_class
|
|
76
|
+
|
|
77
|
+
|
|
89
78
|
# Code adapted from sklearn.linear_model.logistic version 0.21
|
|
90
79
|
def __logistic_regression_path(
|
|
91
80
|
X,
|
|
@@ -110,46 +99,6 @@ def __logistic_regression_path(
|
|
|
110
99
|
l1_ratio=None,
|
|
111
100
|
n_threads=1,
|
|
112
101
|
):
|
|
113
|
-
_patching_status = PatchingConditionsChain(
|
|
114
|
-
"sklearn.linear_model.LogisticRegression.fit"
|
|
115
|
-
)
|
|
116
|
-
_dal_ready = _patching_status.and_conditions(
|
|
117
|
-
[
|
|
118
|
-
(
|
|
119
|
-
solver in ["lbfgs", "newton-cg"],
|
|
120
|
-
f"'{solver}' solver is not supported. "
|
|
121
|
-
"Only 'lbfgs' and 'newton-cg' solvers are supported.",
|
|
122
|
-
),
|
|
123
|
-
(not sparse.issparse(X), "X is sparse. Sparse input is not supported."),
|
|
124
|
-
(sample_weight is None, "Sample weights are not supported."),
|
|
125
|
-
(class_weight is None, "Class weights are not supported."),
|
|
126
|
-
]
|
|
127
|
-
)
|
|
128
|
-
if not _dal_ready:
|
|
129
|
-
_patching_status.write_log()
|
|
130
|
-
return lr_path_original(
|
|
131
|
-
X,
|
|
132
|
-
y,
|
|
133
|
-
pos_class=pos_class,
|
|
134
|
-
Cs=Cs,
|
|
135
|
-
fit_intercept=fit_intercept,
|
|
136
|
-
max_iter=max_iter,
|
|
137
|
-
tol=tol,
|
|
138
|
-
verbose=verbose,
|
|
139
|
-
solver=solver,
|
|
140
|
-
coef=coef,
|
|
141
|
-
class_weight=class_weight,
|
|
142
|
-
dual=dual,
|
|
143
|
-
penalty=penalty,
|
|
144
|
-
intercept_scaling=intercept_scaling,
|
|
145
|
-
multi_class=multi_class,
|
|
146
|
-
random_state=random_state,
|
|
147
|
-
check_input=check_input,
|
|
148
|
-
max_squared_sum=max_squared_sum,
|
|
149
|
-
sample_weight=sample_weight,
|
|
150
|
-
l1_ratio=l1_ratio,
|
|
151
|
-
**({"n_threads": n_threads} if sklearn_check_version("1.1") else {}),
|
|
152
|
-
)
|
|
153
102
|
|
|
154
103
|
# Comment 2025-08-04: this file might have dead code paths from unsupported solvers.
|
|
155
104
|
# It appears to have initially been a copy-paste of scikit-learn with a few additions
|
|
@@ -269,7 +218,6 @@ def __logistic_regression_path(
|
|
|
269
218
|
func = _daal4py_loss_
|
|
270
219
|
grad = _daal4py_grad_
|
|
271
220
|
hess = _daal4py_grad_hess_
|
|
272
|
-
warm_start_sag = {"coef": w0.T}
|
|
273
221
|
else:
|
|
274
222
|
target = y_bin
|
|
275
223
|
if solver == "lbfgs":
|
|
@@ -280,7 +228,6 @@ def __logistic_regression_path(
|
|
|
280
228
|
func = _daal4py_loss_
|
|
281
229
|
grad = _daal4py_grad_
|
|
282
230
|
hess = _daal4py_grad_hess_
|
|
283
|
-
warm_start_sag = {"coef": np.expand_dims(w0, axis=1)}
|
|
284
231
|
|
|
285
232
|
coefs = list()
|
|
286
233
|
n_iter = np.zeros(len(Cs), dtype=np.int32)
|
|
@@ -385,8 +332,6 @@ def __logistic_regression_path(
|
|
|
385
332
|
for i, ci in enumerate(coefs):
|
|
386
333
|
coefs[i] = np.delete(ci, 0, axis=-1)
|
|
387
334
|
|
|
388
|
-
_patching_status.write_log()
|
|
389
|
-
|
|
390
335
|
return np.array(coefs), np.array(Cs), n_iter
|
|
391
336
|
|
|
392
337
|
|
|
@@ -427,12 +372,13 @@ def daal4py_predict(self, X, resultsToEvaluate):
|
|
|
427
372
|
f"sklearn.linear_model.LogisticRegression.{_function_name}"
|
|
428
373
|
)
|
|
429
374
|
if _function_name != "predict":
|
|
375
|
+
multi_class = getattr(self, "multi_class", "auto")
|
|
430
376
|
_patching_status.and_conditions(
|
|
431
377
|
[
|
|
432
378
|
(
|
|
433
379
|
self.classes_.size == 2
|
|
434
|
-
or
|
|
435
|
-
|
|
380
|
+
or _check_multi_class(
|
|
381
|
+
multi_class if multi_class != "deprecated" else "auto",
|
|
436
382
|
self.solver,
|
|
437
383
|
self.classes_.size,
|
|
438
384
|
)
|
|
@@ -440,7 +386,7 @@ def daal4py_predict(self, X, resultsToEvaluate):
|
|
|
440
386
|
f"selected multiclass option is not supported for n_classes > 2.",
|
|
441
387
|
),
|
|
442
388
|
(
|
|
443
|
-
not (self.classes_.size == 2 and
|
|
389
|
+
not (self.classes_.size == 2 and multi_class == "multinomial"),
|
|
444
390
|
"multi_class='multinomial' not supported with binary data",
|
|
445
391
|
),
|
|
446
392
|
],
|
|
@@ -502,52 +448,35 @@ def daal4py_predict(self, X, resultsToEvaluate):
|
|
|
502
448
|
return LogisticRegression_original.predict_log_proba(self, X)
|
|
503
449
|
|
|
504
450
|
|
|
505
|
-
def logistic_regression_path(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
random_state=None,
|
|
522
|
-
check_input=True,
|
|
523
|
-
max_squared_sum=None,
|
|
524
|
-
sample_weight=None,
|
|
525
|
-
l1_ratio=None,
|
|
526
|
-
n_threads=1,
|
|
527
|
-
):
|
|
528
|
-
return __logistic_regression_path(
|
|
529
|
-
X,
|
|
530
|
-
y,
|
|
531
|
-
pos_class=pos_class,
|
|
532
|
-
Cs=Cs,
|
|
533
|
-
fit_intercept=fit_intercept,
|
|
534
|
-
max_iter=max_iter,
|
|
535
|
-
tol=tol,
|
|
536
|
-
verbose=verbose,
|
|
537
|
-
solver=solver,
|
|
538
|
-
coef=coef,
|
|
539
|
-
class_weight=class_weight,
|
|
540
|
-
dual=dual,
|
|
541
|
-
penalty=penalty,
|
|
542
|
-
intercept_scaling=intercept_scaling,
|
|
543
|
-
multi_class=multi_class,
|
|
544
|
-
random_state=random_state,
|
|
545
|
-
check_input=check_input,
|
|
546
|
-
max_squared_sum=max_squared_sum,
|
|
547
|
-
sample_weight=sample_weight,
|
|
548
|
-
l1_ratio=l1_ratio,
|
|
549
|
-
n_threads=n_threads,
|
|
451
|
+
def logistic_regression_path(*args, **kwargs):
|
|
452
|
+
|
|
453
|
+
_patching_status = PatchingConditionsChain(
|
|
454
|
+
"sklearn.linear_model.LogisticRegression.fit"
|
|
455
|
+
)
|
|
456
|
+
_dal_ready = _patching_status.and_conditions(
|
|
457
|
+
[
|
|
458
|
+
(
|
|
459
|
+
kwargs["solver"] in ["lbfgs", "newton-cg"],
|
|
460
|
+
f"'{kwargs['solver']}' solver is not supported. "
|
|
461
|
+
"Only 'lbfgs' and 'newton-cg' solvers are supported.",
|
|
462
|
+
),
|
|
463
|
+
(not sparse.issparse(args[0]), "X is sparse. Sparse input is not supported."),
|
|
464
|
+
(kwargs["sample_weight"] is None, "Sample weights are not supported."),
|
|
465
|
+
(kwargs["class_weight"] is None, "Class weights are not supported."),
|
|
466
|
+
]
|
|
550
467
|
)
|
|
468
|
+
if not _dal_ready:
|
|
469
|
+
_patching_status.write_log()
|
|
470
|
+
return lr_path_original(*args, **kwargs)
|
|
471
|
+
|
|
472
|
+
if sklearn_check_version("1.8"):
|
|
473
|
+
kwargs.pop("classes", None)
|
|
474
|
+
res = __logistic_regression_path(*(args[:2]), **kwargs)
|
|
475
|
+
else:
|
|
476
|
+
res = __logistic_regression_path(*args, **kwargs)
|
|
477
|
+
|
|
478
|
+
_patching_status.write_log()
|
|
479
|
+
return res
|
|
551
480
|
|
|
552
481
|
|
|
553
482
|
@control_n_jobs(
|
|
@@ -30,7 +30,7 @@ from sklearn.manifold import TSNE
|
|
|
30
30
|
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor, NearestNeighbors
|
|
31
31
|
from sklearn.svm import SVC
|
|
32
32
|
|
|
33
|
-
from daal4py.sklearn._utils import daal_check_version
|
|
33
|
+
from daal4py.sklearn._utils import daal_check_version, sklearn_check_version
|
|
34
34
|
|
|
35
35
|
MODELS_INFO = [
|
|
36
36
|
{
|
|
@@ -84,7 +84,10 @@ MODELS_INFO = [
|
|
|
84
84
|
"dataset": "classifier",
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
|
-
"model": LogisticRegression(
|
|
87
|
+
"model": LogisticRegression(
|
|
88
|
+
max_iter=100,
|
|
89
|
+
**({} if sklearn_check_version("1.8") else {"multi_class": "multinomial"})
|
|
90
|
+
),
|
|
88
91
|
"methods": [
|
|
89
92
|
"decision_function",
|
|
90
93
|
"predict",
|
|
@@ -280,9 +280,9 @@ def _daal_check_array(
|
|
|
280
280
|
array_converted : object
|
|
281
281
|
The converted and validated array.
|
|
282
282
|
"""
|
|
283
|
-
if force_all_finite not in (True, False, "allow-nan"):
|
|
283
|
+
if force_all_finite not in (True, False, "allow-nan", None):
|
|
284
284
|
raise ValueError(
|
|
285
|
-
'force_all_finite should be a bool or "allow-nan"'
|
|
285
|
+
'force_all_finite should be a bool, None, or "allow-nan"'
|
|
286
286
|
". Got {!r} instead".format(force_all_finite)
|
|
287
287
|
)
|
|
288
288
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
onedal/covariance/covariance.py
CHANGED
|
@@ -20,7 +20,6 @@ import numpy as np
|
|
|
20
20
|
from daal4py.sklearn._utils import daal_check_version
|
|
21
21
|
from onedal._device_offload import supports_queue
|
|
22
22
|
from onedal.common._backend import bind_default_backend
|
|
23
|
-
from onedal.utils.validation import _check_array
|
|
24
23
|
|
|
25
24
|
from .._config import _get_config
|
|
26
25
|
from ..common.hyperparameters import get_hyperparameters
|
|
@@ -101,13 +100,7 @@ class EmpiricalCovariance(BaseEmpiricalCovariance):
|
|
|
101
100
|
self : object
|
|
102
101
|
Returns the instance itself.
|
|
103
102
|
"""
|
|
104
|
-
use_raw_input = _get_config()["use_raw_input"] is True
|
|
105
|
-
sua_iface, xp, _ = _get_sycl_namespace(X)
|
|
106
|
-
if use_raw_input and sua_iface:
|
|
107
|
-
queue = X.sycl_queue
|
|
108
103
|
|
|
109
|
-
if not use_raw_input:
|
|
110
|
-
X = _check_array(X, dtype=[np.float64, np.float32])
|
|
111
104
|
X_table = to_table(X, queue=queue)
|
|
112
105
|
|
|
113
106
|
params = self._get_onedal_params(X_table.dtype)
|
|
@@ -123,6 +116,6 @@ class EmpiricalCovariance(BaseEmpiricalCovariance):
|
|
|
123
116
|
from_table(result.cov_matrix, like=X) * (X.shape[0] - 1) / X.shape[0]
|
|
124
117
|
)
|
|
125
118
|
|
|
126
|
-
self.location_ =
|
|
119
|
+
self.location_ = from_table(result.means, like=X)[0, ...]
|
|
127
120
|
|
|
128
121
|
return self
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
|
|
19
19
|
from daal4py.sklearn._utils import daal_check_version
|
|
20
|
-
from onedal._device_offload import supports_queue
|
|
21
|
-
from onedal.common._backend import bind_default_backend
|
|
22
|
-
from onedal.utils import _sycl_queue_manager as QM
|
|
23
20
|
|
|
24
21
|
from .._config import _get_config
|
|
25
|
-
from ..
|
|
22
|
+
from .._device_offload import supports_queue
|
|
23
|
+
from ..common._backend import bind_default_backend
|
|
24
|
+
from ..datatypes import from_table, return_type_constructor, to_table
|
|
25
|
+
from ..utils import _sycl_queue_manager as QM
|
|
26
26
|
from ..utils._array_api import _get_sycl_namespace
|
|
27
27
|
from ..utils.validation import _check_array
|
|
28
28
|
from .covariance import BaseEmpiricalCovariance
|
|
@@ -74,6 +74,7 @@ class IncrementalEmpiricalCovariance(BaseEmpiricalCovariance):
|
|
|
74
74
|
def _reset(self):
|
|
75
75
|
self._need_to_finalize = False
|
|
76
76
|
self._queue = None
|
|
77
|
+
self._outtype = None
|
|
77
78
|
self._partial_result = self.partial_compute_result()
|
|
78
79
|
|
|
79
80
|
def __getstate__(self):
|
|
@@ -108,15 +109,10 @@ class IncrementalEmpiricalCovariance(BaseEmpiricalCovariance):
|
|
|
108
109
|
self : object
|
|
109
110
|
Returns the instance itself.
|
|
110
111
|
"""
|
|
111
|
-
use_raw_input = _get_config()["use_raw_input"] is True
|
|
112
|
-
sua_iface, _, _ = _get_sycl_namespace(X)
|
|
113
|
-
|
|
114
|
-
if use_raw_input and sua_iface:
|
|
115
|
-
queue = X.sycl_queue
|
|
116
|
-
if not use_raw_input:
|
|
117
|
-
X = _check_array(X, dtype=[np.float64, np.float32], ensure_2d=True)
|
|
118
112
|
|
|
119
113
|
self._queue = queue
|
|
114
|
+
if not self._outtype:
|
|
115
|
+
self._outtype = return_type_constructor(X)
|
|
120
116
|
X_table = to_table(X, queue=queue)
|
|
121
117
|
|
|
122
118
|
if not hasattr(self, "_dtype"):
|
|
@@ -125,8 +121,6 @@ class IncrementalEmpiricalCovariance(BaseEmpiricalCovariance):
|
|
|
125
121
|
params = self._get_onedal_params(self._dtype)
|
|
126
122
|
self._partial_result = self.partial_compute(params, self._partial_result, X_table)
|
|
127
123
|
self._need_to_finalize = True
|
|
128
|
-
# store the queue for when we finalize
|
|
129
|
-
self._queue = queue
|
|
130
124
|
|
|
131
125
|
def finalize_fit(self):
|
|
132
126
|
"""Finalize covariance matrix from the current `_partial_result`.
|
|
@@ -143,13 +137,14 @@ class IncrementalEmpiricalCovariance(BaseEmpiricalCovariance):
|
|
|
143
137
|
with QM.manage_global_queue(self._queue):
|
|
144
138
|
result = self.finalize_compute(params, self._partial_result)
|
|
145
139
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
140
|
+
self.covariance_ = from_table(result.cov_matrix, like=self._outtype)
|
|
141
|
+
|
|
142
|
+
if self.bias and not daal_check_version((2024, "P", 1)):
|
|
149
143
|
n_rows = self._partial_result.partial_n_rows
|
|
150
|
-
self.covariance_
|
|
144
|
+
self.covariance_ *= (n_rows - 1) / n_rows
|
|
151
145
|
|
|
152
|
-
self.location_ = from_table(result.means
|
|
146
|
+
self.location_ = from_table(result.means, like=self._outtype)[0, ...]
|
|
147
|
+
self._outtype = None
|
|
153
148
|
|
|
154
149
|
self._need_to_finalize = False
|
|
155
150
|
|
|
@@ -25,7 +25,7 @@ from onedal.tests.utils._device_selection import get_queues
|
|
|
25
25
|
def test_onedal_import_covariance(queue):
|
|
26
26
|
from onedal.covariance import EmpiricalCovariance
|
|
27
27
|
|
|
28
|
-
X = np.array([[0, 1], [0, 1]])
|
|
28
|
+
X = np.array([[0, 1], [0, 1]], dtype=np.float64)
|
|
29
29
|
result = EmpiricalCovariance().fit(X, queue=queue)
|
|
30
30
|
expected_covariance = np.array([[0, 0], [0, 0]])
|
|
31
31
|
expected_means = np.array([0, 1])
|
|
@@ -33,7 +33,7 @@ def test_onedal_import_covariance(queue):
|
|
|
33
33
|
assert_allclose(expected_covariance, result.covariance_)
|
|
34
34
|
assert_allclose(expected_means, result.location_)
|
|
35
35
|
|
|
36
|
-
X = np.array([[1, 2], [3, 6]])
|
|
36
|
+
X = np.array([[1, 2], [3, 6]], dtype=np.float64)
|
|
37
37
|
result = EmpiricalCovariance().fit(X, queue=queue)
|
|
38
38
|
expected_covariance = np.array([[2, 4], [4, 8]])
|
|
39
39
|
expected_means = np.array([2, 4])
|
|
@@ -41,7 +41,7 @@ def test_onedal_import_covariance(queue):
|
|
|
41
41
|
assert_allclose(expected_covariance, result.covariance_)
|
|
42
42
|
assert_allclose(expected_means, result.location_)
|
|
43
43
|
|
|
44
|
-
X = np.array([[1, 2], [3, 6]])
|
|
44
|
+
X = np.array([[1, 2], [3, 6]], dtype=np.float64)
|
|
45
45
|
result = EmpiricalCovariance(bias=True).fit(X, queue=queue)
|
|
46
46
|
expected_covariance = np.array([[1, 2], [2, 4]])
|
|
47
47
|
expected_means = np.array([2, 4])
|
|
@@ -112,7 +112,9 @@ def return_type_constructor(array):
|
|
|
112
112
|
)
|
|
113
113
|
|
|
114
114
|
elif hasattr(array, "__array_namespace__"):
|
|
115
|
-
|
|
115
|
+
xp = array.__array_namespace__()
|
|
116
|
+
device = array.device
|
|
117
|
+
func = lambda inp: xp.from_dlpack(inp, device=device)
|
|
116
118
|
else:
|
|
117
119
|
try:
|
|
118
120
|
func = _compat_convert(array)
|
onedal/datatypes/_dlpack.py
CHANGED
|
@@ -45,11 +45,14 @@ def dlpack_to_numpy(obj):
|
|
|
45
45
|
raise TypeError(f"cannot move {type(obj)} to cpu")
|
|
46
46
|
|
|
47
47
|
# convert to numpy
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
try:
|
|
49
|
+
# Some frameworks implement an __array__ method just to
|
|
50
|
+
# throw a RuntimeError when used (array_api_strict, dpctl),
|
|
51
|
+
# or a TypeError (array_api-strict) rather than an AttributeError
|
|
52
|
+
# therefore a try catch is necessary (logic is essentially a
|
|
53
|
+
# getattr call + some)
|
|
54
|
+
obj = obj.__array__()
|
|
55
|
+
except (AttributeError, RuntimeError, TypeError):
|
|
53
56
|
# requires numpy 1.23
|
|
54
57
|
try:
|
|
55
58
|
obj = np.from_dlpack(obj)
|
|
@@ -578,7 +578,7 @@ def test_table_conversions_dlpack(dataframe, queue, order, data_shape, dtype):
|
|
|
578
578
|
|
|
579
579
|
|
|
580
580
|
@pytest.mark.parametrize(
|
|
581
|
-
"dataframe,queue", get_dataframes_and_queues("dpctl,
|
|
581
|
+
"dataframe,queue", get_dataframes_and_queues("numpy,dpctl,array_api", "cpu,gpu")
|
|
582
582
|
)
|
|
583
583
|
@pytest.mark.parametrize("order", ["F", "C"])
|
|
584
584
|
@pytest.mark.parametrize("data_shape", data_shapes)
|
|
@@ -616,3 +616,71 @@ def test_table___dlpack__(dataframe, queue, order, data_shape, dtype):
|
|
|
616
616
|
del capsule
|
|
617
617
|
gc.collect()
|
|
618
618
|
assert_allclose(np.squeeze(from_table(X_table)), np.squeeze(X))
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
@pytest.mark.skipif(
|
|
622
|
+
not hasattr(np, "from_dlpack"), reason="no dlpack support in installed numpy"
|
|
623
|
+
)
|
|
624
|
+
@pytest.mark.parametrize("dataframe,queue", get_dataframes_and_queues("dpctl", "cpu,gpu"))
|
|
625
|
+
@pytest.mark.parametrize("order", ["F", "C"])
|
|
626
|
+
@pytest.mark.parametrize("data_shape", data_shapes)
|
|
627
|
+
@pytest.mark.parametrize("dtype", [np.float32, np.float64, np.int32, np.int64])
|
|
628
|
+
def test_table_convert_to_host_dlpack(dataframe, queue, order, data_shape, dtype):
|
|
629
|
+
"""Test if __dlpack__ attribute can be properly consumed by moving data
|
|
630
|
+
to host from a SYCL device.
|
|
631
|
+
"""
|
|
632
|
+
rng = np.random.RandomState(0)
|
|
633
|
+
X = np.array(5 * rng.random_sample(data_shape), dtype=dtype)
|
|
634
|
+
|
|
635
|
+
X = ORDER_DICT[order](X)
|
|
636
|
+
|
|
637
|
+
X_df = _convert_to_dataframe(X, sycl_queue=queue, target_df=dataframe)
|
|
638
|
+
|
|
639
|
+
X_table = to_table(X_df)
|
|
640
|
+
# verify that it is on a kDLOneAPI device
|
|
641
|
+
assert X_df.__dlpack_device__() == X_table.__dlpack_device__()
|
|
642
|
+
|
|
643
|
+
# extract to numpy (which should move to host)
|
|
644
|
+
try:
|
|
645
|
+
X_out = np.from_dlpack(X_table)
|
|
646
|
+
except RuntimeError as e:
|
|
647
|
+
if "Unsupported device in DLTensor." in str(e):
|
|
648
|
+
pytest.skip("Numpy version cannot request device conversion")
|
|
649
|
+
else:
|
|
650
|
+
raise e
|
|
651
|
+
assert X_out.__dlpack_device__() != X_table.__dlpack_device__()
|
|
652
|
+
|
|
653
|
+
if X_out.dtype == X.dtype:
|
|
654
|
+
assert_array_equal(np.squeeze(X_out), np.squeeze(X))
|
|
655
|
+
else:
|
|
656
|
+
assert_allclose(np.squeeze(X_out), np.squeeze(X))
|
|
657
|
+
|
|
658
|
+
# verify that table immutability is gone and copy behavior has been followed
|
|
659
|
+
assert X_out.flags.writeable
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
@pytest.mark.parametrize("queue", get_queues())
|
|
663
|
+
def test_table_writable_dlpack(queue):
|
|
664
|
+
"""Test if __dlpack__ attribute can be properly consumed by moving data
|
|
665
|
+
to host from a SYCL device.
|
|
666
|
+
"""
|
|
667
|
+
xp = pytest.importorskip("dpctl.tensor")
|
|
668
|
+
X = xp.eye(5, 8, dtype=xp.float32, device=queue)
|
|
669
|
+
X.flags["W"] = False
|
|
670
|
+
X_table = to_table(X)
|
|
671
|
+
|
|
672
|
+
cpu_device = (backend.kDLCPU, 0)
|
|
673
|
+
# verify that it is on a kDLOneAPI device
|
|
674
|
+
assert X.__dlpack_device__() == X_table.__dlpack_device__()
|
|
675
|
+
assert X_table.__dlpack_device__() != cpu_device
|
|
676
|
+
|
|
677
|
+
# verify move to host
|
|
678
|
+
X_table.__dlpack__(dl_device=cpu_device)
|
|
679
|
+
# verify error is raised when copy=False
|
|
680
|
+
with pytest.raises(BufferError, match="Cannot transfer data to requested device"):
|
|
681
|
+
X_table.__dlpack__(dl_device=cpu_device, copy=False)
|
|
682
|
+
|
|
683
|
+
for copy_bool in [True, False]:
|
|
684
|
+
X_out = xp.from_dlpack(X_table, copy=copy_bool)
|
|
685
|
+
# verify that table immutability is gone and copy behavior has been followed
|
|
686
|
+
assert X_out.flags["W"] is copy_bool
|