Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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