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
4 changes: 2 additions & 2 deletions configs/BENCH-CONFIG-SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Configs have the three highest parameter keys:
| `data`:`distributed_split` | None | None, `rank_based` | Split type used to distribute data between machines in distributed algorithm. `None` type means usage of all data without split on all machines. `rank_based` type splits the data equally between machines with split sequence based on rank id from MPI. |
|<h3>Algorithm parameters</h3>||||
| `algorithm`:`library` | None | | Python module containing measured entity (class or function). |
| `algorithm`:`device` | `default` | `default`, `cpu`, `gpu` | Device selected for computation. |
| `algorithm`:`device` | `default` | `default`, `cpu`, `gpu` | Device selected for computation. `sklearnex`+`gpu` cases enable sklearn's `array_api_dispatch` and use `dpnp` data by default (see `sklearn_context` below). |

## Benchmark-Specific Parameters

Expand All @@ -109,7 +109,7 @@ Configs have the three highest parameter keys:
| `algorithm`:`estimator` | None | | Name of measured estimator. |
| `algorithm`:`estimator_params` | Empty `dict` | | Parameters for estimator constructor. |
| `algorithm`:`batch_size`:`{stage}` | None | Any positive integer | Enables online mode for `{stage}` methods of estimator (sequential calls for each batch). |
| `algorithm`:`sklearn_context` | None | | Parameters for sklearn `config_context` used over estimator. |
| `algorithm`:`sklearn_context` | None | | Parameters for sklearn `config_context` used over estimator. `array_api_dispatch` requires `SCIPY_ARRAY_API=1`, which scikit-learn_bench sets by default if it is unset in the environment. |
| `algorithm`:`sklearnex_context` | None | | Parameters for sklearnex `config_context` used over estimator. Updated by `sklearn_context` if set. |
| `bench`:`ensure_sklearnex_patching` | True | | If True, warns about sklearnex patching failures. |

Expand Down
18 changes: 12 additions & 6 deletions configs/common/sklearn.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
{ "library": "sklearnex", "device": "cpu" }
]
},
"sklearn-ex[cpu,gpu] implementations": {
"algorithm": [
{ "library": "sklearn", "device": "cpu" },
{ "library": "sklearnex", "device": ["cpu", "gpu"] }
]
},
"sklearn-ex[cpu,gpu] implementations": [
{ "algorithm": { "library": "sklearn", "device": "cpu" } },
{ "algorithm": { "library": "sklearnex", "device": "cpu" } },
{
"algorithm": {
"library": "sklearnex",
"device": "gpu",
"sklearn_context": { "array_api_dispatch": true }
},
"data": { "format": "dpnp", "order": "C" }
}
],
"sklearnex spmd implementation": {
"algorithm": {
"library": "sklearnex.spmd",
Expand Down
3 changes: 3 additions & 0 deletions sklbench/benchmarks/sklearn_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
from importlib.metadata import PackageNotFoundError, version
from typing import Dict, List, Union

# sklbench uses array API by default; must precede scipy import to take effect
os.environ.setdefault("SCIPY_ARRAY_API", "1")

import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator
Expand Down
17 changes: 15 additions & 2 deletions sklbench/datasets/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from ..utils.logger import logger


def convert_data(data, dformat: str, order: str, dtype: str, device: str = None):
def convert_data(data, dformat: str, order: str, dtype: str, device: str = None, sycl_queue=None):
if isinstance(data, csr_matrix) and dformat != "csr_matrix":
data = data.toarray()
if dtype == "preserve":
Expand All @@ -46,6 +46,11 @@ def convert_data(data, dformat: str, order: str, dtype: str, device: str = None)
elif dformat == "dpnp":
import dpnp

# Pin every subset to one shared queue: sklearnex builds its internal
# arrays (e.g. the take() indices in KNN predict) on the device's default
# queue, and array_api_dispatch requires all arrays share one queue object.
if sycl_queue is not None:
return dpnp.asarray(data, dtype=dtype, order=order, sycl_queue=sycl_queue)
return dpnp.array(data, dtype=dtype, order=order, device=device)
elif dformat == "dpctl":
warnings.warn(
Expand Down Expand Up @@ -143,6 +148,14 @@ def split_and_transform_data(bench_case, data, data_description):

device = get_bench_case_value(bench_case, "algorithm:device", None)
common_data_format = get_bench_case_value(bench_case, "data:format", "pandas")

# Resolve one queue for the device up front so all dpnp subsets share it;
# dpnp.array(device=...) per subset can otherwise land on distinct queues.
sycl_queue = None
if common_data_format == "dpnp" and device is not None:
import dpnp

sycl_queue = dpnp.array([], device=device).sycl_queue
common_data_order = get_bench_case_value(bench_case, "data:order", "F")
common_data_dtype = get_bench_case_value(bench_case, "data:dtype", "float32")

Expand Down Expand Up @@ -177,7 +190,7 @@ def split_and_transform_data(bench_case, data, data_description):
data_dtype = required_label_dtype

converted_data = convert_data(
subset_content, data_format, data_order, data_dtype, device
subset_content, data_format, data_order, data_dtype, device, sycl_queue
)
data_dict[subset_name] = converted_data
if not is_label:
Expand Down
Loading