Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions daal4py/sklearn/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from typing import Any, Tuple

import numpy as np
import scipy.sparse as sp
from numpy.lib.recfunctions import require_fields
from sklearn import __version__ as sklearn_version

Expand Down Expand Up @@ -195,6 +196,10 @@ def convert_to_old_tree_nodes(tree_nodes):
return convert_to_old_tree_nodes(tree_nodes)


def is_sparse(x):
return sp.issparse(x) or (is_DataFrame(x) and hasattr(x, "sparse"))


class PatchingConditionsChain:
def __init__(self, scope_name):
self.scope_name = scope_name
Expand Down
9 changes: 4 additions & 5 deletions daal4py/sklearn/linear_model/logistic_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import numpy as np
import scipy.optimize as optimize
import scipy.sparse as sparse
import sklearn.linear_model._logistic as logistic_module
from sklearn.linear_model._logistic import _LOGISTIC_SOLVER_CONVERGENCE_MSG
from sklearn.linear_model._logistic import (
Expand All @@ -32,7 +31,7 @@
import daal4py as d4p

from .._n_jobs_support import control_n_jobs
from .._utils import PatchingConditionsChain, getFPType, sklearn_check_version
from .._utils import PatchingConditionsChain, getFPType, is_sparse, sklearn_check_version
from ..utils.validation import check_feature_names
from .logistic_loss import (
_daal4py_cross_entropy_loss_extra_args,
Expand Down Expand Up @@ -400,9 +399,9 @@ def daal4py_predict(self, X, resultsToEvaluate):

_dal_ready = _patching_status.and_conditions(
[
(not sparse.issparse(X), "X is sparse. Sparse input is not supported."),
(not is_sparse(X), "X is sparse. Sparse input is not supported."),
(
not sparse.issparse(self.coef_),
not is_sparse(self.coef_),
"self.coef_ is sparse. Sparse coefficients are not supported.",
),
(fptype is not None, "Unable to get dtype."),
Expand Down Expand Up @@ -466,7 +465,7 @@ def logistic_regression_path(*args, **kwargs):
f"'{kwargs['solver']}' solver is not supported. "
"Only 'lbfgs' and 'newton-cg' solvers are supported.",
),
(not sparse.issparse(args[0]), "X is sparse. Sparse input is not supported."),
(not is_sparse(args[0]), "X is sparse. Sparse input is not supported."),
(kwargs["sample_weight"] is None, "Sample weights are not supported."),
(kwargs["class_weight"] is None, "Class weights are not supported."),
(
Expand Down
6 changes: 3 additions & 3 deletions daal4py/sklearn/manifold/_t_sne.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from time import time

import numpy as np
from scipy.sparse import issparse
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE as BaseTSNE
from sklearn.manifold._t_sne import _joint_probabilities, _joint_probabilities_nn
Expand All @@ -32,6 +31,7 @@
from daal4py.sklearn._utils import (
PatchingConditionsChain,
daal_check_version,
is_sparse,
sklearn_check_version,
)

Expand Down Expand Up @@ -149,7 +149,7 @@ def _fit(self, X, skip_num_points=0):
),
(
not (
isinstance(self.init, str) and self.init == "pca" and issparse(X)
isinstance(self.init, str) and self.init == "pca" and is_sparse(X)
),
"PCA initialization is not supported with sparse input matrices.",
),
Expand Down Expand Up @@ -273,7 +273,7 @@ def _fit(self, X, skip_num_points=0):
"should contain positive distances.",
)

if self.method == "exact" and issparse(X):
if self.method == "exact" and is_sparse(X):
raise TypeError(
'TSNE with method="exact" does not accept sparse '
'precomputed distance matrix. Use method="barnes_hut" '
Expand Down
7 changes: 4 additions & 3 deletions onedal/svm/svm.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import numpy as np
from scipy import sparse as sp

from daal4py.sklearn._utils import is_sparse
from onedal._device_offload import supports_queue
from onedal.common._backend import bind_default_backend
from onedal.utils import _sycl_queue_manager as QM
Expand Down Expand Up @@ -155,7 +156,7 @@ def _fit(self, X, y, sample_weight):
data = (X, y, sample_weight)
else:
data = (X, y)
self._sparse = sp.issparse(X)
self._sparse = is_sparse(X)

if self.kernel == "linear":
self._scale_, self._sigma_ = 1.0, 1.0
Expand Down Expand Up @@ -251,7 +252,7 @@ def _predict(self, X):
if self._sparse:
X.sort_indices()

if sp.issparse(X) and not self._sparse and not callable(self.kernel):
if is_sparse(X) and not self._sparse and not callable(self.kernel):
raise ValueError(
"cannot use sparse input in %r trained on dense data"
% type(self).__name__
Expand Down Expand Up @@ -299,7 +300,7 @@ def _decision_function(self, X):
if self._sparse:
X.sort_indices()

if sp.issparse(X) and not self._sparse and not callable(self.kernel):
if is_sparse(X) and not self._sparse and not callable(self.kernel):
raise ValueError(
"cannot use sparse input in %r trained on dense data"
% type(self).__name__
Expand Down
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pytest==7.4.4 ; python_version <= '3.10'
pytest==9.0.1 ; python_version >= '3.11'
pytest-json-report==1.5.0
pytest-cov==7.0.0
pytest-mock==3.15.1
numpy>=1.19.5 ; python_version <= '3.9'
numpy>=1.21.6 ; python_version == '3.10'
numpy>=1.23.5 ; python_version == '3.11'
Expand Down
7 changes: 3 additions & 4 deletions sklearnex/basic_statistics/basic_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@

import warnings

from scipy.sparse import issparse
from sklearn.base import BaseEstimator

from daal4py.sklearn._n_jobs_support import control_n_jobs
from daal4py.sklearn._utils import daal_check_version, sklearn_check_version
from daal4py.sklearn._utils import daal_check_version, is_sparse, sklearn_check_version
from onedal.basic_statistics import BasicStatistics as onedal_BasicStatistics
from onedal.utils.validation import _is_csr

Expand Down Expand Up @@ -160,11 +159,11 @@ def _onedal_gpu_supported(self, method_name, *data):
)
X, sample_weight = data

is_data_supported = not issparse(X) or (
is_data_supported = not is_sparse(X) or (
_is_csr(X) and daal_check_version((2025, "P", 200))
)

is_sample_weight_supported = sample_weight is None or not issparse(X)
is_sample_weight_supported = sample_weight is None or not is_sparse(X)

patching_status.and_conditions(
[
Expand Down
5 changes: 2 additions & 3 deletions sklearnex/cluster/dbscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
# limitations under the License.
# ===============================================================================

from scipy import sparse as sp
from sklearn.cluster import DBSCAN as _sklearn_DBSCAN

from daal4py.sklearn._n_jobs_support import control_n_jobs
from daal4py.sklearn._utils import sklearn_check_version
from daal4py.sklearn._utils import is_sparse, sklearn_check_version
from onedal.cluster import DBSCAN as onedal_DBSCAN
from onedal.utils._array_api import _is_numpy_namespace

Expand Down Expand Up @@ -132,7 +131,7 @@ def _onedal_supported(self, method_name, *data):
f"'{self.metric}' (p={self.p}) metric is not supported. "
"Only 'euclidean' or 'minkowski' with p=2 metrics are supported.",
),
(not sp.issparse(X), "X is sparse. Sparse input is not supported."),
(not is_sparse(X), "X is sparse. Sparse input is not supported."),
]
)
return patching_status
Expand Down
7 changes: 3 additions & 4 deletions sklearnex/cluster/k_means.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import warnings

import numpy as np
from scipy.sparse import issparse
from sklearn.cluster import KMeans as _sklearn_KMeans
from sklearn.utils._openmp_helpers import _openmp_effective_n_threads
from sklearn.utils.validation import (
Expand All @@ -34,7 +33,7 @@
)

from daal4py.sklearn._n_jobs_support import control_n_jobs
from daal4py.sklearn._utils import sklearn_check_version
from daal4py.sklearn._utils import is_sparse, sklearn_check_version
from onedal._device_offload import support_input_format
from onedal.cluster import KMeans as onedal_KMeans
from onedal.utils.validation import _is_csr
Expand Down Expand Up @@ -111,7 +110,7 @@ def _onedal_fit_supported(self, method_name, X, y=None, sample_weight=None):

is_data_supported = (
_is_csr(X) and daal_check_version((2024, "P", 700))
) or not issparse(X)
) or not is_sparse(X)

_acceptable_sample_weights = self._validate_sample_weight(sample_weight, X)

Expand Down Expand Up @@ -208,7 +207,7 @@ def _onedal_predict_supported(self, method_name, *data):

is_data_supported = (
_is_csr(X) and daal_check_version((2024, "P", 700))
) or not issparse(X)
) or not is_sparse(X)

# algorithm "auto" has been deprecated since 1.1,
# algorithm "full" has been replaced by "lloyd"
Expand Down
5 changes: 2 additions & 3 deletions sklearnex/decomposition/pca.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@

import logging

from daal4py.sklearn._utils import daal_check_version
from daal4py.sklearn._utils import daal_check_version, is_sparse

if daal_check_version((2024, "P", 100)):
from math import sqrt
from numbers import Integral
from warnings import warn

import numpy as np
from scipy.sparse import issparse
from sklearn.decomposition._pca import _infer_dimension
from sklearn.utils.extmath import stable_cumsum
from sklearn.utils.validation import check_is_fitted
Expand Down Expand Up @@ -172,7 +171,7 @@ def _onedal_supported(self, method_name, *data):
"solvers are supported."
),
),
(not issparse(X), "oneDAL PCA does not support sparse data"),
(not is_sparse(X), "oneDAL PCA does not support sparse data"),
]
)
return patching_status
Expand Down
17 changes: 8 additions & 9 deletions sklearnex/dummy/_dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
comments guiding code development should be removed if reused unless
pertinent to the derivative implementation."""
import numpy as np
import scipy.sparse as sp
from sklearn.dummy import DummyRegressor as _sklearn_DummyRegressor
from sklearn.utils.validation import check_is_fitted

from daal4py.sklearn._n_jobs_support import control_n_jobs
from daal4py.sklearn._utils import daal_check_version, sklearn_check_version
from daal4py.sklearn._utils import daal_check_version, is_sparse, sklearn_check_version
from onedal._device_offload import support_input_format
from onedal.dummy import DummyEstimator as onedal_DummyEstimator

Expand Down Expand Up @@ -463,9 +462,9 @@ def _onedal_cpu_supported(self, method_name, *data):
# of the oneDAL implementation to the aspects of the sklearn
# estimator. For example, oneDAL may not support sparse inputs
# where sklearn might, that would need to be checked with
# scipy.sparse.issparse(X). In general the conditions will
# correspond to information in the metadata and/or the estimator
# parameters.
# 'is_sparse(X)' (which is broader that SciPy's 'sparse.issparse')'.
# In general the conditions will correspond to information in the
# metadata and/or the estimator parameters.
#
# In no circumstance should ``validate_data`` be called here or
# in _onedal_gpu_supoorted to get the data into the proper form.
Expand All @@ -480,7 +479,7 @@ def _onedal_cpu_supported(self, method_name, *data):
patching_status.and_conditions(
[
(
not sp.issparse(X),
not is_sparse(X),
"sparse data is not supported",
),
(
Expand Down Expand Up @@ -514,7 +513,7 @@ def _onedal_cpu_supported(self, method_name, *data):
[
(hasattr(self, "_onedal_estimator"), "oneDAL model was not trained."),
(
not sp.issparse(X),
not is_sparse(X),
"sparse data is not supported",
),
]
Expand All @@ -538,7 +537,7 @@ def _onedal_gpu_supported(self, method_name, *data):
patching_status.and_conditions(
[
(
not sp.issparse(X),
not is_sparse(X),
"sparse data is not supported",
),
(
Expand All @@ -564,7 +563,7 @@ def _onedal_gpu_supported(self, method_name, *data):
[
(hasattr(self, "_onedal_estimator"), "oneDAL model was not trained."),
(
not sp.issparse(X),
not is_sparse(X),
"sparse data is not supported",
),
]
Expand Down
Loading
Loading