diff --git a/.ci/pipeline/build-and-test-lnx.yml b/.ci/pipeline/build-and-test-lnx.yml index bfc91ffc0f..9d8a904b9f 100644 --- a/.ci/pipeline/build-and-test-lnx.yml +++ b/.ci/pipeline/build-and-test-lnx.yml @@ -47,6 +47,7 @@ steps: bash .ci/scripts/setup_sklearn.sh $(SKLEARN_VERSION) pip install --upgrade -r requirements-test.txt -r requirements-test-optional.txt pip install $(python .ci/scripts/get_compatible_scipy_version.py) + if [ $(echo $(PYTHON_VERSION) | grep '3.8\|3.9\|3.10') ]; then conda install -q -y -c intel dpnp; fi pip list displayName: 'Install testing requirements' - script: | diff --git a/examples/sklearnex/knn_bf_classification_dpnp_batch.py b/examples/sklearnex/knn_bf_classification_dpnp_batch.py new file mode 100644 index 0000000000..4c8a976400 --- /dev/null +++ b/examples/sklearnex/knn_bf_classification_dpnp_batch.py @@ -0,0 +1,58 @@ +# =============================================================================== +# Copyright 2023 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# =============================================================================== + +# sklearnex kNN example for GPU offloading with DPNP ndarray: +# python ./knn_bf_classification_dpnp_batch.py.py + +import dpctl +import dpnp +import numpy as np +from sklearn.datasets import make_classification +from sklearn.metrics import accuracy_score +from sklearn.model_selection import train_test_split + +from sklearnex.neighbors import KNeighborsClassifier + +X, y = make_classification( + n_samples=1000, + n_features=4, + n_informative=2, + n_redundant=0, + random_state=0, + shuffle=False, +) + +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) + +# Make sure that all DPNP ndarrays using the same device. +q = dpctl.SyclQueue("gpu") # GPU + +dpnp_X_train = dpnp.asarray(X_train, usm_type="device", sycl_queue=q) +dpnp_y_train = dpnp.asarray(y_train, usm_type="device", sycl_queue=q) +dpnp_X_test = dpnp.asarray(X_test, usm_type="device", sycl_queue=q) + +knn_mdl = KNeighborsClassifier( + algorithm="brute", n_neighbors=20, weights="uniform", p=2, metric="minkowski" +) +knn_mdl.fit(dpnp_X_train, dpnp_y_train) + +y_predict = knn_mdl.predict(dpnp_X_test) + +print("Brute Force Distributed kNN classification results:") +print("Ground truth (first 5 observations):\n{}".format(y_test[:5])) +print("Classification results (first 5 observations):\n{}".format(y_predict[:5])) +print("Accuracy (2 classes): {}\n".format(accuracy_score(y_test, y_predict.asnumpy()))) +print("Are predicted results on GPU: {}".format(y_predict.sycl_device.is_gpu)) diff --git a/examples/sklearnex/random_forest_classifier_dpctl_batch.py b/examples/sklearnex/random_forest_classifier_dpctl_batch.py new file mode 100644 index 0000000000..0a5e0e8e09 --- /dev/null +++ b/examples/sklearnex/random_forest_classifier_dpctl_batch.py @@ -0,0 +1,53 @@ +# =============================================================================== +# Copyright 2023 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# =============================================================================== + +# sklearnex RF example for GPU offloading with DPCtl tensor: +# python ./random_forest_classifier_dpctl_batch.py + +import dpctl +import dpctl.tensor as dpt +import numpy as np +from sklearn.datasets import make_classification +from sklearn.model_selection import train_test_split + +from sklearnex.preview.ensemble import RandomForestClassifier + +# Make sure that all DPCtl tensors using the same device. +q = dpctl.SyclQueue("gpu") # GPU + +X, y = make_classification( + n_samples=1000, + n_features=4, + n_informative=2, + n_redundant=0, + random_state=0, + shuffle=False, +) + +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) + +dpt_X_train = dpt.asarray(X_train, usm_type="device", sycl_queue=q) +dpt_y_train = dpt.asarray(y_train, usm_type="device", sycl_queue=q) +dpt_X_test = dpt.asarray(X_test, usm_type="device", sycl_queue=q) + +rf = RandomForestClassifier(max_depth=2, random_state=0).fit(dpt_X_train, dpt_y_train) + +pred = rf.predict(dpt_X_test) + +print("Random Forest classification results:") +print("Ground truth (first 5 observations):\n{}".format(y_test[:5])) +print("Classification results (first 5 observations):\n{}".format(pred[:5])) +print("Are predicted results on GPU: {}".format(pred.sycl_device.is_gpu)) diff --git a/examples/sklearnex/random_forest_regressor_dpnp_batch.py b/examples/sklearnex/random_forest_regressor_dpnp_batch.py new file mode 100644 index 0000000000..d741bdaf57 --- /dev/null +++ b/examples/sklearnex/random_forest_regressor_dpnp_batch.py @@ -0,0 +1,46 @@ +# =============================================================================== +# Copyright 2023 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# =============================================================================== + +# sklearnex RF example for GPU offloading with DPNP ndarray: +# python ./random_forest_regressor_dpnp_batch.py.py + +import dpnp +import numpy as np +from sklearn.datasets import make_regression +from sklearn.model_selection import train_test_split + +from sklearnex.preview.ensemble import RandomForestRegressor + +sycl_device = "gpu:0" + +X, y = make_regression( + n_samples=1000, n_features=4, n_informative=2, random_state=0, shuffle=False +) + +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) + +dpnp_X_train = dpnp.asarray(X_train, device=sycl_device) +dpnp_y_train = dpnp.asarray(y_train, device=sycl_device) +dpnp_X_test = dpnp.asarray(X_test, device=sycl_device) + +rf = RandomForestRegressor(max_depth=2, random_state=0).fit(dpnp_X_train, dpnp_y_train) + +pred = rf.predict(dpnp_X_test) + +print("Random Forest regression results:") +print("Ground truth (first 5 observations):\n{}".format(y_test[:5])) +print("Regression results (first 5 observations):\n{}".format(pred[:5])) +print("Are predicted results on GPU: {}".format(pred.sycl_device.is_gpu)) diff --git a/sklearnex/_device_offload.py b/sklearnex/_device_offload.py index f0177e4cd3..e2d3693361 100644 --- a/sklearnex/_device_offload.py +++ b/sklearnex/_device_offload.py @@ -20,9 +20,6 @@ import numpy as np -from ._config import get_config -from ._utils import get_patch_message - try: from dpctl import SyclQueue from dpctl.memory import MemoryUSMDevice, as_usm_memory @@ -32,6 +29,16 @@ except ImportError: dpctl_available = False +try: + import dpnp + + dpnp_available = True +except ImportError: + dpnp_available = False + +from ._config import get_config +from ._utils import get_patch_message + oneapi_is_available = "daal4py.oneapi" in sys.modules if oneapi_is_available: from daal4py.oneapi import _get_device_name_sycl_ctxt, _get_sycl_ctxt_params @@ -197,7 +204,9 @@ def wrapper(self, *args, **kwargs): usm_iface = getattr(data[0], "__sycl_usm_array_interface__", None) result = func(self, *args, **kwargs) if usm_iface is not None: - return _copy_to_usm(usm_iface["syclobj"], result) + result = _copy_to_usm(usm_iface["syclobj"], result) + if dpnp_available and isinstance(data[0], dpnp.ndarray): + result = dpnp.array(result, copy=False) return result return wrapper diff --git a/tests/run_examples.py b/tests/run_examples.py index 7f74deb23f..7af4eed9a3 100755 --- a/tests/run_examples.py +++ b/tests/run_examples.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright 2014 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,71 +12,72 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -#=============================================================================== +# =============================================================================== import os import struct import subprocess import sys +from collections import defaultdict +from os.path import join as jp +from time import gmtime, strftime from daal4py import __has_dist__ from daal4py.sklearn._utils import get_daal_version -from os.path import join as jp -from time import gmtime, strftime -from collections import defaultdict -print('Starting examples validation') +print("Starting examples validation") # First item is major version - 2021, # second is minor+patch - 0110, # third item is status - B -print('DAAL version:', get_daal_version()) +print("DAAL version:", get_daal_version()) runner_path = os.path.realpath(__file__) runner_dir = os.path.dirname(runner_path) examples_rootdir = jp( - os.path.dirname(os.path.abspath(os.path.join(runner_path, - os.pardir))), - 'examples') + os.path.dirname(os.path.abspath(os.path.join(runner_path, os.pardir))), "examples" +) IS_WIN = False IS_MAC = False IS_LIN = False system_os = "not_supported" -if 'linux' in sys.platform: +if "linux" in sys.platform: IS_LIN = True system_os = "lnx" -elif sys.platform == 'darwin': +elif sys.platform == "darwin": IS_MAC = True system_os = "mac" -elif sys.platform in ['win32', 'cygwin']: +elif sys.platform in ["win32", "cygwin"]: IS_WIN = True system_os = "win" else: - assert False, sys.platform + ' not supported' + assert False, sys.platform + " not supported" -assert 8 * struct.calcsize('P') in [32, 64] +assert 8 * struct.calcsize("P") in [32, 64] -if 8 * struct.calcsize('P') == 32: - logdir = jp(runner_dir, '_results', 'ia32') +if 8 * struct.calcsize("P") == 32: + logdir = jp(runner_dir, "_results", "ia32") else: - logdir = jp(runner_dir, '_results', 'intel64') + logdir = jp(runner_dir, "_results", "intel64") ex_log_dirs = [ - (jp(examples_rootdir, 'daal4py'), jp(logdir, 'daal4py')), - (jp(examples_rootdir, 'sklearnex'), jp(logdir, 'sklearnex'))] + (jp(examples_rootdir, "daal4py"), jp(logdir, "daal4py")), + (jp(examples_rootdir, "sklearnex"), jp(logdir, "sklearnex")), +] availabe_devices = [] try: from daal4py.oneapi import sycl_context + sycl_extention_available = True except ModuleNotFoundError: sycl_extention_available = False -print('Sycl extensions available: {}'.format(sycl_extention_available)) +print("Sycl extensions available: {}".format(sycl_extention_available)) if sycl_extention_available: try: - with sycl_context('gpu'): + with sycl_context("gpu"): gpu_available = True availabe_devices.append("gpu") except RuntimeError: @@ -84,7 +85,7 @@ availabe_devices.append("cpu") # validate that host and cpu devices avaialbe for logging reasons. Examples and # vaidaton logic assumes that host and cpu devices are always available - print('Sycl gpu device: {}'.format(gpu_available)) + print("Sycl gpu device: {}".format(gpu_available)) def check_version(rule, target): @@ -118,56 +119,72 @@ def check_library(rule): for rule_item in rule: try: import importlib + importlib.import_module(rule_item, package=None) except ImportError: return False return True -req_version = defaultdict(lambda: (2019, 'P', 0)) -req_version['sycl/dbscan_batch.py'] = \ - (2021, 'P', 100) # hangs in beta08, need to be fixed -req_version['sycl/linear_regression_batch.py'] = \ - (2021, 'P', 100) # hangs in beta08, need to be fixed -req_version['sycl/kmeans_batch.py'] = \ - (2021, 'P', 200) # not equal results for host and gpu runs -req_version['sycl/pca_transform_batch.py'] = (2021, 'P', 200) -req_version['sycl/decision_forest_classification_hist_batch.py'] = (2021, 'P', 200) -req_version['sycl/decision_forest_regression_hist_batch.py'] = (2021, 'P', 200) -req_version['decision_forest_classification_hist_batch.py'] = (2023, 'P', 1) -req_version['decision_forest_classification_default_dense_batch.py'] = (2023, 'P', 1) -req_version['decision_forest_classification_traverse_batch.py'] = (2023, 'P', 1) -req_version['decision_forest_regression_hist_batch.py'] = (2021, 'P', 200) -req_version['basic_statistics_spmd.py'] = (2023, 'P', 1) -req_version['kmeans_spmd.py'] = (2023, 'P', 2) -req_version['knn_bf_classification_spmd.py'] = (2023, 'P', 1) -req_version['knn_bf_regression_spmd.py'] = (2023, 'P', 1) -req_version['linear_regression_spmd.py'] = (2023, 'P', 1) +req_version = defaultdict(lambda: (2019, "P", 0)) +req_version["sycl/dbscan_batch.py"] = ( + 2021, + "P", + 100, +) # hangs in beta08, need to be fixed +req_version["sycl/linear_regression_batch.py"] = ( + 2021, + "P", + 100, +) # hangs in beta08, need to be fixed +req_version["sycl/kmeans_batch.py"] = ( + 2021, + "P", + 200, +) # not equal results for host and gpu runs +req_version["sycl/pca_transform_batch.py"] = (2021, "P", 200) +req_version["sycl/decision_forest_classification_hist_batch.py"] = (2021, "P", 200) +req_version["sycl/decision_forest_regression_hist_batch.py"] = (2021, "P", 200) +req_version["decision_forest_classification_hist_batch.py"] = (2023, "P", 1) +req_version["decision_forest_classification_default_dense_batch.py"] = (2023, "P", 1) +req_version["decision_forest_classification_traverse_batch.py"] = (2023, "P", 1) +req_version["decision_forest_regression_hist_batch.py"] = (2021, "P", 200) +req_version["basic_statistics_spmd.py"] = (2023, "P", 1) +req_version["kmeans_spmd.py"] = (2023, "P", 2) +req_version["knn_bf_classification_spmd.py"] = (2023, "P", 1) +req_version["knn_bf_regression_spmd.py"] = (2023, "P", 1) +req_version["linear_regression_spmd.py"] = (2023, "P", 1) req_device = defaultdict(lambda: []) -req_device['basic_statistics_spmd.py'] = ["gpu"] -req_device['kmeans_spmd.py'] = ["gpu"] -req_device['knn_bf_classification_spmd.py'] = ["gpu"] -req_device['knn_bf_regression_spmd.py'] = ["gpu"] -req_device['linear_regression_spmd.py'] = ["gpu"] -req_device['pca_spmd.py'] = ["gpu"] -req_device['random_forest_classifier_spmd.py'] = ["gpu"] -req_device['random_forest_regressor_spmd.py'] = ["gpu"] -req_device['sycl/gradient_boosted_regression_batch.py'] = ["gpu"] +req_device["basic_statistics_spmd.py"] = ["gpu"] +req_device["kmeans_spmd.py"] = ["gpu"] +req_device["knn_bf_classification_dpnp_batch.py"] = ["gpu"] +req_device["knn_bf_classification_spmd.py"] = ["gpu"] +req_device["knn_bf_regression_spmd.py"] = ["gpu"] +req_device["linear_regression_spmd.py"] = ["gpu"] +req_device["pca_spmd.py"] = ["gpu"] +req_device["random_forest_classifier_dpctl_batch.py"] = ["gpu"] +req_device["random_forest_classifier_spmd.py"] = ["gpu"] +req_device["random_forest_regressor_dpnp_batch.py"] = ["gpu"] +req_device["random_forest_regressor_spmd.py"] = ["gpu"] +req_device["sycl/gradient_boosted_regression_batch.py"] = ["gpu"] req_library = defaultdict(lambda: []) -req_library['basic_statistics_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['model_builders_lightgbm.py'] = ['lightgbm'] -req_library['model_builders_xgboost.py'] = ['xgboost'] -req_library['model_builders_catboost.py'] = ['catboost'] -req_library['basic_statistics_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['kmeans_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['knn_bf_classification_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['knn_bf_regression_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['linear_regression_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['pca_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['random_forest_classifier_spmd.py'] = ['dpctl', 'mpi4py'] -req_library['random_forest_regressor_spmd.py'] = ['dpctl', 'mpi4py'] +req_library["basic_statistics_spmd.py"] = ["dpctl", "mpi4py"] +req_library["model_builders_lightgbm.py"] = ["lightgbm"] +req_library["model_builders_xgboost.py"] = ["xgboost"] +req_library["model_builders_catboost.py"] = ["catboost"] +req_library["basic_statistics_spmd.py"] = ["dpctl", "mpi4py"] +req_library["kmeans_spmd.py"] = ["dpctl", "mpi4py"] +req_library["knn_bf_classification_dpnp_batch.py"] = ["dpctl", "dpnp"] +req_library["knn_bf_classification_spmd.py"] = ["dpctl", "mpi4py"] +req_library["knn_bf_regression_spmd.py"] = ["dpctl", "mpi4py"] +req_library["linear_regression_spmd.py"] = ["dpctl", "mpi4py"] +req_library["pca_spmd.py"] = ["dpctl", "mpi4py"] +req_library["random_forest_classifier_dpctl_batch.py"] = ["dpctl"] +req_library["random_forest_classifier_spmd.py"] = ["dpctl", "mpi4py"] +req_library["random_forest_regressor_dpnp_batch.py"] = ["dpnp"] +req_library["random_forest_regressor_spmd.py"] = ["dpctl", "mpi4py"] req_os = defaultdict(lambda: []) @@ -176,11 +193,11 @@ def get_exe_cmd(ex, nodist, nostream): if os.path.dirname(ex).endswith("sycl"): if not sycl_extention_available: return None - if not check_version(req_version["sycl/" + os.path.basename(ex)], - get_daal_version()): + if not check_version( + req_version["sycl/" + os.path.basename(ex)], get_daal_version() + ): return None - if not check_device( - req_device["sycl/" + os.path.basename(ex)], availabe_devices): + if not check_device(req_device["sycl/" + os.path.basename(ex)], availabe_devices): return None if not check_os(req_os["sycl/" + os.path.basename(ex)], system_os): return None @@ -190,19 +207,19 @@ def get_exe_cmd(ex, nodist, nostream): return None if not check_library(req_library[os.path.basename(ex)]): return None - if os.path.dirname(ex).endswith("sklearnex") and not nodist and \ - ex.endswith('spmd.py'): + + if os.path.dirname(ex).endswith("sklearnex"): if not check_device(req_device[os.path.basename(ex)], availabe_devices): return None if not check_version(req_version[os.path.basename(ex)], get_daal_version()): return None if not check_library(req_library[os.path.basename(ex)]): return None - if any(ex.endswith(x) for x in ['batch.py', 'stream.py']): + if any(ex.endswith(x) for x in ["batch.py", "stream.py"]): return '"' + sys.executable + '" "' + ex + '"' - if not nostream and ex.endswith('streaming.py'): + if not nostream and ex.endswith("streaming.py"): return '"' + sys.executable + '" "' + ex + '"' - if not nodist and ex.endswith('spmd.py'): + if not nodist and ex.endswith("spmd.py"): if IS_WIN: return 'mpiexec -localonly -n 4 "' + sys.executable + '" "' + ex + '"' return 'mpirun -n 4 "' + sys.executable + '" "' + ex + '"' @@ -214,44 +231,44 @@ def run(exdir, logdir, nodist=False, nostream=False): n = 0 if not os.path.exists(logdir): os.makedirs(logdir) - for (dirpath, dirnames, filenames) in os.walk(exdir): + for dirpath, dirnames, filenames in os.walk(exdir): for script in filenames: - if any(script.endswith(x) for x in ['spmd.py', - 'streaming.py', - 'stream.py', - 'batch.py']): + if any( + script.endswith(x) + for x in ["spmd.py", "streaming.py", "stream.py", "batch.py"] + ): n += 1 - logfn = jp(logdir, script.replace('.py', '.res')) - with open(logfn, 'w') as logfile: - print('\n##### ' + jp(dirpath, script)) - execute_string = get_exe_cmd(jp(dirpath, script), - nodist, nostream) + logfn = jp(logdir, script.replace(".py", ".res")) + with open(logfn, "w") as logfile: + print("\n##### " + jp(dirpath, script)) + execute_string = get_exe_cmd(jp(dirpath, script), nodist, nostream) if execute_string: os.chdir(dirpath) proc = subprocess.Popen( - execute_string if IS_WIN else ['/bin/bash', - '-c', - execute_string], + execute_string + if IS_WIN + else ["/bin/bash", "-c", execute_string], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - shell=False + shell=False, ) out = proc.communicate()[0] - logfile.write(out.decode('ascii')) + logfile.write(out.decode("ascii")) if proc.returncode: print(out) print( - strftime("%H:%M:%S", gmtime()) + '\tFAILED' - '\t' + script + '\twith errno' - '\t' + str(proc.returncode) + strftime("%H:%M:%S", gmtime()) + "\tFAILED" + "\t" + script + "\twith errno" + "\t" + str(proc.returncode) ) else: success += 1 - print(strftime("%H:%M:%S", gmtime()) + '\t' - 'PASSED\t' + script) + print( + strftime("%H:%M:%S", gmtime()) + "\t" "PASSED\t" + script + ) else: success += 1 - print(strftime("%H:%M:%S", gmtime()) + '\tSKIPPED\t' + script) + print(strftime("%H:%M:%S", gmtime()) + "\tSKIPPED\t" + script) return success, n @@ -263,13 +280,15 @@ def run_all(nodist=False, nostream=False): success += s num += n if success != num: - print('{}/{} examples passed/skipped, ' - '{} failed'.format(success, num, num - success)) - print('Error(s) occured. Logs can be found in ' + logdir) + print( + "{}/{} examples passed/skipped, " + "{} failed".format(success, num, num - success) + ) + print("Error(s) occured. Logs can be found in " + logdir) return 4711 - print('{}/{} examples passed/skipped'.format(success, num)) + print("{}/{} examples passed/skipped".format(success, num)) return 0 -if __name__ == '__main__': - sys.exit(run_all('nodist' in sys.argv or not __has_dist__, 'nostream' in sys.argv)) +if __name__ == "__main__": + sys.exit(run_all("nodist" in sys.argv or not __has_dist__, "nostream" in sys.argv)) diff --git a/tests/test_examples_sklearnex.py b/tests/test_examples_sklearnex.py index 2b7e8e4f54..92e752a29f 100644 --- a/tests/test_examples_sklearnex.py +++ b/tests/test_examples_sklearnex.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright 2023 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,27 +12,29 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -#=============================================================================== +# =============================================================================== import os import subprocess import unittest + from daal4py.sklearn._utils import get_daal_version + test_path = os.path.abspath(os.path.dirname(__file__)) unittest_data_path = os.path.join(test_path, "unittest_data") -examples_path = os.path.join( - os.path.dirname(test_path), "examples", "sklearnex") +examples_path = os.path.join(os.path.dirname(test_path), "examples", "sklearnex") -print('Testing examples_sklearnex') +print("Testing examples_sklearnex") # First item is major version - 2021, # second is minor+patch - 0110, # third item is status - B sklearnex_version = get_daal_version() -print('oneDAL version:', sklearnex_version) +print("oneDAL version:", sklearnex_version) class TestsklearnexExamples(unittest.TestCase): - '''Class for testing sklernex examples''' + """Class for testing sklernex examples""" + # Get a list of all Python files in the examples directory pass @@ -41,22 +43,28 @@ def test_generator(file): def testit(self): # Run the script and capture its exit code process = subprocess.run( - ['python', os.path.join(examples_path, file)], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, - check=True) # nosec + ["python", os.path.join(examples_path, file)], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=True, + ) # nosec exit_code = process.returncode # Assert that the exit code is 0 self.assertEqual(exit_code, 0) - setattr(TestsklearnexExamples, 'test_' + os.path.splitext(file)[0], testit) + setattr(TestsklearnexExamples, "test_" + os.path.splitext(file)[0], testit) print("Generating tests for " + os.path.splitext(file)[0]) -files = [f for f in os.listdir(examples_path) if f.endswith(".py") and 'spmd' not in f] +files = [ + f + for f in os.listdir(examples_path) + if f.endswith(".py") and "spmd" not in f and "batch" not in f +] for file in files: test_generator(file) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main()