diff --git a/.github/workflows/run_benchmark_results_file_sanity_checks.yaml b/.github/workflows/run_benchmark_results_file_sanity_checks.yaml index d427868..a93e386 100644 --- a/.github/workflows/run_benchmark_results_file_sanity_checks.yaml +++ b/.github/workflows/run_benchmark_results_file_sanity_checks.yaml @@ -19,3 +19,4 @@ jobs: run: | python ./benchmarks/kmeans/consolidate_result_csv.py ./benchmarks/kmeans/results.csv --check-csv python ./benchmarks/pca/consolidate_result_csv.py ./benchmarks/pca/results.csv --check-csv + python ./benchmarks/ridge/consolidate_result_csv.py ./benchmarks/ridge/results.csv --check-csv diff --git a/.github/workflows/sync_benchmark_files_to_gsheet.yaml b/.github/workflows/sync_benchmark_files_to_gsheet.yaml index cbd2f25..c99700b 100644 --- a/.github/workflows/sync_benchmark_files_to_gsheet.yaml +++ b/.github/workflows/sync_benchmark_files_to_gsheet.yaml @@ -24,8 +24,11 @@ jobs: run: | python ./benchmarks/kmeans/consolidate_result_csv.py ./benchmarks/kmeans/results.csv --check-csv python ./benchmarks/pca/consolidate_result_csv.py ./benchmarks/pca/results.csv --check-csv + python ./benchmarks/ridge/consolidate_result_csv.py ./benchmarks/ridge/results.csv --check-csv echo "$GSPREAD_SERVICE_ACCOUNT_AUTH_KEY" > service_account.json python ./benchmarks/kmeans/consolidate_result_csv.py ./benchmarks/kmeans/results.csv \ --sync-to-gspread --gspread-url $GSPREAD_URL --gspread-auth-key ./service_account.json python ./benchmarks/pca/consolidate_result_csv.py ./benchmarks/pca/results.csv \ --sync-to-gspread --gspread-url $GSPREAD_URL --gspread-auth-key ./service_account.json + python ./benchmarks/ridge/consolidate_result_csv.py ./benchmarks/ridge/results.csv \ + --sync-to-gspread --gspread-url $GSPREAD_URL --gspread-auth-key ./service_account.json diff --git a/.github/workflows/test_cpu_benchmarks.yaml b/.github/workflows/test_cpu_benchmarks.yaml index 57b0707..4bb5cc5 100644 --- a/.github/workflows/test_cpu_benchmarks.yaml +++ b/.github/workflows/test_cpu_benchmarks.yaml @@ -143,3 +143,5 @@ jobs: PYTHONPATH=$PYTHONPATH:$(realpath ../../kmeans_dpcpp/) benchopt run --no-plot -l -d Simulated_correlated_data[n_samples=1000,n_features=14] cd ../pca benchopt run --no-plot -l -d Simulated_correlated_data[n_samples=100,n_features=100] + cd ../ridge + benchopt run --no-plot -l -d Simulated_correlated_data[n_samples=100,n_features=100,n_targets=2] diff --git a/README.md b/README.md index 82f5e88..214f473 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ hardware. Benchmarks are currently available for the following algorithms: - [k-means](https://github.com/soda-inria/sklearn-engine-benchmarks/tree/main/benchmarks/kmeans) - [PCA](https://github.com/soda-inria/sklearn-engine-benchmarks/tree/main/benchmarks/pca) +- [Ridge](https://github.com/soda-inria/sklearn-engine-benchmarks/tree/main/benchmarks/pca) Here is a (non-exhaustive) list of libraries that are compared in the benchmarks: - [scikit-learn](https://scikit-learn.org/stable/index.html) diff --git a/benchmarks/kmeans/consolidate_result_csv.py b/benchmarks/kmeans/consolidate_result_csv.py index 00ef838..5656264 100644 --- a/benchmarks/kmeans/consolidate_result_csv.py +++ b/benchmarks/kmeans/consolidate_result_csv.py @@ -2,7 +2,6 @@ from functools import partial from io import BytesIO from itertools import zip_longest -from operator import attrgetter import numpy as np import pandas as pd @@ -393,17 +392,18 @@ def _gspread_sync(source, gspread_url, gspread_auth_key): worksheet.freeze(0, 0) worksheet.resize(rows=n_rows + 1, cols=n_cols) worksheet.clear_notes(global_range) - white_background = dict( - backgroundColorStyle=dict(rgbColor=dict(red=1, green=1, blue=1, alpha=1)) + reset_format = dict( + backgroundColorStyle=dict(rgbColor=dict(red=1, green=1, blue=1, alpha=1)), + textFormat=dict(bold=False), ) - worksheet.format(global_range, white_background) + worksheet.format(global_range, reset_format) except gspread.WorksheetNotFound: worksheet = sheet.add_worksheet( GOOGLE_WORKSHEET_NAME, rows=n_rows + 1, cols=n_cols ) # ensure worksheets are sorted anti-alphabetically sheet.reorder_worksheets( - sorted(sheet.worksheets(), key=attrgetter("title"), reverse=True) + sorted(sheet.worksheets(), key=lambda worksheet: worksheet.title.lower()) ) # upload all values diff --git a/benchmarks/pca/consolidate_result_csv.py b/benchmarks/pca/consolidate_result_csv.py index e4e1a3f..90835e3 100644 --- a/benchmarks/pca/consolidate_result_csv.py +++ b/benchmarks/pca/consolidate_result_csv.py @@ -2,7 +2,6 @@ from functools import partial from io import BytesIO from itertools import zip_longest -from operator import attrgetter import numpy as np import pandas as pd @@ -391,17 +390,18 @@ def _gspread_sync(source, gspread_url, gspread_auth_key): worksheet.freeze(0, 0) worksheet.resize(rows=n_rows + 1, cols=n_cols) worksheet.clear_notes(global_range) - white_background = dict( - backgroundColorStyle=dict(rgbColor=dict(red=1, green=1, blue=1, alpha=1)) + reset_format = dict( + backgroundColorStyle=dict(rgbColor=dict(red=1, green=1, blue=1, alpha=1)), + textFormat=dict(bold=False), ) - worksheet.format(global_range, white_background) + worksheet.format(global_range, reset_format) except gspread.WorksheetNotFound: worksheet = sheet.add_worksheet( GOOGLE_WORKSHEET_NAME, rows=n_rows + 1, cols=n_cols ) # ensure worksheets are sorted anti-alphabetically sheet.reorder_worksheets( - sorted(sheet.worksheets(), key=attrgetter("title"), reverse=True) + sorted(sheet.worksheets(), key=lambda worksheet: worksheet.title.lower()) ) # upload all values diff --git a/benchmarks/ridge/consolidate_result_csv.py b/benchmarks/ridge/consolidate_result_csv.py new file mode 100644 index 0000000..892cbfd --- /dev/null +++ b/benchmarks/ridge/consolidate_result_csv.py @@ -0,0 +1,643 @@ +import hashlib +from functools import partial +from io import BytesIO +from itertools import zip_longest + +import numpy as np +import pandas as pd +from pandas.io.parsers.readers import STR_NA_VALUES + +GOOGLE_WORKSHEET_NAME = "Ridge" + +DATES_FORMAT = "%Y-%m-%d" + +BENCHMARK_DEFINING_COLUMNS = [ + "objective_objective_param___name", + "objective_dataset_param___name", + "objective_dataset_param_n_samples", + "objective_dataset_param_n_features", + "objective_dataset_param_n_targets", + "objective_dataset_param_dtype", + "objective_dataset_param_random_state", + "objective_objective_param_alpha", + "objective_objective_param_fit_intercept", + "objective_objective_param_sample_weight", + "objective_objective_param_random_state", +] + +BENCHMARK_DEFINING_COLUMNS = sorted(BENCHMARK_DEFINING_COLUMNS) +_benchmark_defining_columns_identifier = "".join(sorted(BENCHMARK_DEFINING_COLUMNS)) + +BACKEND_PROVIDER = "Backend provider" +COMMENT = "Comment" +COMPUTE_DEVICE = "Compute device" +COMPUTE_RUNTIME = "Compute runtime" +DATA_RANDOM_STATE = "Data random state" +REGULARIZATION_STRENGTH = "Regularization strength" +DTYPE = "Dtype" +NB_DATA_FEATURES = "Nb data features" +NB_DATA_SAMPLES = "Nb data samples" +NB_DATA_TARGETS = "Nb data targets" +SOLVER = "Solver" +PLATFORM = "Platform" +PLATFORM_ARCHITECTURE = "Platform architecture" +PLATFORM_RELEASE = "Platform release" +SYSTEM_CPUS = "Nb cpus" +SYSTEM_PROCESSOR = "Cpu name" +SYSTEM_RAM = "RAM (GB)" +SYSTEM_GPU = "Gpu name" +RESULT_NB_ITERATIONS = "Result nb iterations" +OBJECTIVE_FUNCTION_VALUE = "Result objective value" +VERSION_INFO = "Version info" +RUN_DATE = "Run date" +SOLVER_RANDOM_STATE = "Solver random state" +WALLTIME = "Walltime" + +BENCHMARK_ID_NAME = "Benchmark id" + +TABLE_DISPLAY_ORDER = [ + BENCHMARK_ID_NAME, + DTYPE, + NB_DATA_SAMPLES, + NB_DATA_FEATURES, + NB_DATA_TARGETS, + REGULARIZATION_STRENGTH, + WALLTIME, + BACKEND_PROVIDER, + COMPUTE_DEVICE, + COMPUTE_RUNTIME, + SOLVER, + SYSTEM_CPUS, + SYSTEM_PROCESSOR, + SYSTEM_GPU, + SYSTEM_RAM, + PLATFORM, + PLATFORM_ARCHITECTURE, + PLATFORM_RELEASE, + RUN_DATE, + VERSION_INFO, + COMMENT, + RESULT_NB_ITERATIONS, + OBJECTIVE_FUNCTION_VALUE, + DATA_RANDOM_STATE, + SOLVER_RANDOM_STATE, +] + +COLUMNS_DTYPES = { + BENCHMARK_ID_NAME: str, + DTYPE: str, + NB_DATA_SAMPLES: np.int64, + NB_DATA_FEATURES: np.int64, + NB_DATA_TARGETS: np.int64, + REGULARIZATION_STRENGTH: np.float64, + WALLTIME: np.float64, + BACKEND_PROVIDER: str, + COMPUTE_DEVICE: str, + COMPUTE_RUNTIME: str, + # NB: following should be int but str is more practical because it enables + # use of missing values for solver for which it doesn't apply. + RESULT_NB_ITERATIONS: str, + OBJECTIVE_FUNCTION_VALUE: np.float64, + SOLVER: str, + PLATFORM: str, + PLATFORM_ARCHITECTURE: str, + PLATFORM_RELEASE: str, + SYSTEM_CPUS: np.int64, + SYSTEM_PROCESSOR: str, + SYSTEM_GPU: str, + SYSTEM_RAM: np.int64, + DATA_RANDOM_STATE: np.int64, + SOLVER_RANDOM_STATE: np.int64, + VERSION_INFO: str, + RUN_DATE: str, + COMMENT: str, +} + +COLUMNS_WITH_NONE_STRING = [] + +# If all those fields have equal values for two given benchmarks, then the oldest +# benchmark (given by RUN_DATE) will be discarded +UNIQUE_BENCHMARK_KEY = [ + BENCHMARK_ID_NAME, + DTYPE, + NB_DATA_SAMPLES, + NB_DATA_FEATURES, + NB_DATA_TARGETS, + REGULARIZATION_STRENGTH, + BACKEND_PROVIDER, + SOLVER, + COMPUTE_DEVICE, + COMPUTE_RUNTIME, + PLATFORM, + PLATFORM_ARCHITECTURE, + SYSTEM_PROCESSOR, + SYSTEM_CPUS, + SYSTEM_GPU, + DATA_RANDOM_STATE, + SOLVER_RANDOM_STATE, +] + +# Importance and say if ascending / descending +ROW_SORT_ORDER = [ + (DTYPE, True), + (NB_DATA_SAMPLES, False), + (NB_DATA_FEATURES, False), + (NB_DATA_TARGETS, True), + (REGULARIZATION_STRENGTH, False), + (WALLTIME, True), + (BACKEND_PROVIDER, True), + (COMPUTE_DEVICE, True), + (COMPUTE_RUNTIME, True), + (RESULT_NB_ITERATIONS, True), + (OBJECTIVE_FUNCTION_VALUE, False), + (SOLVER, True), + (SYSTEM_GPU, True), + (SYSTEM_CPUS, True), + (PLATFORM, True), + (PLATFORM_ARCHITECTURE, True), + (PLATFORM_RELEASE, True), + (SYSTEM_PROCESSOR, True), + (SYSTEM_RAM, True), + (DATA_RANDOM_STATE, True), + (SOLVER_RANDOM_STATE, True), + (RUN_DATE, False), + (VERSION_INFO, False), + (COMMENT, True), + (BENCHMARK_ID_NAME, True), +] +_row_sort_by, _row_sort_ascending = map(list, zip(*ROW_SORT_ORDER)) + +PARQUET_TABLE_DISPLAY_MAPPING = dict( + time=WALLTIME, + objective_value=OBJECTIVE_FUNCTION_VALUE, + objective_n_iter=RESULT_NB_ITERATIONS, + objective_dataset_param_n_samples=NB_DATA_SAMPLES, + objective_dataset_param_n_features=NB_DATA_FEATURES, + objective_dataset_param_n_targets=NB_DATA_TARGETS, + objective_objective_param_alpha=REGULARIZATION_STRENGTH, + objective_dataset_param_dtype=DTYPE, + objective_dataset_param_random_state=DATA_RANDOM_STATE, + objective_objective_param_random_state=SOLVER_RANDOM_STATE, + objective_objective_param_solver=SOLVER, + objective_solver_param___name=BACKEND_PROVIDER, + objective_solver_param_device=COMPUTE_DEVICE, + objective_solver_param_runtime=COMPUTE_RUNTIME, + objective_solver_param_comment=COMMENT, + objective_solver_param_version_info=VERSION_INFO, + objective_solver_param_run_date=RUN_DATE, + platform=PLATFORM, +) + +PARQUET_TABLE_DISPLAY_MAPPING.update( + { + "platform-architecture": PLATFORM_ARCHITECTURE, + "platform-release": PLATFORM_RELEASE, + "system-cpus": SYSTEM_CPUS, + "system-processor": SYSTEM_PROCESSOR, + "system-ram (GB)": SYSTEM_RAM, + } +) +_all_table_columns = list(PARQUET_TABLE_DISPLAY_MAPPING) + [BENCHMARK_ID_NAME] + +ALL_EXPECTED_COLUMNS = set(BENCHMARK_DEFINING_COLUMNS + _all_table_columns) + +IDS_LENGTH = 8 + + +def _get_id_from_str(s): + return hashlib.sha256(s.encode("utf8"), usedforsecurity=False).hexdigest()[ + :IDS_LENGTH + ] + + +def _get_sample_id_for_columns(row, defining_colums, constant_identifier): + return _get_id_from_str( + "".join(row[defining_colums].astype(str)) + constant_identifier + ) + + +def _validate_one_parquet_table(source): + df = pd.read_parquet(source) + + # NB: we're lenient on the columns + for col in ALL_EXPECTED_COLUMNS - set(df.columns): + df[col] = None + + df[BENCHMARK_ID_NAME] = df.apply( + lambda row: _get_sample_id_for_columns( + row, BENCHMARK_DEFINING_COLUMNS, _benchmark_defining_columns_identifier + ), + axis=1, + ) + + df = df[_all_table_columns] + df.rename(columns=PARQUET_TABLE_DISPLAY_MAPPING, inplace=True, errors="raise") + + df[RUN_DATE] = df[RUN_DATE].astype("datetime64[ns]") + + return df + + +def _validate_one_csv_table(source, parse_dates=True, order_columns=True): + NA_VALUES = set(STR_NA_VALUES) + NA_VALUES.discard("None") + + df = pd.read_csv( + source, + usecols=TABLE_DISPLAY_ORDER, + dtype=COLUMNS_DTYPES, + index_col=False, + na_values={col: NA_VALUES for col in COLUMNS_WITH_NONE_STRING}, + keep_default_na=False, + ) + + if order_columns: + df = df[TABLE_DISPLAY_ORDER] + + if parse_dates: + df[RUN_DATE] = pd.to_datetime(df[RUN_DATE], format=DATES_FORMAT).astype( + "datetime64[ns]" + ) + + return df + + +def _assemble_output_table( + dfs_from_csv, dfs_from_parquet, parquet_gpu_name, create_gpu_entry, list_known_gpus +): + + if not list_known_gpus and (len(dfs_from_parquet) == 0): + if parquet_gpu_name is not None: + parameter_name = ( + "--parquet-gpu-name" if parquet_gpu_name else "--no-parquet-gpu-name" + ) + raise ValueError( + f"The parameter {parameter_name} should only be used if at least one " + "benchopt parquet table is being consolidated, but only got csv tables." + ) + if create_gpu_entry is not False: + raise ValueError( + "The parameter --create-gpu-entry should only be used if at least one " + "benchopt parquet table is being consolidated, but got only csv tables." + ) + elif not list_known_gpus and parquet_gpu_name is None: + raise ValueError( + "Please use the --parquet-gpu-name parameter to provide a gpu name that " + "will be added to the metadata of the samples in the input parquet tables " + "or use the --no-parquet-gpu-name if you intend to leave the corresponding " + "field empty." + ) + + else: + gpu_names_from_csv = set( + gpu_name + for df in dfs_from_csv + for gpu_name in df[SYSTEM_GPU] + if (len(gpu_name) > 0) + ) + + if list_known_gpus: + print("\n".join(gpu_names_from_csv)) + return False + + if ( + (len(parquet_gpu_name) > 0) + and (parquet_gpu_name not in gpu_names_from_csv) + and not create_gpu_entry + ): + raise IndexError( + f"The gpu name {parquet_gpu_name} is unknown. Please use the " + "--new-gpu-entry parameter to confirm the addition of the new gpu " + "entry in the output csv table, or use --list-known-gpus parameter to " + "print a list of gpus names that have been already registered and use " + "one of those to bypass this error." + ) + + for df in dfs_from_parquet: + df[SYSTEM_GPU] = parquet_gpu_name + + df_list = dfs_from_csv + dfs_from_parquet + + if len(df_list) > 1: + df = pd.concat(df_list, ignore_index=True, copy=False) + else: + df = df_list[0] + + df = df[TABLE_DISPLAY_ORDER] + df.sort_values( + by=_row_sort_by, ascending=_row_sort_ascending, inplace=True, kind="stable" + ) + # HACK: sanitize mix of None values and empty strings that can happen when some + # columns are missing in the parquet input files (because it's optional and no + # solver returns it in the batch) by passing the data to CSV and re-loading + # again from CSV + df = _sanitize_df_with_tocsv(df) + + df.drop_duplicates(subset=UNIQUE_BENCHMARK_KEY, inplace=True, ignore_index=True) + + return df + + +def _sanitize_df_with_tocsv(df): + in_memory_buffer = BytesIO() + _df_to_csv(df, in_memory_buffer) + in_memory_buffer.seek(0) + return _validate_one_csv_table(in_memory_buffer, order_columns=False) + + +def _df_to_csv(df, target): + float_format_fn = partial( + np.format_float_positional, + precision=3, + unique=True, + fractional=False, + trim="-", + sign=False, + pad_left=None, + pad_right=None, + min_digits=None, + ) + df = df.copy() + df[WALLTIME] = df[WALLTIME].map(float_format_fn) + df.to_csv( + target, + index=False, + mode="a", + date_format=DATES_FORMAT, + ) + + +def _gspread_sync(source, gspread_url, gspread_auth_key): + import gspread + + df = _validate_one_csv_table(source, parse_dates=False) + + n_rows, n_cols = df.shape + walltime_worksheet_col = df.columns.get_loc(WALLTIME) + 1 + + gs = gspread.service_account(gspread_auth_key) + sheet = gs.open_by_url(gspread_url) + + global_range = ( + f"{gspread.utils.rowcol_to_a1(1, 1)}:" + f"{gspread.utils.rowcol_to_a1(n_rows + 1, n_cols)}" + ) + + try: + worksheet = sheet.worksheet(GOOGLE_WORKSHEET_NAME) + worksheet.clear() + worksheet.clear_basic_filter() + worksheet.freeze(0, 0) + worksheet.resize(rows=n_rows + 1, cols=n_cols) + worksheet.clear_notes(global_range) + reset_format = dict( + backgroundColorStyle=dict(rgbColor=dict(red=1, green=1, blue=1, alpha=1)), + textFormat=dict(bold=False), + ) + worksheet.format(global_range, reset_format) + except gspread.WorksheetNotFound: + worksheet = sheet.add_worksheet( + GOOGLE_WORKSHEET_NAME, rows=n_rows + 1, cols=n_cols + ) + + # ensure worksheets are sorted anti-alphabetically + sheet.reorder_worksheets( + sorted(sheet.worksheets(), key=lambda worksheet: worksheet.title.lower()) + ) + + # upload all values + worksheet.update( + values=[df.columns.values.tolist()] + df.values.tolist(), range_name="A1" + ) + + # set filter + worksheet.set_basic_filter(1, 1, n_rows + 1, n_cols) + + # freeze filter rows and benchmark-defining cols + worksheet.freeze(rows=1, cols=walltime_worksheet_col) + + format_queries = [] + + # Text is centerd and wrapped in all cells + global_format = dict( + horizontalAlignment="CENTER", + verticalAlignment="MIDDLE", + wrapStrategy="WRAP", + ) + format_queries.append(dict(range=global_range, format=global_format)) + + # benchmark_id and walltime columns are bold + bold_format = dict(textFormat=dict(bold=True)) + benchmark_id_col_range = ( + f"{gspread.utils.rowcol_to_a1(2, 1)}:" + f"{gspread.utils.rowcol_to_a1(n_rows + 1, 1)}" + ) + walltime_col_range = ( + f"{gspread.utils.rowcol_to_a1(2, walltime_worksheet_col)}:" + f"{gspread.utils.rowcol_to_a1(n_rows + 1, walltime_worksheet_col)}" + ) + format_queries.append(dict(range=benchmark_id_col_range, format=bold_format)) + format_queries.append(dict(range=walltime_col_range, format=bold_format)) + + # Header is light-ish yellow + yellow_lighter_header = dict( + backgroundColorStyle=dict( + rgbColor=dict(red=1, green=1, blue=102 / 255, alpha=1) + ) + ) + header_row_range = ( + f"{gspread.utils.rowcol_to_a1(1, 1)}:" + f"{gspread.utils.rowcol_to_a1(1, n_cols)}" + ) + format_queries.append(dict(range=header_row_range, format=yellow_lighter_header)) + + # Every other benchmark_id has greyed background + bright_gray_background = dict( + backgroundColorStyle=dict( + rgbColor=dict(red=232 / 255, green=233 / 255, blue=235 / 255, alpha=1) + ) + ) + benchmark_ids = df[BENCHMARK_ID_NAME] + benchmark_ids_ending_idx = ( + np.where((benchmark_ids.shift() != benchmark_ids).values[1:])[0] + 2 + ) + for benchmark_id_range_start, benchmark_id_range_end in zip_longest( + *(iter(benchmark_ids_ending_idx),) * 2 + ): + benchmark_row_range = ( + f"{gspread.utils.rowcol_to_a1(benchmark_id_range_start + 1, 1)}:" + f"{gspread.utils.rowcol_to_a1(benchmark_id_range_end or (n_rows + 1), n_cols)}" # noqa + ) + format_queries.append( + dict(range=benchmark_row_range, format=bright_gray_background) + ) + + # Apply formats + worksheet.batch_format(format_queries) + + # auto-resize rows and cols + worksheet.columns_auto_resize(0, n_cols - 1) + worksheet.rows_auto_resize(0, n_rows) + + +if __name__ == "__main__": + import os + import sys + from argparse import ArgumentParser + + argparser = ArgumentParser( + description=( + "Print an aggregated CSV-formated database of ridge benchmark results " + "for the sklearn-engine-benchmarks project hosted at " + "https://github.com/soda-inria/sklearn-engine-benchmarks.\n\n" + "The inputs are assumed to be a collection of benchopt parquet files and " + "CSV files, well formated according to the project current specs. This " + "command assumes rhat the inputs are valid and is lenient at checking " + "types, null values, or missing columns, hence the user is advised to " + "cautiously check outputs before using.\n\n" + "If several results are found for identical benchmarks, only the most " + "recent `Run date` value is retained, all anterior entries are discarded " + "from the output CSV." + ) + ) + + argparser.add_argument( + "benchmark_files", + nargs="+", + help="benchopt parquet files or sklearn-engine-benchmarks csv files", + ) + + argparser.add_argument( + "--check-csv", + action="store_true", + help="Perform a few sanity checks on a CSV database of ridge benchmark " + "results. If this option is passed, then the command only expects a single " + "input path to a csv file.", + ) + + argparser.add_argument( + "--sync-to-gspread", + action="store_true", + help="Synchronize a CSV database of ridge benchmark results to a google " + "spreadsheet and format it nicely. If this option is passed, then the command " + "only expects a single input path to a csv file, and also requires " + "--gspread-url and --gspread-auth-key.", + ) + + argparser.add_argument( + "--gspread-url", + help="URL to a google spreadsheet. Expected if and only if --sync-to-gspread " + "is passed.", + ) + + argparser.add_argument( + "--gspread-auth-key", + help="Path to a json authentication key for a gspread service account. " + "Expected if and only if --sync-to-gspread is passed.", + ) + + argparser.add_argument( + "--parquet-gpu-name", + help="Name of the GPU on the host that runs the benchmarks that are recorded " + "in the input parquet files.", + ) + + argparser.add_argument( + "--no-parquet-gpu-name", + action="store_true", + help="Do not insert a GPU name in the metadata of the benchmark samples that " + "were recorded in the input parquet files (and leave it blank).", + ) + + argparser.add_argument( + "--new-gpu-entry", + action="store_true", + help="Use this parameter along with --parquet-gpu-name to confirm that if the " + "GPU name is not yet known in the existing databases, it will be added to the " + "list of known GPU names. Else the command will throw an error.", + ) + + argparser.add_argument( + "--list-known-gpus", + action="store_true", + help="Will print a list of the GPU names that are used in CSV benchmark files.", + ) + + args = argparser.parse_args() + + if (parquet_gpu_name := args.parquet_gpu_name) is None and args.no_parquet_gpu_name: + parquet_gpu_name = "" + + create_gpu_entry = args.new_gpu_entry + list_known_gpus = args.list_known_gpus + + paths = args.benchmark_files + if (check_csv := args.check_csv) or args.sync_to_gspread: + if (n_paths := len(paths)) > 1: + command = "--check-csv" if check_csv else "--sync-to-gspread" + raise ValueError( + f"A single input path to a csv file is expected when the {command} " + f"parameter is passed, but you passed {n_paths - 1} additional " + "arguments." + ) + path = paths[0] + _, file_extension = os.path.splitext(path) + if file_extension != ".csv": + raise ValueError( + "Expecting a '.csv' file extensions, but got " + f"{file_extension} instead !" + ) + + if check_csv: + df_loaded = _validate_one_csv_table(path) + df_clean = _assemble_output_table( + dfs_from_csv=[df_loaded], + dfs_from_parquet=[], + parquet_gpu_name=None, + create_gpu_entry=False, + list_known_gpus=list_known_gpus, + ) + + pd.testing.assert_frame_equal(df_loaded, df_clean) + + if gspread_sync := args.sync_to_gspread: + if (gspread_url := args.gspread_url) is None: + raise ValueError( + "Please provide a URL to a google spreadsheet using the " + "--gspread-url parameter." + ) + + if (gspread_auth_key := args.gspread_auth_key) is None: + raise ValueError( + "Please use the --gspread-auth-key parameter to pass a json " + "authentication key for a service account from the google developer " + "console." + ) + _gspread_sync(path, gspread_url, gspread_auth_key) + + if not check_csv and not gspread_sync: + dfs_from_parquet, dfs_from_csv = [], [] + for path in paths: + _, file_extension = os.path.splitext(path) + if file_extension == ".parquet": + if list_known_gpus: + continue + dfs_from_parquet.append(_validate_one_parquet_table(path)) + elif file_extension == ".csv": + dfs_from_csv.append(_validate_one_csv_table(path, order_columns=False)) + else: + raise ValueError( + "Expecting '.csv' or '.parquet' file extensions, but got " + f"{file_extension} instead !" + ) + + df = _assemble_output_table( + dfs_from_csv=dfs_from_csv, + dfs_from_parquet=dfs_from_parquet, + parquet_gpu_name=parquet_gpu_name, + create_gpu_entry=create_gpu_entry, + list_known_gpus=list_known_gpus, + ) + + if df is not False: + _df_to_csv(df, sys.stdout) diff --git a/benchmarks/ridge/datasets/simulated_blobs.py b/benchmarks/ridge/datasets/simulated_blobs.py new file mode 100644 index 0000000..d850f73 --- /dev/null +++ b/benchmarks/ridge/datasets/simulated_blobs.py @@ -0,0 +1,42 @@ +from benchopt import BaseDataset, safe_import_context +from benchopt.datasets import make_correlated_data + +with safe_import_context() as import_ctx: + import numpy as np + + +class Dataset(BaseDataset): + name = "Simulated_correlated_data" + + parameters = { + "n_samples, n_features": [ + (10_000_000, 100), + (5_000_000, 100), + (5_000_000, 10), + (5000, 10000), + (5000, 5000), + ], + "n_targets": [1, 10], + "dtype": ["float32"], + "random_state": [123], + } + + def __init__(self, n_samples, n_features, n_targets, dtype, random_state): + self.n_samples = n_samples + self.n_features = n_features + self.n_targets = n_targets + self.random_state = random_state + self.dtype = dtype + + def get_data(self): + rng = np.random.RandomState(self.random_state) + + X, y, _ = make_correlated_data( + self.n_samples, self.n_features, self.n_targets, random_state=rng + ) + + dtype = getattr(np, self.dtype) + + return dict( + X=X.astype(dtype), y=y.astype(dtype), __name=self.name, **self._parameters + ) diff --git a/benchmarks/ridge/objective.py b/benchmarks/ridge/objective.py new file mode 100644 index 0000000..f5520fc --- /dev/null +++ b/benchmarks/ridge/objective.py @@ -0,0 +1,148 @@ +import numbers +from datetime import datetime + +from benchopt import BaseObjective, safe_import_context + +with safe_import_context() as import_ctx: + import numpy as np + from sklearn.linear_model._base import _rescale_data + + +class Objective(BaseObjective): + name = "Ridge walltime" + url = "https://github.com/soda-inria/sklearn-engine-benchmarks" + + requirements = ["numpy"] + + # Since our goal is to measure walltime for solvers that perform exact same + # computations, the solver parameters are part of the objective and must be set + # for all solvers, rather than being an independent benchmark space for each + # solver. + parameters = { + "alpha": [1.0, 1e-10], + "fit_intercept": [True], + "solver, max_iter, tol": [ + ("svd", None, 0), + ("cholesky", None, 0), + ("lsqr", None, 1e-4), + ("sparse_cg", None, 1e-4), + ("sag", None, 1e-4), + ("saga", None, 1e-4), + ("cd", None, 1e-4), + ("eig", None, None), + # Used for scikit-learn-intelex that doesn't + # document the underlying solver nor expose the n_iter_ attribute + ("DefaultDense", None, 1e-4), + ], + "sample_weight": ["None"], # NB: add "random" to test non None weights + "random_state": [123], + } + + def set_data(self, X, y, **dataset_parameters): + self.X = X + self.y = y + dtype = X.dtype + + if self.sample_weight == "None": + sample_weight = None + elif self.sample_weight == "unary": + sample_weight = np.ones(len(X), dtype=dtype) + elif self.sample_weight == "random": + rng_sample_weight = np.random.default_rng( + dataset_parameters["random_state"] + 1 + ) + sample_weight = rng_sample_weight.random(size=len(X)).astype(dtype) + else: + raise ValueError( + "Expected 'sample_weight' parameter to be either equal to 'None', " + f"'unary' or 'random', but got {sample_weight}." + ) + + self.sample_weight_ = sample_weight + self.dataset_parameters = dataset_parameters + + def evaluate_result(self, weights, intercept, n_iter, **solver_parameters): + # NB: weights, intercept expected to be numpy arrays + + X, y = self.X, self.y + if self.sample_weight_ is not None: + X, y, _ = _rescale_data(X, y, self.sample_weight_, inplace=False) + + y = y.reshape((y.shape[0], -1)) + weights = weights.reshape((-1, X.shape[1], 1)) + + value = ( + (((X @ weights).squeeze(2) + (intercept - y).T) ** 2).sum() + + (self.alpha * (weights**2).sum()) + ) / (X.shape[0] * len(y.T)) + + all_parameters = dict(solver_param_run_date=datetime.today()) + all_parameters.update( + { + ("dataset_param_" + key): value + for key, value in self.dataset_parameters.items() + } + ) + all_parameters.update( + { + ("objective_param_" + key): value + for key, value in self._parameters.items() + } + ) + all_parameters.update( + {("solver_param_" + key): value for key, value in solver_parameters.items()} + ) + + if not (isinstance(n_iter, numbers.Number) or (n_iter is None)): + n_iter = max(n_iter) + + # NB: str for n_iter is a more practical type because it enables + # using missing values for solvers for which it doesn't apply + if n_iter is None: + n_iter = "" + else: + n_iter = str(n_iter) + + return dict( + value=value, + n_iter=n_iter, + objective_param___name=self.name, + **all_parameters, + ) + + def get_one_result(self): + n_features = self.dataset_parameters["n_features"] + n_targets = self.dataset_parameters["n_targets"] + if n_targets == 1: + weights = np.ones((n_features,)) + else: + weights = np.ones( + ( + n_targets, + n_features, + ) + ) + + return dict(weights=weights, intercept=np.ones((n_targets,))) + + def get_objective(self): + # Copy the data before sending to the solver, to ensure that no unfortunate + # side effects can happen + X = self.X.copy() + y = self.y.copy() + + sample_weight = self.sample_weight_ + if hasattr(sample_weight, "copy"): + sample_weight = sample_weight.copy() + + return dict( + X=X, + y=y, + sample_weight=sample_weight, + alpha=self.alpha, + fit_intercept=self.fit_intercept, + solver=self.solver, + max_iter=self.max_iter, + tol=self.tol, + random_state=self.random_state, + ) diff --git a/benchmarks/ridge/outputs/benchopt_run_2024-01-18_11h26m04.parquet b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_11h26m04.parquet new file mode 100644 index 0000000..ca3adf5 Binary files /dev/null and b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_11h26m04.parquet differ diff --git a/benchmarks/ridge/outputs/benchopt_run_2024-01-18_12h59m51.parquet b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_12h59m51.parquet new file mode 100644 index 0000000..180efc8 Binary files /dev/null and b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_12h59m51.parquet differ diff --git a/benchmarks/ridge/outputs/benchopt_run_2024-01-18_13h35m10.parquet b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_13h35m10.parquet new file mode 100644 index 0000000..25627ed Binary files /dev/null and b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_13h35m10.parquet differ diff --git a/benchmarks/ridge/outputs/benchopt_run_2024-01-18_16h06m03.parquet b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_16h06m03.parquet new file mode 100644 index 0000000..c1fd068 Binary files /dev/null and b/benchmarks/ridge/outputs/benchopt_run_2024-01-18_16h06m03.parquet differ diff --git a/benchmarks/ridge/results.csv b/benchmarks/ridge/results.csv new file mode 100644 index 0000000..8ad111b --- /dev/null +++ b/benchmarks/ridge/results.csv @@ -0,0 +1,157 @@ +Benchmark id,Dtype,Nb data samples,Nb data features,Nb data targets,Regularization strength,Walltime,Backend provider,Compute device,Compute runtime,Solver,Nb cpus,Cpu name,Gpu name,RAM (GB),Platform,Platform architecture,Platform release,Run date,Version info,Comment,Result nb iterations,Result objective value,Data random state,Solver random state +cbe96b03,float32,10000000,100,1,1.0,0.7,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,3.105119722035217,123,123 +cbe96b03,float32,10000000,100,1,1.0,0.799,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,3.1051199220344543,123,123 +cbe96b03,float32,10000000,100,1,1.0,1.89,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.105120322080231,123,123 +cbe96b03,float32,10000000,100,1,1.0,4.69,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.105119322015,123,123 +cbe96b03,float32,10000000,100,1,1.0,10,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,3.105120522610473,123,123 +cbe96b03,float32,10000000,100,1,1.0,10.6,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,17,3.1051191220458985,123,123 +cbe96b03,float32,10000000,100,1,1.0,10.9,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.105118922013855,123,123 +cbe96b03,float32,10000000,100,1,1.0,35.2,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.105119722034836,123,123 +f976a4f8,float32,10000000,100,1,1e-10,0.706,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,3.1051164000000004,123,123 +f976a4f8,float32,10000000,100,1,1e-10,0.759,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,3.105116600000001,123,123 +f976a4f8,float32,10000000,100,1,1e-10,1.88,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.1051168,123,123 +f976a4f8,float32,10000000,100,1,1e-10,4.66,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.105116,123,123 +f976a4f8,float32,10000000,100,1,1e-10,9.8,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,3.1051172000000005,123,123 +f976a4f8,float32,10000000,100,1,1e-10,10.3,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,17,3.105116,123,123 +f976a4f8,float32,10000000,100,1,1e-10,10.9,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.1051154000000003,123,123 +f976a4f8,float32,10000000,100,1,1e-10,35.4,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,3.1051164000000004,123,123 +a9625843,float32,10000000,100,10,1.0,0.742,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,2.692140948618164,123,123 +a9625843,float32,10000000,100,10,1.0,0.748,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,2.692140948620453,123,123 +a9625843,float32,10000000,100,10,1.0,5.49,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.69214126861908,123,123 +a9625843,float32,10000000,100,10,1.0,10.8,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.6921425489871216,123,123 +a9625843,float32,10000000,100,10,1.0,38.2,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.692140628619232,123,123 +a9625843,float32,10000000,100,10,1.0,90.9,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,18,2.692143188612213,123,123 +a9625843,float32,10000000,100,10,1.0,93.4,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.6921435085891723,123,123 +8ed75954,float32,10000000,100,10,1e-10,0.748,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,2.69213824,123,123 +8ed75954,float32,10000000,100,10,1e-10,0.749,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,2.69213856,123,123 +8ed75954,float32,10000000,100,10,1e-10,5.54,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.69213888,123,123 +8ed75954,float32,10000000,100,10,1e-10,11,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.69214016,123,123 +8ed75954,float32,10000000,100,10,1e-10,37.2,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.69213824,123,123 +8ed75954,float32,10000000,100,10,1e-10,85.6,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,18,2.6921408,123,123 +8ed75954,float32,10000000,100,10,1e-10,89.7,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.69214112,123,123 +3a327106,float32,5000000,100,1,1.0,0.375,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,4.5062807864048,123,123 +3a327106,float32,5000000,100,1,1.0,0.385,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,4.506280786417007,123,123 +3a327106,float32,5000000,100,1,1.0,0.97,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506280786545562,123,123 +3a327106,float32,5000000,100,1,1.0,1.29,cuml,gpu,,svd,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.5062807864048,123,123 +3a327106,float32,5000000,100,1,1.0,2.35,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506281986365509,123,123 +3a327106,float32,5000000,100,1,1.0,4.87,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,4.506281586739349,123,123 +3a327106,float32,5000000,100,1,1.0,4.96,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506283986231232,123,123 +3a327106,float32,5000000,100,1,1.0,5.15,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,17,4.506282786375428,123,123 +3a327106,float32,5000000,100,1,1.0,17.6,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506280786405563,123,123 +83d52c66,float32,5000000,100,1,1e-10,0.369,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,4.506274400000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,0.376,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,4.506274,123,123 +83d52c66,float32,5000000,100,1,1e-10,0.978,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506274400000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,1.27,cuml,gpu,,svd,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506274400000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,2.32,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506275200000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,4.89,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,4.506275200000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,5.14,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,17,4.506276400000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,5.17,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506277600000001,123,123 +83d52c66,float32,5000000,100,1,1e-10,18,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.506274400000001,123,123 +9bd2a256,float32,5000000,100,10,1.0,0.379,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,2.0798047731054687,123,123 +9bd2a256,float32,5000000,100,10,1.0,0.398,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,2.0798046131018064,123,123 +9bd2a256,float32,5000000,100,10,1.0,2.73,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.079804933096008,123,123 +9bd2a256,float32,5000000,100,10,1.0,5.29,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.079804933297729,123,123 +9bd2a256,float32,5000000,100,10,1.0,18.6,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.0798046131018064,123,123 +9bd2a256,float32,5000000,100,10,1.0,42.8,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,18,2.0798062130960084,123,123 +9bd2a256,float32,5000000,100,10,1.0,45.8,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.079805413095704,123,123 +61613818,float32,5000000,100,10,1e-10,0.393,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,2.0798011200000004,123,123 +61613818,float32,5000000,100,10,1e-10,0.4,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,2.0798012800000003,123,123 +61613818,float32,5000000,100,10,1e-10,2.72,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.0798011200000004,123,123 +61613818,float32,5000000,100,10,1e-10,5.57,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.0798012800000003,123,123 +61613818,float32,5000000,100,10,1e-10,18.4,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.0798009600000005,123,123 +61613818,float32,5000000,100,10,1e-10,42.4,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,18,2.07980256,123,123 +61613818,float32,5000000,100,10,1e-10,44.6,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.0798017600000005,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.027,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.025126947566986,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.0478,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.025126947566989,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.103,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0251269460045784,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.256,cuml,gpu,,svd,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0251269475669652,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.282,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0251269460051715,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.381,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0251269600671082,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.426,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,0.0251269460046142,123,123 +a9a05f25,float32,5000000,10,1,1.0,0.581,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,9,0.0251269647544533,123,123 +a9a05f25,float32,5000000,10,1,1.0,1.06,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.025126947566992,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.0187,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.0251269046875,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.0478,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.025126903125,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.102,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.025126903125,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.117,cuml,gpu,,svd,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0251269046875,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.299,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.025126903125,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.405,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0251269203125,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.432,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,0.025126903125,123,123 +684c4a29,float32,5000000,10,1,1e-10,0.602,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,9,0.025126921875,123,123 +684c4a29,float32,5000000,10,1,1e-10,1.04,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.025126903125,123,123 +ffd32c2e,float32,5000000,10,10,1.0,0.0294,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.1351635853305053,123,123 +ffd32c2e,float32,5000000,10,10,1.0,0.0715,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.1351635853307151,123,123 +ffd32c2e,float32,5000000,10,10,1.0,0.572,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,0.1351635653210258,123,123 +ffd32c2e,float32,5000000,10,10,1.0,0.61,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.135163555332241,123,123 +ffd32c2e,float32,5000000,10,10,1.0,1.39,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.1351635753305053,123,123 +ffd32c2e,float32,5000000,10,10,1.0,2.25,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.1351635853300857,123,123 +ffd32c2e,float32,5000000,10,10,1.0,4.8,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,11,0.1351635753308296,123,123 +669ae596,float32,5000000,10,10,1e-10,0.0205,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.13516333,123,123 +669ae596,float32,5000000,10,10,1e-10,0.0669,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.13516333,123,123 +669ae596,float32,5000000,10,10,1e-10,0.575,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,0.13516331,123,123 +669ae596,float32,5000000,10,10,1e-10,0.666,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.1351633,123,123 +669ae596,float32,5000000,10,10,1e-10,1.35,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.13516332,123,123 +669ae596,float32,5000000,10,10,1e-10,2.24,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.13516341,123,123 +669ae596,float32,5000000,10,10,1e-10,4.82,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,11,0.13516332,123,123 +73b8dab5,float32,5000,10000,1,1.0,0.418,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.268106903386116,123,123 +73b8dab5,float32,5000,10000,1,1.0,0.463,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,50,0.268086632657051,123,123 +73b8dab5,float32,5000,10000,1,1.0,0.805,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2680860376119613,123,123 +73b8dab5,float32,5000,10000,1,1.0,0.843,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.2680860376119613,123,123 +73b8dab5,float32,5000,10000,1,1.0,2,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2681012868404388,123,123 +73b8dab5,float32,5000,10000,1,1.0,3.6,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.2681045798659324,123,123 +73b8dab5,float32,5000,10000,1,1.0,14.5,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,0.268086059141159,123,123 +73b8dab5,float32,5000,10000,1,1.0,14.8,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2680860648870468,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,0.308,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,30,0.0019931515008172,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,0.437,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.1197693048449857e-05,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,0.818,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,7.062814981604591e-09,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,0.824,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,7.062814981604591e-09,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,1.94,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,4.778688843857479e-07,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,3.53,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,1.8515764182853547e-05,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,13.7,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.8215831693544388e-08,123,123 +1e6fef9b,float32,5000,10000,1,1e-10,14.8,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.485896558746457e-08,123,123 +06511952,float32,5000,10000,10,1.0,0.82,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2710840446662902,123,123 +06511952,float32,5000,10000,10,1.0,0.835,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.2710840446662902,123,123 +06511952,float32,5000,10000,10,1.0,3.41,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2711014544296264,123,123 +06511952,float32,5000,10000,10,1.0,3.59,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.2711023703384399,123,123 +06511952,float32,5000,10000,10,1.0,3.87,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,50,0.2710846074485779,123,123 +06511952,float32,5000,10000,10,1.0,13.2,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,0.2710841004276275,123,123 +06511952,float32,5000,10000,10,1.0,15,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2710840761089325,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,0.818,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,8.369689202053547e-09,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,0.83,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,8.369689202053547e-09,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,2.35,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,30,0.0019068925747256,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,3.36,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,1.7703694999546022e-05,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,3.52,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,1.8287345041726805e-05,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,13.2,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,3.1812859882497786e-08,123,123 +6e8bfb2d,float32,5000,10000,10,1e-10,14.9,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.6364008265968563e-08,123,123 +e5684553,float32,5000,5000,1,1.0,0.408,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.20554375,123,123 +e5684553,float32,5000,5000,1,1.0,0.638,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.2054421875,123,123 +e5684553,float32,5000,5000,1,1.0,0.825,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,2.20544248046875,123,123 +e5684553,float32,5000,5000,1,1.0,1.42,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.20639384765625,123,123 +e5684553,float32,5000,5000,1,1.0,1.51,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,396,2.20628037109375,123,123 +e5684553,float32,5000,5000,1,1.0,3.66,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,2.20545478515625,123,123 +e5684553,float32,5000,5000,1,1.0,6.71,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.20544208984375,123,123 +e5684553,float32,5000,5000,1,1.0,7.3,cuml,gpu,,svd,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.205442578125,123,123 +e5684553,float32,5000,5000,1,1.0,9.85,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.20544287109375,123,123 +accdc2be,float32,5000,5000,1,1e-10,0.4,cuml,gpu,,eig,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.2741389233834743,123,123 +accdc2be,float32,5000,5000,1,1e-10,1.15,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,0.0106379599382264,123,123 +accdc2be,float32,5000,5000,1,1e-10,2.13,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,563,0.373785498419541,123,123 +accdc2be,float32,5000,5000,1,1e-10,3.66,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,6.823594151750061e-05,123,123 +accdc2be,float32,5000,5000,1,1e-10,4.49,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,3.844662064117317e-06,123,123 +accdc2be,float32,5000,5000,1,1e-10,7.23,cuml,gpu,,svd,32,AMD EPYC 7302 16-Core Processor,NVIDIA A100-PCIE-40GB,503,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.271922983596916e-06,123,123 +accdc2be,float32,5000,5000,1,1e-10,9.96,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.7624334327618407e-06,123,123 +accdc2be,float32,5000,5000,1,1e-10,10.5,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.7624334327618407e-06,123,123 +accdc2be,float32,5000,5000,1,1e-10,11,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0467559783076562,123,123 +7b05f2bf,float32,5000,5000,10,1.0,0.645,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.375215234375,123,123 +7b05f2bf,float32,5000,5000,10,1.0,0.778,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,2.375215,123,123 +7b05f2bf,float32,5000,5000,10,1.0,3.66,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,2.375225234375,123,123 +7b05f2bf,float32,5000,5000,10,1.0,4.53,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,2.375214921875,123,123 +7b05f2bf,float32,5000,5000,10,1.0,9.85,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.375214453125,123,123 +7b05f2bf,float32,5000,5000,10,1.0,13.7,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,2.376071796875,123,123 +7b05f2bf,float32,5000,5000,10,1.0,14.4,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,403,2.37613625,123,123 +2f926629,float32,5000,5000,10,1e-10,1.02,scikit-learn-intelex,cpu,,DefaultDense,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn-intelex 2024.0.1,,,314637385570.715,123,123 +2f926629,float32,5000,5000,10,1e-10,3.67,sklearn-torch-dispatch,cuda,,svd,32,AMD EPYC 7402 24-Core Processor,NVIDIA A100-PCIE-40GB,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.2,,,0.0002252654870639,123,123 +2f926629,float32,5000,5000,10,1e-10,5.85,sklearn-torch-dispatch,cpu,,svd,32,AMD EPYC 7402 24-Core Processor,,1008,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.5.dev0; torch 2.1.0.post100,,,1.004838915901758e-05,123,123 +2f926629,float32,5000,5000,10,1e-10,9.98,scikit-learn,,,svd,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,7.194650675920532e-06,123,123 +2f926629,float32,5000,5000,10,1e-10,10.5,scikit-learn,,,cholesky,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,7.194650675920532e-06,123,123 +2f926629,float32,5000,5000,10,1e-10,19.9,scikit-learn,,,lsqr,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,652,0.4086182426040169,123,123 +2f926629,float32,5000,5000,10,1e-10,93.1,scikit-learn,,,sparse_cg,32,Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz,,377,Linux,x86_64,4.18.0-394.el8.x86_64,2024-01-18,scikit-learn 1.3.2,,,0.0719987724515187,123,123 diff --git a/benchmarks/ridge/solvers/cuml.py b/benchmarks/ridge/solvers/cuml.py new file mode 100644 index 0000000..b892e96 --- /dev/null +++ b/benchmarks/ridge/solvers/cuml.py @@ -0,0 +1,107 @@ +from importlib.metadata import version + +from benchopt import BaseSolver, safe_import_context +from benchopt.stopping_criterion import SingleRunCriterion + +with safe_import_context() as import_ctx: + import cuml + import cupy + import numpy as np + + +class Solver(BaseSolver): + """https://docs.rapids.ai/api/cuml/stable/api/#ridge-regression""" + + name = "cuml" + requirements = ["cuml"] + + parameters = dict(device=["gpu"]) + + stopping_criterion = SingleRunCriterion(1) + + def set_objective( + self, + X, + y, + sample_weight, + alpha, + fit_intercept, + solver, + max_iter, + tol, + random_state, + ): + self.X = cupy.asarray(X) + self.y = cupy.asarray(y) + + self.sample_weight = sample_weight + if sample_weight is not None: + self.sample_weight = cupy.asarray(sample_weight) + + self.alpha = alpha + self.fit_intercept = fit_intercept + self.solver = solver + self.max_iter = max_iter + self.tol = tol + self.random_state = random_state + + def skip(self, **objective_dict): + + X = objective_dict["X"] + if X.dtype == np.float64: + # We haven't came accross cuda devices that doesn't support float64 yet, + # can it happen ? If it happens, the following instruction will fail, + # please enclose it with the appropriate Try/Except to return the + # appropriate skip decision. + cupy.zeros(1, dtype=cupy.float64) + # return True, ( + # f"This {self.device} device has no support for float64 compute" + # ) + + y = objective_dict["y"] + if (y.ndim == 2) and (y.shape[1] > 1): + return True, "Multitarget is not supported." + + solver = objective_dict["solver"] + # NB: should also support "cd" but it doesnt work + # TODO: investigate ? + if solver not in ["svd", "eig"]: + return True, "Only accepts the svd solver at the moment." + + return False, None + + def warm_up(self): + n_warmup_samples = 20 + n_warmup_features = 5 + sample_weight = self.sample_weight + if sample_weight is not None: + sample_weight = sample_weight[:n_warmup_samples].copy() + cuml.Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + solver=self.solver, + ).fit( + self.X[:n_warmup_samples, :n_warmup_features].copy(), + self.y[:n_warmup_samples].copy(), + sample_weight=sample_weight, + ) + + def run(self, _): + estimator = cuml.Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + solver=self.solver, + ).fit(self.X, self.y, sample_weight=self.sample_weight) + + self.weights = estimator.coef_ + self.intercept = estimator.intercept_ + + def get_result(self): + return dict( + weights=cupy.asnumpy(self.weights), + intercept=cupy.asnumpy(self.intercept), + n_iter=None, + version_info=f"scikit-learn {version('scikit-learn')}", + __name=self.name, + **self._parameters, + ) diff --git a/benchmarks/ridge/solvers/scikit_learn.py b/benchmarks/ridge/solvers/scikit_learn.py new file mode 100644 index 0000000..14674a2 --- /dev/null +++ b/benchmarks/ridge/solvers/scikit_learn.py @@ -0,0 +1,98 @@ +from importlib.metadata import version + +from benchopt import BaseSolver, safe_import_context +from benchopt.stopping_criterion import SingleRunCriterion + +with safe_import_context() as import_ctx: + from sklearn.linear_model import Ridge + + +class Solver(BaseSolver): + name = "scikit-learn" + requirements = ["scikit-learn"] + + stopping_criterion = SingleRunCriterion(1) + + def set_objective( + self, + X, + y, + sample_weight, + alpha, + fit_intercept, + solver, + max_iter, + tol, + random_state, + ): + self.X = X + self.y = y + self.sample_weight = sample_weight + self.alpha = alpha + self.fit_intercept = fit_intercept + self.solver = solver + self.max_iter = max_iter + self.tol = tol + self.random_state = random_state + + def skip(self, **objective_dict): + solver = objective_dict["solver"] + + if solver in ["sag", "saga"]: + # TODO: investigate ? + return True, ( + "Preliminary testing show this solver is too slow to have relevance " + "in the benchmark." + ) + + if solver in ["DefaultDense", "eig", "cd"]: + return True, "No support for this solver parameter." + + return False, None + + def warm_up(self): + n_warmup_samples = 20 + n_warmup_features = 5 + sample_weight = self.sample_weight + if sample_weight is not None: + sample_weight = sample_weight[:n_warmup_samples].copy() + Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + copy_X=False, + max_iter=self.max_iter, + tol=self.tol, + solver=self.solver, + positive=True if (self.solver == "lbfgs") else False, + random_state=self.random_state, + ).fit( + self.X[:n_warmup_samples, :n_warmup_features].copy(), + self.y[:n_warmup_samples].copy(), + sample_weight, + ) + + def run(self, _): + estimator = Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + copy_X=False, + max_iter=self.max_iter, + tol=self.tol, + solver=self.solver, + positive=True if (self.solver == "lbfgs") else False, + random_state=self.random_state, + ).fit(self.X, self.y, self.sample_weight) + + self.weights = estimator.coef_ + self.intercept = estimator.intercept_ + self.n_iter_ = estimator.n_iter_ + + def get_result(self): + return dict( + weights=self.weights, + intercept=self.intercept, + n_iter=self.n_iter_, + version_info=f"scikit-learn {version('scikit-learn')}", + __name=self.name, + **self._parameters, + ) diff --git a/benchmarks/ridge/solvers/scikit_learn_intelex.py b/benchmarks/ridge/solvers/scikit_learn_intelex.py new file mode 100644 index 0000000..c5f697f --- /dev/null +++ b/benchmarks/ridge/solvers/scikit_learn_intelex.py @@ -0,0 +1,148 @@ +from contextlib import nullcontext +from importlib.metadata import version + +from benchopt import BaseSolver, safe_import_context +from benchopt.stopping_criterion import SingleRunCriterion + +with safe_import_context() as import_ctx: + # isort: off + import dpctl + import numpy as np + from sklearnex.linear_model import Ridge + from sklearnex import config_context + + # isort: on + + +class Solver(BaseSolver): + name = "scikit-learn-intelex" + + requirements = [ + "scikit-learn-intelex", + "dpcpp-cpp-rt", + ] + + parameters = { + "device, runtime": [ + ("cpu", None), # TODO: replace "None" with "opencl" if relevant + ("gpu", "level_zero"), + ], + } + + stopping_criterion = SingleRunCriterion(1) + + def set_objective( + self, + X, + y, + sample_weight, + alpha, + fit_intercept, + solver, + max_iter, + tol, + random_state, + ): + # TODO: the overhead of the copy of the data from host to device could be + # eliminated if scikit-learn-intelex could just take usm_ndarray objects as + # input and directly run compute with the underlying memory buffer. The + # documentation at + # https://intel.github.io/scikit-learn-intelex/latest/oneapi-gpu.html#device-offloading # noqa + # suggests that it is the intended behavior, however in practice + # scikit-learn-intelex currently always perform underlying copies + # under the hood no matter what, and sometimes fails at doing so. See e.g. + # issue at + # https://github.com/intel/scikit-learn-intelex/issues/1534#issuecomment-1766266299 # noqa + + # if self.runtime != "numpy": + # device = device = dpctl.SyclDevice(f"{self.runtime}:{self.device}") + # self.X = dpt.asarray(X, copy=True, device=device) + # else: + # self.X = X + + self.X = X + self.y = y + self.sample_weight = sample_weight + self.alpha = alpha + self.fit_intercept = fit_intercept + self.solver = solver + self.max_iter = max_iter + self.tol = tol + self.random_state = random_state + + def skip(self, **objective_dict): + if self.runtime is not None: + try: + device = dpctl.SyclDevice(f"{self.runtime}:{self.device}") + except Exception: + return ( + True, + f"{self.runtime} runtime not found for device {self.device}", + ) + + X = objective_dict["X"] + if (X.dtype == np.float64) and not device.has_aspect_fp64: + return True, ( + f"This {self.device} device has no support for float64 compute" + ) + + solver = objective_dict["solver"] + + if solver != "DefaultDense": + # TODO: investigate ? + return True, "The only supported solver parameter is DefaultDense." + + return False, None + + def warm_up(self): + n_warmup_samples = 20 + n_warmup_features = 5 + sample_weight = self.sample_weight + if sample_weight is not None: + sample_weight = sample_weight[:n_warmup_samples].copy() + with nullcontext() if (self.runtime is None) else config_context( + target_offload=f"{self.runtime}:{self.device}" + ): + Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + copy_X=False, + max_iter=self.max_iter, + tol=self.tol, + solver="auto", + positive=True if (self.solver == "lbfgs") else False, + random_state=self.random_state, + ).fit( + self.X[:n_warmup_samples, :n_warmup_features].copy(), + self.y[:n_warmup_samples].copy(), + sample_weight, + ) + + def run(self, _): + with nullcontext() if (self.runtime is None) else config_context( + target_offload=f"{self.runtime}:{self.device}" + ): + estimator = Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + copy_X=False, + max_iter=self.max_iter, + tol=self.tol, + solver="auto", + positive=True if (self.solver == "lbfgs") else False, + random_state=self.random_state, + ).fit(self.X, self.y, self.sample_weight) + + self.weights = estimator.coef_ + self.intercept = estimator.intercept_ + self.n_iter_ = estimator.n_iter_ + + def get_result(self): + return dict( + weights=self.weights, + intercept=self.intercept, + n_iter=self.n_iter_, + version_info=f"scikit-learn-intelex {version('scikit-learn-intelex')}", + __name=self.name, + **self._parameters, + ) diff --git a/benchmarks/ridge/solvers/sklearn_torch_dispatch.py b/benchmarks/ridge/solvers/sklearn_torch_dispatch.py new file mode 100644 index 0000000..1ba6213 --- /dev/null +++ b/benchmarks/ridge/solvers/sklearn_torch_dispatch.py @@ -0,0 +1,140 @@ +from importlib.metadata import PackageNotFoundError, version + +from benchopt import BaseSolver, safe_import_context +from benchopt.stopping_criterion import SingleRunCriterion + +with safe_import_context() as import_ctx: + # isort: off + import numpy as np + + # NB: even if it's not use for the compute we rely on the sklearn_pytorch_engine + # for the few utilities it contains e.g for loading torch with xpu support and + # checking for float64 compat. + # This import is necessary to pre-load torch extensions + import sklearn_pytorch_engine # noqa + import torch + from sklearn import config_context + from sklearn.linear_model import Ridge + from sklearn_pytorch_engine._utils import has_fp64_support + + # isort: on + + +class Solver(BaseSolver): + name = "sklearn-torch-dispatch" + requirements = ["scikit-learn", "sklearn-pytorch-engine"] + + parameters = { + "device": ["cpu", "xpu", "cuda", "mps"], + } + + stopping_criterion = SingleRunCriterion(1) + + def set_objective( + self, + X, + y, + sample_weight, + alpha, + fit_intercept, + solver, + max_iter, + tol, + random_state, + ): + # Copy the data before running the benchmark to ensure that no unfortunate side + # effects can happen + self.X = torch.asarray(X, copy=True, device=self.device) + self.y = torch.asarray(y, copy=True, device=self.device) + self.sample_weight = sample_weight + if sample_weight is not None: + self.sample_weight = torch.asarray( + sample_weight, copy=True, device=self.device + ) + + self.alpha = alpha + self.fit_intercept = fit_intercept + self.solver = solver + self.max_iter = max_iter + self.tol = tol + self.random_state = random_state + + def skip(self, **objective_dict): + if not Ridge()._get_tags()["array_api_support"]: + return True, ( + "Requires the development branch for Ridge support for Array API." + ) + + try: + torch.zeros(1, dtype=torch.float32, device=self.device) + except Exception: + return True, f"{self.device} compute backend for pytorch not found" + + X = objective_dict["X"] + if (X.dtype == np.float64) and not has_fp64_support(self.device): + return True, ( + f"This {self.device} device has no support for float64 compute" + ) + + solver = objective_dict["solver"] + if solver != "svd": + return True, "Only accepts the svd solver at the moment." + + return False, None + + def warm_up(self): + n_warmup_samples = 20 + n_warmup_features = 5 + sample_weight = self.sample_weight + if sample_weight is not None: + sample_weight = sample_weight[:n_warmup_samples].clone() + with config_context(array_api_dispatch=True): + Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + copy_X=False, + max_iter=self.max_iter, + tol=self.tol, + solver=self.solver, + positive=True if (self.solver == "lbfgs") else False, + random_state=self.random_state, + ).fit( + self.X[:n_warmup_samples, :n_warmup_features].clone(), + self.y[:n_warmup_samples].clone(), + sample_weight, + ) + + def run(self, _): + with config_context(array_api_dispatch=True): + estimator = Ridge( + alpha=self.alpha, + fit_intercept=self.fit_intercept, + copy_X=False, + max_iter=self.max_iter, + tol=self.tol, + solver=self.solver, + positive=True if (self.solver == "lbfgs") else False, + random_state=self.random_state, + ).fit(self.X, self.y, self.sample_weight) + + self.weights = estimator.coef_ + self.intercept = estimator.intercept_ + self.n_iter_ = estimator.n_iter_ + + def get_result(self): + version_info = ( + f"scikit-learn {version('scikit-learn')}; torch {version('torch')}" + ) + try: + version_info += f"; ipex {version('intel-extension-for-pytorch')}" + except PackageNotFoundError: + pass + + return dict( + weights=self.weights.cpu().numpy(), + intercept=self.intercept.cpu().numpy(), + n_iter=self.n_iter_, + version_info=version_info, + __name=self.name, + **self._parameters, + )