From 77863a657535a905ebfb6691ca03e6e191623601 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Mon, 8 Apr 2024 23:47:49 +0200 Subject: [PATCH 1/8] example --- _doc/examples/plot_benchmark_rf.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/_doc/examples/plot_benchmark_rf.py b/_doc/examples/plot_benchmark_rf.py index 423669c..c844d74 100644 --- a/_doc/examples/plot_benchmark_rf.py +++ b/_doc/examples/plot_benchmark_rf.py @@ -22,8 +22,6 @@ import numpy import pandas from lightgbm import LGBMRegressor -from onnxmltools.convert.lightgbm.operator_converters.LightGbm import convert_lightgbm -from onnxmltools.convert.xgboost.operator_converters.XGBoost import convert_xgboost from onnxruntime import InferenceSession, SessionOptions from psutil import cpu_count from sphinx_runpython.runpython import run_cmd @@ -33,9 +31,14 @@ from sklearn.ensemble import RandomForestRegressor from tqdm import tqdm from xgboost import XGBRegressor +from onnxmltools.convert.xgboost.operator_converters.XGBoost import convert_xgboost def skl2onnx_convert_lightgbm(scope, operator, container): + from onnxmltools.convert.lightgbm.operator_converters.LightGbm import ( + convert_lightgbm, + ) + options = scope.get_options(operator.raw_operator) if "split" in options: operator.split = options["split"] From ada0b518268571e7afe339901ca93f9105c11816 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Fri, 30 Aug 2024 10:13:26 +0200 Subject: [PATCH 2/8] lint --- _doc/examples/plot_benchmark_rf.py | 12 +++---- _doc/examples/plot_onnxruntime.py | 4 +-- .../ut_light_api/test_backend_export.py | 9 +++--- _unittests/ut_light_api/test_light_api.py | 2 +- _unittests/ut_plotting/test_dot_plot.py | 1 - _unittests/ut_plotting/test_text_plot.py | 1 - _unittests/ut_translate_api/test_translate.py | 10 ++++-- .../test_translate_classic.py | 10 ++++-- _unittests/ut_validation/test_f8.py | 24 +++++++------- .../test_documentation_examples.py | 2 +- onnx_array_api/__init__.py | 1 - onnx_array_api/_command_lines_parser.py | 8 +++-- onnx_array_api/_helpers.py | 2 +- onnx_array_api/array_api/__init__.py | 21 +++++++------ onnx_array_api/array_api/_onnx_common.py | 14 ++++----- onnx_array_api/ext_test_case.py | 9 +++--- onnx_array_api/graph_api/graph_builder.py | 28 ++++++++++------- onnx_array_api/light_api/model.py | 3 +- onnx_array_api/light_api/var.py | 5 +-- onnx_array_api/npx/npx_array_api.py | 2 -- onnx_array_api/npx/npx_core_api.py | 4 +-- onnx_array_api/npx/npx_functions.py | 2 +- onnx_array_api/npx/npx_graph_builder.py | 13 +++----- onnx_array_api/npx/npx_helper.py | 3 +- onnx_array_api/npx/npx_jit_eager.py | 22 ++++++------- onnx_array_api/npx/npx_numpy_tensors.py | 8 ++--- onnx_array_api/npx/npx_tensors.py | 4 +-- onnx_array_api/npx/npx_types.py | 26 ++++++++-------- onnx_array_api/npx/npx_var.py | 18 +++++------ onnx_array_api/ort/ort_profile.py | 14 +++++---- onnx_array_api/ort/ort_tensors.py | 4 +-- onnx_array_api/plotting/_helper.py | 6 ++-- onnx_array_api/plotting/dot_plot.py | 2 +- onnx_array_api/plotting/text_plot.py | 14 ++++----- onnx_array_api/profiling.py | 7 ++--- onnx_array_api/reference/evaluator_yield.py | 20 +++++++----- onnx_array_api/translate_api/inner_emitter.py | 16 +++++++--- onnx_array_api/translate_api/light_emitter.py | 6 ++-- onnx_array_api/validation/f8.py | 12 +++---- pyproject.toml | 31 +++++++++++++++++-- setup.py | 1 - 41 files changed, 218 insertions(+), 183 deletions(-) diff --git a/_doc/examples/plot_benchmark_rf.py b/_doc/examples/plot_benchmark_rf.py index c844d74..c1ce486 100644 --- a/_doc/examples/plot_benchmark_rf.py +++ b/_doc/examples/plot_benchmark_rf.py @@ -40,10 +40,7 @@ def skl2onnx_convert_lightgbm(scope, operator, container): ) options = scope.get_options(operator.raw_operator) - if "split" in options: - operator.split = options["split"] - else: - operator.split = None + operator.split = options.get("split", None) convert_lightgbm(scope, operator, container) @@ -103,7 +100,7 @@ def measure_inference(fct, X, repeat, max_time=5, quantile=1): :return: number of runs, sum of the time, average, median """ times = [] - for n in range(repeat): + for _n in range(repeat): perf = time.perf_counter() fct(X) delta = time.perf_counter() - perf @@ -241,7 +238,10 @@ def measure_inference(fct, X, repeat, max_time=5, quantile=1): # onnxruntime bar.set_description(f"J={n_j} E={n_estimators} D={max_depth} predictO") r, t, mean, med = measure_inference( - lambda x: sess.run(None, {"X": x}), X, repeat=repeat, max_time=max_time + lambda x, sess=sess: sess.run(None, {"X": x}), + X, + repeat=repeat, + max_time=max_time, ) o2 = obs.copy() o2.update(dict(avg=mean, med=med, n_runs=r, ttime=t, name="ort_")) diff --git a/_doc/examples/plot_onnxruntime.py b/_doc/examples/plot_onnxruntime.py index fcace3e..0aba6ac 100644 --- a/_doc/examples/plot_onnxruntime.py +++ b/_doc/examples/plot_onnxruntime.py @@ -87,14 +87,14 @@ def loop(n=1000): x = np.random.randn(n, 2).astype(np.float32) y = np.random.randn(n, 2).astype(np.float32) - obs = measure_time(lambda: myloss(x, y)) + obs = measure_time(lambda x=x, y=y: myloss(x, y)) obs["name"] = "numpy" obs["n"] = n data.append(obs) xort = OrtTensor.from_array(x) yort = OrtTensor.from_array(y) - obs = measure_time(lambda: ort_myloss(xort, yort)) + obs = measure_time(lambda xort=xort, yort=yort: ort_myloss(xort, yort)) obs["name"] = "ort" obs["n"] = n data.append(obs) diff --git a/_unittests/ut_light_api/test_backend_export.py b/_unittests/ut_light_api/test_backend_export.py index 47ee7d9..8dd9f86 100644 --- a/_unittests/ut_light_api/test_backend_export.py +++ b/_unittests/ut_light_api/test_backend_export.py @@ -31,7 +31,6 @@ class ReferenceImplementationError(RuntimeError): "Fails, export cannot be compared." - pass class ExportWrapper: @@ -64,7 +63,8 @@ def run( expected = self.expected_sess.run(names, feeds) except (RuntimeError, AssertionError, TypeError, KeyError) as e: raise ReferenceImplementationError( - f"ReferenceImplementation fails with {onnx_simple_text_plot(self.model)}" + f"ReferenceImplementation fails with " + f"{onnx_simple_text_plot(self.model)}" f"\n--RAW--\n{self.model}" ) from e @@ -85,7 +85,7 @@ def run( new_code = "\n".join( [f"{i+1:04} {line}" for i, line in enumerate(code.split("\n"))] ) - raise AssertionError(f"ERROR {e}\n{new_code}") + raise AssertionError(f"ERROR {e}\n{new_code}") # noqa: B904 locs = { "np": numpy, @@ -154,7 +154,8 @@ def run( ): if a.tolist() != b.tolist(): raise AssertionError( - f"Text discrepancies for api {api!r} with a.dtype={a.dtype} " + f"Text discrepancies for api {api!r} " + f"with a.dtype={a.dtype} " f"and b.dtype={b.dtype}" f"\n--BASE--\n{onnx_simple_text_plot(self.model)}" f"\n--EXP[{api}]--\n{onnx_simple_text_plot(export_model)}" diff --git a/_unittests/ut_light_api/test_light_api.py b/_unittests/ut_light_api/test_light_api.py index e14896a..f936cc1 100644 --- a/_unittests/ut_light_api/test_light_api.py +++ b/_unittests/ut_light_api/test_light_api.py @@ -484,7 +484,7 @@ def g(self): def ah(self): return True - setattr(A, "h", ah) + setattr(A, "h", ah) # noqa: B010 self.assertTrue(A().h()) self.assertIn("(self)", str(inspect.signature(A.h))) diff --git a/_unittests/ut_plotting/test_dot_plot.py b/_unittests/ut_plotting/test_dot_plot.py index 5c03746..4c8c4dd 100644 --- a/_unittests/ut_plotting/test_dot_plot.py +++ b/_unittests/ut_plotting/test_dot_plot.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import unittest diff --git a/_unittests/ut_plotting/test_text_plot.py b/_unittests/ut_plotting/test_text_plot.py index 963b5cb..df0d3f5 100644 --- a/_unittests/ut_plotting/test_text_plot.py +++ b/_unittests/ut_plotting/test_text_plot.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import textwrap import unittest diff --git a/_unittests/ut_translate_api/test_translate.py b/_unittests/ut_translate_api/test_translate.py index 0212d0b..98629d8 100644 --- a/_unittests/ut_translate_api/test_translate.py +++ b/_unittests/ut_translate_api/test_translate.py @@ -160,8 +160,14 @@ def test_export_if(self): self.assertEqualArray(np.array([1], dtype=np.int64), got[0]) code = translate(onx) - selse = "g().cst(np.array([0], dtype=np.int64)).rename('Z').bring('Z').vout(elem_type=TensorProto.FLOAT)" - sthen = "g().cst(np.array([1], dtype=np.int64)).rename('Z').bring('Z').vout(elem_type=TensorProto.FLOAT)" + selse = ( + "g().cst(np.array([0], dtype=np.int64)).rename('Z')." + "bring('Z').vout(elem_type=TensorProto.FLOAT)" + ) + sthen = ( + "g().cst(np.array([1], dtype=np.int64)).rename('Z')." + "bring('Z').vout(elem_type=TensorProto.FLOAT)" + ) expected = dedent( f""" ( diff --git a/_unittests/ut_translate_api/test_translate_classic.py b/_unittests/ut_translate_api/test_translate_classic.py index c6cb412..153a7d4 100644 --- a/_unittests/ut_translate_api/test_translate_classic.py +++ b/_unittests/ut_translate_api/test_translate_classic.py @@ -221,8 +221,12 @@ def test_topk_reverse(self): sorted=1 ) ) - outputs.append(make_tensor_value_info('Values', TensorProto.FLOAT, shape=[])) - outputs.append(make_tensor_value_info('Indices', TensorProto.FLOAT, shape=[])) + outputs.append( + make_tensor_value_info('Values', TensorProto.FLOAT, shape=[]) + ) + outputs.append( + make_tensor_value_info('Indices', TensorProto.FLOAT, shape=[]) + ) graph = make_graph( nodes, 'light_api', @@ -252,7 +256,7 @@ def test_fft(self): new_code = "\n".join( [f"{i+1:04} {line}" for i, line in enumerate(code.split("\n"))] ) - raise AssertionError(f"ERROR {e}\n{new_code}") + raise AssertionError(f"ERROR {e}\n{new_code}") # noqa: B904 def test_aionnxml(self): onx = ( diff --git a/_unittests/ut_validation/test_f8.py b/_unittests/ut_validation/test_f8.py index 80611b5..4c6517f 100644 --- a/_unittests/ut_validation/test_f8.py +++ b/_unittests/ut_validation/test_f8.py @@ -88,7 +88,7 @@ def test_fe5m2_to_float32_paper(self): self.assertEqual(fe5m2_to_float32(int("11111100", 2)), -numpy.inf) def test_fe4m3fn_to_float32_all(self): - for i in range(0, 256): + for i in range(256): a = fe4m3_to_float32_float(i) b = fe4m3_to_float32(i) if numpy.isnan(a): @@ -97,7 +97,7 @@ def test_fe4m3fn_to_float32_all(self): self.assertEqual(a, b) def test_fe4m3fn_to_float32_all_ml_types(self): - for i in range(0, 256): + for i in range(256): a = fe4m3_to_float32_float(i) b = fe4m3_to_float32(i) c = new_cvt_float32_to_e4m3fn(b) @@ -188,7 +188,7 @@ def test_search_float32_into_fe5m2_simple(self): self.assertEqual(b1, b2) def test_search_float32_into_fe4m3fn_equal(self): - values = [(fe4m3_to_float32_float(i), i) for i in range(0, 256)] + values = [(fe4m3_to_float32_float(i), i) for i in range(256)] values.sort() for value, expected in values: @@ -208,7 +208,7 @@ def test_search_float32_into_fe4m3fn_equal(self): self.assertIn(nf, (0, 128)) def test_search_float32_into_fe5m2_equal(self): - values = [(fe5m2_to_float32_float(i), i) for i in range(0, 256)] + values = [(fe5m2_to_float32_float(i), i) for i in range(256)] values.sort() for value, expected in values: @@ -233,7 +233,7 @@ def test_search_float32_into_fe5m2_equal(self): self.assertEqual(fe5m2_to_float32(nf), float(cf)) def test_search_float32_into_fe4m3fn(self): - values = [(fe4m3_to_float32_float(i), i) for i in range(0, 256)] + values = [(fe4m3_to_float32_float(i), i) for i in range(256)] values.sort() obs = [] @@ -308,7 +308,7 @@ def test_search_float32_into_fe4m3fn(self): ) def test_search_float32_into_fe5m2(self): - values = [(fe5m2_to_float32_float(i), i) for i in range(0, 256)] + values = [(fe5m2_to_float32_float(i), i) for i in range(256)] values.sort() obs = [] @@ -651,7 +651,7 @@ def test_search_float32_into_fe5m2fnuz_simple(self): self.assertEqual(expected, got) def test_fe4m3fnuz_to_float32_all(self): - for i in range(0, 256): + for i in range(256): a = fe4m3_to_float32_float(i, uz=True) b = fe4m3_to_float32(i, uz=True) if numpy.isnan(a): @@ -660,7 +660,7 @@ def test_fe4m3fnuz_to_float32_all(self): self.assertEqual(a, b) def test_fe5m2fnuz_to_float32_all(self): - for i in range(0, 256): + for i in range(256): a = fe5m2_to_float32_float(i, fn=True, uz=True) b = fe5m2_to_float32(i, fn=True, uz=True) if numpy.isnan(a): @@ -669,7 +669,7 @@ def test_fe5m2fnuz_to_float32_all(self): self.assertEqual(a, b) def test_search_float32_into_fe4m3fnuz(self): - values = [(fe4m3_to_float32_float(i, uz=True), i) for i in range(0, 256)] + values = [(fe4m3_to_float32_float(i, uz=True), i) for i in range(256)] values.sort() obs = [] @@ -715,9 +715,7 @@ def test_search_float32_into_fe4m3fnuz(self): ) def test_search_float32_into_fe5m2fnuz(self): - values = [ - (fe5m2_to_float32_float(i, fn=True, uz=True), i) for i in range(0, 256) - ] + values = [(fe5m2_to_float32_float(i, fn=True, uz=True), i) for i in range(256)] values.sort() obs = [] @@ -1235,7 +1233,7 @@ def test_nan(self): expected, ) ] - for i in range(0, 23): + for i in range(23): v = 0x7F800000 | (1 << i) f = numpy.uint32(v).view(numpy.float32) values.append((i, v, f, expected)) diff --git a/_unittests/ut_xrun_doc/test_documentation_examples.py b/_unittests/ut_xrun_doc/test_documentation_examples.py index 12a36ba..6f6a5d1 100644 --- a/_unittests/ut_xrun_doc/test_documentation_examples.py +++ b/_unittests/ut_xrun_doc/test_documentation_examples.py @@ -49,7 +49,7 @@ def run_test(self, fold: str, name: str, verbose=0) -> int: if verbose: print(f"failed: {name!r} due to missing dot.") return 0 - raise AssertionError( + raise AssertionError( # noqa: B904 "Example '{}' (cmd: {} - exec_prefix='{}') " "failed due to\n{}" "".format(name, cmds, sys.exec_prefix, st) diff --git a/onnx_array_api/__init__.py b/onnx_array_api/__init__.py index c4bc456..f78126c 100644 --- a/onnx_array_api/__init__.py +++ b/onnx_array_api/__init__.py @@ -1,4 +1,3 @@ -# coding: utf-8 """ APIs to create ONNX Graphs. """ diff --git a/onnx_array_api/_command_lines_parser.py b/onnx_array_api/_command_lines_parser.py index c0a7678..e9b69a2 100644 --- a/onnx_array_api/_command_lines_parser.py +++ b/onnx_array_api/_command_lines_parser.py @@ -18,10 +18,11 @@ def get_main_parser() -> ArgumentParser: help=dedent( """ Selects a command. - + 'translate' exports an onnx graph into a piece of code replicating it, 'compare' compares the execution of two onnx models, - 'replace' replaces constant and initliazers by ConstantOfShape to make the model lighter + 'replace' replaces constant and initliazers by ConstantOfShape + to make the model lighter """ ), ) @@ -75,7 +76,8 @@ def get_parser_compare() -> ArgumentParser: Compares the execution of two onnx models. """ ), - epilog="This is used when two models are different but should produce the same results.", + epilog="This is used when two models are different but " + "should produce the same results.", ) parser.add_argument( "-m1", diff --git a/onnx_array_api/_helpers.py b/onnx_array_api/_helpers.py index f9808ca..83afc59 100644 --- a/onnx_array_api/_helpers.py +++ b/onnx_array_api/_helpers.py @@ -41,5 +41,5 @@ def np_dtype_to_tensor_dtype(dtype: Any): elif dtype is float: dt = TensorProto.DOUBLE else: - raise KeyError(f"Unable to guess type for dtype={dtype}.") + raise KeyError(f"Unable to guess type for dtype={dtype}.") # noqa: B904 return dt diff --git a/onnx_array_api/array_api/__init__.py b/onnx_array_api/array_api/__init__.py index f4b3c4d..3252405 100644 --- a/onnx_array_api/array_api/__init__.py +++ b/onnx_array_api/array_api/__init__.py @@ -51,8 +51,8 @@ def _finfo(dtype): d[k] = v d["dtype"] = DType(np_dtype_to_tensor_dtype(dt)) nres = type("finfo", (res.__class__,), d) - setattr(nres, "smallest_normal", float(res.smallest_normal)) - setattr(nres, "tiny", float(res.tiny)) + setattr(nres, "smallest_normal", float(res.smallest_normal)) # noqa: B010 + setattr(nres, "tiny", float(res.tiny)) # noqa: B010 return nres @@ -84,8 +84,8 @@ def _iinfo(dtype): d[k] = v d["dtype"] = DType(np_dtype_to_tensor_dtype(dt)) nres = type("iinfo", (res.__class__,), d) - setattr(nres, "min", int(res.min)) - setattr(nres, "max", int(res.max)) + setattr(nres, "min", int(res.min)) # noqa: B010 + setattr(nres, "max", int(res.max)) # noqa: B010 return nres @@ -133,10 +133,10 @@ def _finalize_array_api(module, function_names, TEagerTensor): module.uint32 = DType(TensorProto.UINT32) module.uint64 = DType(TensorProto.UINT64) module.bfloat16 = DType(TensorProto.BFLOAT16) - setattr(module, "bool", DType(TensorProto.BOOL)) - setattr(module, "str", DType(TensorProto.STRING)) - setattr(module, "finfo", _finfo) - setattr(module, "iinfo", _iinfo) + setattr(module, "bool", DType(TensorProto.BOOL)) # noqa: B010 + setattr(module, "str", DType(TensorProto.STRING)) # noqa: B010 + setattr(module, "finfo", _finfo) # noqa: B010 + setattr(module, "iinfo", _iinfo) # noqa: B010 if function_names is None: function_names = supported_functions @@ -146,7 +146,10 @@ def _finalize_array_api(module, function_names, TEagerTensor): if f is None: f2 = getattr(npx_functions, name, None) if f2 is None: - warnings.warn(f"Function {name!r} is not available in {module!r}.") + warnings.warn( + f"Function {name!r} is not available in {module!r}.", + stacklevel=0, + ) continue f = lambda TEagerTensor, *args, _f=f2, **kwargs: _f( # noqa: E731 *args, **kwargs diff --git a/onnx_array_api/array_api/_onnx_common.py b/onnx_array_api/array_api/_onnx_common.py index 8456378..498c296 100644 --- a/onnx_array_api/array_api/_onnx_common.py +++ b/onnx_array_api/array_api/_onnx_common.py @@ -92,13 +92,13 @@ def asarray( elif isinstance(a, str): v = TEagerTensor(np.array(a, dtype=np.str_)) elif isinstance(a, list): - if all(map(lambda x: isinstance(x, bool), a)): + if all(isinstance(x, bool) for x in a): v = TEagerTensor(np.array(a, dtype=np.bool_)) - elif all(map(lambda x: isinstance(x, int), a)): + elif all(isinstance(x, int) for x in a): try: cvt = np.array(a, dtype=np.int64) except OverflowError as e: - if all(map(lambda x: x >= 0, a)): + if all(x >= 0 for x in a): cvt = np.array(a, dtype=np.uint64) else: raise e @@ -127,9 +127,7 @@ def arange( step: EagerTensor[OptTensorType[ElemType.int64, "I", (1,)]] = None, dtype: OptParType[DType] = None, ) -> EagerTensor[TensorType[ElemType.numerics, "T"]]: - use_float = any( - map(lambda x: isinstance(x, float), [start_or_stop, stop_or_step, step]) - ) + use_float = any(isinstance(x, float) for x in [start_or_stop, stop_or_step, step]) if isinstance(start_or_stop, int): start_or_stop = TEagerTensor( np.array([start_or_stop], dtype=np.float64 if use_float else np.int64) @@ -207,7 +205,7 @@ def eye( /, *, k: ParType[int] = 0, - dtype: ParType[DType] = DType(TensorProto.DOUBLE), + dtype: ParType[DType] = DType(TensorProto.DOUBLE), # noqa: B008 ): if isinstance(n_rows, int): n_rows = TEagerTensor(np.array(n_rows, dtype=np.int64)) @@ -245,7 +243,7 @@ def linspace( dtype: OptParType[DType] = None, endpoint: ParType[int] = 1, ) -> EagerTensor[TensorType[ElemType.numerics, "T"]]: - use_float = any(map(lambda x: isinstance(x, float), [start, stop])) + use_float = any(isinstance(x, float) for x in [start, stop]) if isinstance(start, int): start = TEagerTensor( np.array(start, dtype=np.float64 if use_float else np.int64) diff --git a/onnx_array_api/ext_test_case.py b/onnx_array_api/ext_test_case.py index 3c12e65..d91ba1a 100644 --- a/onnx_array_api/ext_test_case.py +++ b/onnx_array_api/ext_test_case.py @@ -235,7 +235,7 @@ def assertRaise(self, fct: Callable, exc_type: Exception): fct() except exc_type as e: if not isinstance(e, exc_type): - raise AssertionError(f"Unexpected exception {type(e)!r}.") + raise AssertionError(f"Unexpected exception {type(e)!r}.") # noqa: B904 return raise AssertionError("No exception was raised.") @@ -266,7 +266,7 @@ def assertStartsWith(self, prefix: str, full: str): @classmethod def tearDownClass(cls): for name, line, w in cls._warns: - warnings.warn(f"\n{name}:{line}: {type(w)}\n {str(w)}") + warnings.warn(f"\n{name}:{line}: {type(w)}\n {str(w)}", stacklevel=0) def capture(self, fct: Callable): """ @@ -277,9 +277,8 @@ def capture(self, fct: Callable): """ sout = StringIO() serr = StringIO() - with redirect_stdout(sout): - with redirect_stderr(serr): - res = fct() + with redirect_stdout(sout), redirect_stderr(serr): + res = fct() return res, sout.getvalue(), serr.getvalue() def relative_path(self, filename: str, *names: List[str]) -> str: diff --git a/onnx_array_api/graph_api/graph_builder.py b/onnx_array_api/graph_api/graph_builder.py index 4f5c601..293d2cc 100644 --- a/onnx_array_api/graph_api/graph_builder.py +++ b/onnx_array_api/graph_api/graph_builder.py @@ -328,9 +328,9 @@ def has_type(self, name: str) -> bool: return name in self._known_types def get_type(self, name: str) -> int: - assert name in self._known_types, ( - f"Type is unknown for result {name!r}, " f"known_types={self._known_types}." - ) + assert ( + name in self._known_types + ), f"Type is unknown for result {name!r}, known_types={self._known_types}." return self._known_types[name] def unique_name(self, prefix: str) -> str: @@ -472,7 +472,7 @@ def make_node( f"A node {op_type!r} cannot be created with " f"inputs={inputs} (types={[type(i) for i in inputs]}), " f"outputs={outputs} " - f"(types={[type(o) for o in outputs] if isinstance(outputs, (tuple, list)) else outputs}), " + f"(types={[type(o) for o in outputs] if isinstance(outputs, (tuple, list)) else outputs}), " # noqa: E501 f"domain={domain!r}, kwargs={kwargs}." ) from e if attributes: @@ -594,14 +594,16 @@ def make_nodes( return output_names[0] return output_names - def from_array(self, arr: T, name: str = None) -> TensorProto: # noqa: F821 + def from_array( + self, arr: T, name: Optional[str] = None + ) -> TensorProto: # noqa: F821 if isinstance(arr, np.ndarray): return self.from_np_array(arr, name) raise NotImplementedError( f"{type(arr)} is not supported yet but initializer {name or ''!r} is." ) - def from_np_array(self, arr: np.ndarray, name: str = None) -> TensorProto: + def from_np_array(self, arr: np.ndarray, name: Optional[str] = None) -> TensorProto: arr_cpu = np.ascontiguousarray(arr) if not arr.flags["C_CONTIGUOUS"] else arr if arr_cpu.ctypes.data == arr.ctypes.data: if sys.byteorder == "big": @@ -816,7 +818,7 @@ def constant_folding(self): """ updates = {} node_to_remove = set() - for k, v in self.constants_.items(): + for _k, v in self.constants_.items(): if v is None: # this is an initiliazer continue @@ -837,7 +839,8 @@ def constant_folding(self): self.initializers_dict[name] = value if self.verbose: print( - f"[GraphBuilder] fold_constant:{v.op_type}:{name}[{value.dtype}:" + f"[GraphBuilder] fold_constant:" + f"{v.op_type}:{name}[{value.dtype}:" f"{value.shape}]:from:{','.join(sorted(feeds))}" ) @@ -880,7 +883,8 @@ def remove_identity_nodes(self): if new_name in replacements: new_name = replacements[new_name] assert new_name not in replacements, ( - f"Name {old_name!r} still in {replacements}, node.op_type={node.op_type!r}, " + f"Name {old_name!r} still in {replacements}, " + f"node.op_type={node.op_type!r}, " f"node.input={node.input}, node.output={node.output}, " f"input_names={input_names}, output_names={output_names}" ) @@ -891,7 +895,8 @@ def remove_identity_nodes(self): if old_name in replacements: replacements[replacements[old_name]] = new_name assert new_name not in replacements, ( - f"Name {old_name!r} still in {replacements}, node.op_type={node.op_type!r}, " + f"Name {old_name!r} still in {replacements}, " + f"node.op_type={node.op_type!r}, " f"node.input={node.input}, node.output={node.output}, " f"input_names={input_names}, output_names={output_names}" ) @@ -902,7 +907,8 @@ def remove_identity_nodes(self): for k, v in replacements.items(): assert v not in replacements, ( f"replacement {k}->{v} is not possible because of " - f"{v}->{replacements[v]}, old_name={old_name!r}, new_name={new_name!r}" + f"{v}->{replacements[v]}, old_name={old_name!r}, " + f"new_name={new_name!r}" ) # second pass: replacements in initializer diff --git a/onnx_array_api/light_api/model.py b/onnx_array_api/light_api/model.py index 6478c4d..f6770eb 100644 --- a/onnx_array_api/light_api/model.py +++ b/onnx_array_api/light_api/model.py @@ -319,7 +319,8 @@ def rename(self, old_name: str, new_name: str): value = self.unique_names_[old_name] if isinstance(value, int): raise TypeError( - f"Unexpected type {type(value)} for value {old_name!r} renamed into {new_name!r}." + f"Unexpected type {type(value)} for value {old_name!r} " + f"renamed into {new_name!r}." ) self.unique_names_[new_name] = value self.renames_[old_name] = new_name diff --git a/onnx_array_api/light_api/var.py b/onnx_array_api/light_api/var.py index 2d7eac8..72a9533 100644 --- a/onnx_array_api/light_api/var.py +++ b/onnx_array_api/light_api/var.py @@ -193,7 +193,7 @@ def make_node( ) if len(names) == 1: return Var(self.parent, names[0]) - return Vars(self.parent, *list(map(lambda v: Var(self.parent, v), names))) + return Vars(self.parent, *[Var(self.parent, v) for v in names]) def vin( self, @@ -445,7 +445,8 @@ def rename(self, *new_names: List[str]) -> "Vars": "Renames variables." if len(new_names) != len(self): raise ValueError( - f"Vars has {len(self)} elements but the method received {len(new_names)} names." + f"Vars has {len(self)} elements but the method " + f"received {len(new_names)} names." ) new_vars = [] for var, name in zip(self.vars_, new_names): diff --git a/onnx_array_api/npx/npx_array_api.py b/onnx_array_api/npx/npx_array_api.py index 142a892..a9fb3d6 100644 --- a/onnx_array_api/npx/npx_array_api.py +++ b/onnx_array_api/npx/npx_array_api.py @@ -10,8 +10,6 @@ class ArrayApiError(RuntimeError): Raised when a function is not supported by the :epkg:`Array API`. """ - pass - class BaseArrayApi: """ diff --git a/onnx_array_api/npx/npx_core_api.py b/onnx_array_api/npx/npx_core_api.py index d6688cf..a09280a 100644 --- a/onnx_array_api/npx/npx_core_api.py +++ b/onnx_array_api/npx/npx_core_api.py @@ -15,7 +15,7 @@ class args_tuple(tuple): """Overwrites a tuple to make the distinction later in the code.""" - pass + __slots__ = () def cst(*args, **kwargs): @@ -140,7 +140,7 @@ def _xapi(fn: Callable, inline: bool): # It has the same signature def wrapper(*inputs, **kwargs): - if any(map(lambda x: isinstance(x, EagerTensor), inputs)): + if any(isinstance(x, EagerTensor) for x in inputs): tensor_class = None for x in inputs: if isinstance(x, EagerTensor): diff --git a/onnx_array_api/npx/npx_functions.py b/onnx_array_api/npx/npx_functions.py index 7c6cd66..c6319f2 100644 --- a/onnx_array_api/npx/npx_functions.py +++ b/onnx_array_api/npx/npx_functions.py @@ -480,7 +480,7 @@ def eye( /, *, k: ParType[int] = 0, - dtype: ParType[DType] = DType(TensorProto.DOUBLE), + dtype: ParType[DType] = DType(TensorProto.DOUBLE), # noqa: B008 ): "See :func:`numpy.eye`." shape = cst(np.array([-1], dtype=np.int64)) diff --git a/onnx_array_api/npx/npx_graph_builder.py b/onnx_array_api/npx/npx_graph_builder.py index 4496d79..91034f7 100644 --- a/onnx_array_api/npx/npx_graph_builder.py +++ b/onnx_array_api/npx/npx_graph_builder.py @@ -450,7 +450,7 @@ def _make_onnx(self): name = inp.name if name is None: raise RuntimeError( - f"Input {i} is None for function " f"{self.function_name!r}." + f"Input {i} is None for function {self.function_name!r}." ) inputs.append(name) @@ -473,7 +473,7 @@ def _make_onnx(self): model = make_model( graph, opset_imports=opset_imports, - functions=list(f[0] for f in self.functions_.values()), + functions=[f[0] for f in self.functions_.values()], ir_version=self.ir_version, ) if not is_windows() or not is_azure(): @@ -512,12 +512,7 @@ def _function_to_onnx(self, fct: Callable, n_inputs: int, n_outputs: int): there is an undefined number of inputs """ sig = signature(fct) - if any( - map( - lambda t: issubclass(t.annotation, SequenceType), - sig.parameters.values(), - ) - ): + if any(issubclass(t.annotation, SequenceType) for t in sig.parameters.values()): # onnx does not allow undefined number of inputs key = fct.__module__, fct.__name__, n_inputs else: @@ -852,7 +847,7 @@ def to_onnx( node_inputs.append(input_name) continue - if isinstance(i, tuple) and all(map(lambda x: isinstance(x, int), i)): + if isinstance(i, tuple) and all(isinstance(x, int) for x in i): ai = np.array(list(i), dtype=np.int64) c = Cst(ai) input_name = self._unique(var._prefix) diff --git a/onnx_array_api/npx/npx_helper.py b/onnx_array_api/npx/npx_helper.py index 34d9af3..b2c6b48 100644 --- a/onnx_array_api/npx/npx_helper.py +++ b/onnx_array_api/npx/npx_helper.py @@ -130,8 +130,7 @@ def iter_nodes(nodes: Sequence[NodeProto]) -> Iterator[NodeProto]: and hasattr(att, "g") and att.g is not None ): - for n in iter_nodes(att.g.node): - yield n + yield from iter_nodes(att.g.node) def onnx_model_to_function( diff --git a/onnx_array_api/npx/npx_jit_eager.py b/onnx_array_api/npx/npx_jit_eager.py index 20becbd..172bb86 100644 --- a/onnx_array_api/npx/npx_jit_eager.py +++ b/onnx_array_api/npx/npx_jit_eager.py @@ -563,7 +563,7 @@ class JitOnnx(JitEager): def __init__( self, f: Callable, - tensor_class: type = None, + tensor_class: Optional[type] = None, target_opsets: Optional[Dict[str, int]] = None, output_types: Optional[Dict[Any, TensorType]] = None, ir_version: Optional[int] = None, @@ -636,7 +636,7 @@ class EagerOnnx(JitEager): def __init__( self, f: Callable, - tensor_class: type = None, + tensor_class: Optional[type] = None, target_opsets: Optional[Dict[str, int]] = None, output_types: Optional[Dict[Any, TensorType]] = None, ir_version: Optional[int] = None, @@ -671,12 +671,12 @@ def _preprocess_constants(self, *args): new_args.append(self.tensor_class(n.inputs[0])) modified = True elif isinstance(n, tuple): - if all(map(lambda x: isinstance(x, int), n)): + if all(isinstance(x, int) for x in n): new_args.append( self.tensor_class(np.array(list(n), dtype=np.int64)) ) modified = True - elif any(map(lambda t: isinstance(t, Var), n)): + elif any(isinstance(t, Var) for t in n): raise TypeError( f"Unexpected types in tuple " f"({[type(t) for t in n]}) for input {i}, " @@ -727,14 +727,14 @@ def __call__(self, *args, already_eager=False, **kwargs): ) if already_eager: if any( - map( - lambda t: t is not None + ( + t is not None and not isinstance( t, EagerOnnx.allowed_input_types, - ), - args, + ) ) + for t in args ): raise TypeError( f"One of the input is not an EagerTensor or a constant, " @@ -759,8 +759,8 @@ def __call__(self, *args, already_eager=False, **kwargs): try: res = self.f(*values, **kwargs) except (AttributeError, TypeError) as e: - inp1 = ", ".join(map(str, map(lambda a: type(a).__name__, args))) - inp2 = ", ".join(map(str, map(lambda a: type(a).__name__, values))) + inp1 = ", ".join(map(str, [type(a).__name__ for a in args])) + inp2 = ", ".join(map(str, [type(a).__name__ for a in values])) raise TypeError( f"Unexpected types, input types are args=[{inp1}], " f"values=[{inp2}], kwargs={kwargs}. " @@ -778,7 +778,7 @@ def __call__(self, *args, already_eager=False, **kwargs): f"from module {self.f.__module__!r}, " f"type of first input is {type(args[0])}." ) - elif isinstance(res, Var) or any(map(lambda x: isinstance(x, Var), res)): + elif isinstance(res, Var) or any(isinstance(x, Var) for x in res): # The function returns instance of type Var. # It does not support eager mode and needs # to be converted into onnx. diff --git a/onnx_array_api/npx/npx_numpy_tensors.py b/onnx_array_api/npx/npx_numpy_tensors.py index 68a4da7..1daef44 100644 --- a/onnx_array_api/npx/npx_numpy_tensors.py +++ b/onnx_array_api/npx/npx_numpy_tensors.py @@ -223,7 +223,8 @@ def __bool__(self): if self.shape: warnings.warn( f"Conversion to bool only works for scalar, not for {self!r}, " - f"bool(...)={bool(self._tensor)}." + f"bool(...)={bool(self._tensor)}.", + stacklevel=0, ) try: return bool(self._tensor) @@ -279,7 +280,8 @@ def __iter__(self): warnings.warn( f"Iterators are not implemented in the generic case. " f"Every function using them cannot be converted into ONNX " - f"(tensors - {type(self)})." + f"(tensors - {type(self)}).", + stacklevel=0, ) for row in self._tensor: yield self.__class__(row) @@ -289,5 +291,3 @@ class JitNumpyTensor(NumpyTensor, JitTensor): """ Defines a value for a specific backend. """ - - pass diff --git a/onnx_array_api/npx/npx_tensors.py b/onnx_array_api/npx/npx_tensors.py index 3e4faa7..40ebc12 100644 --- a/onnx_array_api/npx/npx_tensors.py +++ b/onnx_array_api/npx/npx_tensors.py @@ -10,8 +10,6 @@ class JitTensor: Defines a value for a specific jit mode """ - pass - class EagerTensor(BaseArrayApi): """ @@ -93,7 +91,7 @@ def _astype_impl( if not isinstance(x, Var): raise TypeError(f"Input 0 must be a Var not {type(x)}.") - meth = getattr(Var, "astype") + meth = getattr(Var, "astype") # noqa: B009 return meth(x, dtype) @staticmethod diff --git a/onnx_array_api/npx/npx_types.py b/onnx_array_api/npx/npx_types.py index 8284765..2f2a6a6 100644 --- a/onnx_array_api/npx/npx_types.py +++ b/onnx_array_api/npx/npx_types.py @@ -11,7 +11,7 @@ class WrapperType: WrapperType. """ - pass + __slots__ = () class DType(WrapperType): @@ -78,8 +78,8 @@ def __eq__(self, dt: "DType") -> bool: return self.code_ == dt.dtype.code_ try: dti = np_dtype_to_tensor_dtype(dt) - except KeyError: - raise TypeError(f"dt must be DType not {type(dt)} - {dt!r}.") + except KeyError as e: + raise TypeError(f"dt must be DType not {type(dt)} - {dt!r}.") from e return self.code_ == dti def __lt__(self, dt: "DType") -> bool: @@ -90,8 +90,8 @@ def __lt__(self, dt: "DType") -> bool: raise TypeError(f"dt must be DType not {type(dt)}.") try: dti = np_dtype_to_tensor_dtype(dt) - except KeyError: - raise TypeError(f"dt must be DType not {type(dt)} - {dt}.") + except KeyError as e: + raise TypeError(f"dt must be DType not {type(dt)} - {dt}.") from e return self.code_ < dti @classmethod @@ -102,12 +102,10 @@ def type_name(cls) -> str: class _DType2(DType): "Wraps a type into a different type." - pass class _DTypes(DType): "Wraps a type into a different type." - pass class ElemTypeCstInner(WrapperType): @@ -367,7 +365,7 @@ def onnx_type(cls): if cls.dtype == str: return AttributeProto.STRING raise RuntimeError( - f"Unsupported attribute type {cls.dtype!r} " f"for parameter {cls!r}." + f"Unsupported attribute type {cls.dtype!r} for parameter {cls!r}." ) @@ -403,9 +401,11 @@ class ShapeType(Tuple[int, ...]): Defines a shape type. """ + __slots__ = () + @classmethod def __class_getitem__(cls, *args): - if any(map(lambda t: t is not None and not isinstance(t, (int, str)), args)): + if any((t is not None and not isinstance(t, (int, str))) for t in args): raise TypeError( f"Unexpected value for args={args}, every element should int or str." ) @@ -504,7 +504,7 @@ def __class_getitem__(cls, *args): if name: msg.append(name) if dtypes is not None: - msg.append("_".join(map(lambda t: str(t.dtype), dtypes))) + msg.append("_".join(str(t.dtype) for t in dtypes)) if shape is not None: msg.append("_".join(map(str, shape))) final = "__".join(msg) @@ -561,11 +561,11 @@ def _name_set(self): s += 1 << dt.dtype try: return ElemType.set_names[s] - except KeyError: + except KeyError as e: raise RuntimeError( f"Unable to guess element type name for {s}: " f"{repr(self)} in {ElemType.set_names}." - ) + ) from e @classmethod def issuperset(cls, tensor_type: type) -> bool: @@ -686,7 +686,7 @@ def len(cls): @classmethod def type_name(cls) -> str: "Returns its full name." - dts = ", ".join(map(lambda s: s.type_name(), cls.elem_types)) + dts = ", ".join(s.type_name() for s in cls.elem_types) if cls.name: newt = f"TupleType[{dts}, {cls.name!r}]" else: diff --git a/onnx_array_api/npx/npx_var.py b/onnx_array_api/npx/npx_var.py index ca8af0d..169183c 100644 --- a/onnx_array_api/npx/npx_var.py +++ b/onnx_array_api/npx/npx_var.py @@ -33,7 +33,7 @@ def __init__( ): if not issubclass(dtype, ParType): raise TypeError( - f"dtype for parameter {name!r} must be of " f"ParType not {dtype}." + f"dtype for parameter {name!r} must be of ParType not {dtype}." ) if parent_op is None: raise ValueError(f"parent_op must be filled for paramenter {name!r}.") @@ -453,7 +453,7 @@ def _get_vars(self): deleted.append(var) continue raise TypeError( - f"Unexpected type {type(applied)} as output of " f"function {fct}." + f"Unexpected type {type(applied)} as output of function {fct}." ) vs.append(var) for i in reversed(var.inputs): @@ -469,11 +469,11 @@ def _get_vars(self): replacement_cst[id(i)] = cst(np.array(i)) continue if isinstance(i, tuple): - if all(map(lambda x: isinstance(x, int), i)): + if all(isinstance(x, int) for x in i): cst = Var.get_cst_var()[0] replacement_cst[id(i)] = cst(np.array(list(i), dtype=np.int64)) continue - if any(map(lambda t: isinstance(t, Var), i)): + if any(isinstance(t, Var) for t in i): raise TypeError( f"Unexpected types in tuple " f"({[type(t) for t in i]}), " @@ -1138,7 +1138,7 @@ class Input(Var): :param annotation: annotation if any is available """ - def __init__(self, name: str = None, annotation: Optional[type] = None): + def __init__(self, name: Optional[str] = None, annotation: Optional[type] = None): Var.__init__(self) self.name = name self._prefix = name or "I" @@ -1172,15 +1172,15 @@ def __init__(self, cst: Any): elif isinstance(cst, float): Var.__init__(self, np.array(cst, dtype=np.float64), op="Identity") elif isinstance(cst, list): - if all(map(lambda t: isinstance(t, bool), cst)): + if all(isinstance(t, bool) for t in cst): Var.__init__(self, np.array(cst, dtype=np.bool_), op="Identity") - elif all(map(lambda t: isinstance(t, (int, bool)), cst)): + elif all(isinstance(t, (int, bool)) for t in cst): Var.__init__(self, np.array(cst, dtype=np.int64), op="Identity") - elif all(map(lambda t: isinstance(t, (float, int, bool)), cst)): + elif all(isinstance(t, (float, int, bool)) for t in cst): Var.__init__(self, np.array(cst, dtype=np.float64), op="Identity") else: raise ValueError( - f"Unable to convert cst (type={type(cst)}), " f"value={cst}." + f"Unable to convert cst (type={type(cst)}), value={cst}." ) else: raise NotImplementedError( diff --git a/onnx_array_api/ort/ort_profile.py b/onnx_array_api/ort/ort_profile.py index b61df67..181a696 100644 --- a/onnx_array_api/ort/ort_profile.py +++ b/onnx_array_api/ort/ort_profile.py @@ -52,7 +52,7 @@ def sep_event(s): for c in agg_cols: df[c] = df[c].fillna("") df["dur"] = df["dur"].fillna(0) - agg = df[agg_cols + ["dur"]].groupby(agg_cols).sum() + agg = df[[*agg_cols, "dur"]].groupby(agg_cols).sum() return agg @@ -101,14 +101,14 @@ def ort_profile( if providers is None: providers = ["CPUExecutionProvider"] sess = InferenceSession(obj, sess_options, providers=providers, **kwargs) - first = list(feeds.values())[0] + first = next(feeds.values()) if isinstance(first, numpy.ndarray): - for i in range(repeat): + for _i in range(repeat): sess.run(None, feeds) else: out_names = [o.name for o in sess.get_outputs()] - for i in range(repeat): + for _i in range(repeat): sess._sess.run_with_ort_values(feeds, out_names, None) prof = sess.end_profiling() @@ -177,7 +177,7 @@ def _idx(row): df[c] = df[c].apply(str) df = df.copy() df["count"] = 1 - gr = df[groupkey + ["dur", "count"]].groupby(groupkey) + gr = df[[*groupkey, "dur", "count"]].groupby(groupkey) return gr.sum() @@ -187,7 +187,9 @@ def _process_shape(s: Tuple[int, ...], keys: Dict[str, str]) -> str: for v in value: if len(v) != 1: raise NotImplementedError(f"Unexpected value {v} in {s!r}.") - k, v = list(v.items())[0] + for _k, _v in v.items(): + k, v = _k, _v + break n = "-".join([keys[k], "x".join(map(str, v))]) ns.append(n) return ",".join(ns) diff --git a/onnx_array_api/ort/ort_tensors.py b/onnx_array_api/ort/ort_tensors.py index 2117e3f..4f53e6e 100644 --- a/onnx_array_api/ort/ort_tensors.py +++ b/onnx_array_api/ort/ort_tensors.py @@ -86,7 +86,7 @@ def __init__( tensor_class: type, input_names: List[str], onx: ModelProto, - f: Callable = None, + f: Optional[Callable] = None, ): try: self.ref = InferenceSession( @@ -282,5 +282,3 @@ class JitOrtTensor(OrtTensor, OrtCommon, JitTensor): """ Defines a value for :epkg:`onnxruntime` as a backend. """ - - pass diff --git a/onnx_array_api/plotting/_helper.py b/onnx_array_api/plotting/_helper.py index 3131177..5c5d881 100644 --- a/onnx_array_api/plotting/_helper.py +++ b/onnx_array_api/plotting/_helper.py @@ -94,7 +94,7 @@ def _extract_attribute_value( f"Unable to convert attribute {att.name!r} type {att.type!r}." ) raise AttributeError( # pragma: no cover - f"Unable to convert default value for {ref_att.name!r} " f"type {att.type!r}." + f"Unable to convert default value for {ref_att.name!r} type {att.type!r}." ) @@ -120,7 +120,7 @@ def get_tensor_shape(obj): for d in obj.tensor_type.shape.dim: v = d.dim_value if d.dim_value > 0 else d.dim_param shape.append(v) - shape = None if not shape else list(None if s == 0 else s for s in shape) + shape = None if not shape else [None if s == 0 else s for s in shape] return shape @@ -183,7 +183,7 @@ def _get_shape(obj): arr = to_array(obj) return arr.shape raise RuntimeError( # pragma: no cover - f"Unable to guess type from {obj0!r}, " f"data_type is {obj.data_type!r}." + f"Unable to guess type from {obj0!r}, data_type is {obj.data_type!r}." ) if hasattr(obj, "type"): obj = obj.type diff --git a/onnx_array_api/plotting/dot_plot.py b/onnx_array_api/plotting/dot_plot.py index 5bfba5d..af8ad22 100644 --- a/onnx_array_api/plotting/dot_plot.py +++ b/onnx_array_api/plotting/dot_plot.py @@ -310,7 +310,7 @@ def dot_label(text): exp.append(f' label="{node.op_type}\\n({dot_name(field)}){satts}";') exp.append(f" fontsize={fontsize};") exp.append(" color=black;") - exp.append("\n".join(map(lambda s: " " + s, subgraph.split("\n")))) + exp.append("\n".join(f" {s}" for s in subgraph.split("\n"))) node0 = body.node[0] connects.append( diff --git a/onnx_array_api/plotting/text_plot.py b/onnx_array_api/plotting/text_plot.py index 9449acb..d3f27c6 100644 --- a/onnx_array_api/plotting/text_plot.py +++ b/onnx_array_api/plotting/text_plot.py @@ -85,10 +85,8 @@ def process_node(self): ) else: ts = " ".join( - map( - lambda t: f"{t['target_id']}:{_number2str(t['weight'])}", - self.targets, - ) + f"{t['target_id']}:{_number2str(t['weight'])}" + for t in self.targets ) text = f"{self.true_false}f {ts}" else: @@ -351,7 +349,7 @@ def __init__(self, nodes): def _find_sequence(node_name, known, done): inputs = dnodes[node_name].input - if any(map(lambda i: i not in known, inputs)): + if any((i not in known) for i in inputs): return [] res = [node_name] @@ -362,7 +360,7 @@ def _find_sequence(node_name, known, done): if len(next_names) == 1: next_name = next_names.pop() inputs = dnodes[next_name].input - if any(map(lambda i: i not in known, inputs)): + if any((i not in known) for i in inputs): break res.extend(next_name) else: @@ -390,7 +388,7 @@ def _find_sequence(node_name, known, done): possibles[k] = v sequences = OrderedDict() - for k, v in possibles.items(): + for k, _v in possibles.items(): if k in done: continue sequences[k] = _find_sequence(k, known, done) @@ -941,7 +939,7 @@ def str_node(indent, node): rows.append(str_node(indent if use_indentation else 0, node)) indents[name] = indent - for i, o in enumerate(node.output): + for _i, o in enumerate(node.output): indents[o] = indent + 1 previous_indent = indents[name] diff --git a/onnx_array_api/profiling.py b/onnx_array_api/profiling.py index 52c464a..815f950 100644 --- a/onnx_array_api/profiling.py +++ b/onnx_array_api/profiling.py @@ -247,8 +247,7 @@ def depth_first(node, roots_keys, indent=0): else: if filter_node is not None and not filter_node(n): continue - for t in depth_first(n, roots_keys, indent + 1): - yield t + yield from depth_first(n, roots_keys, indent + 1) if filter_node is None: filter_node = ProfileNode.filter_node_ @@ -472,7 +471,7 @@ def add_rows(rows, d): def profile2df( ps: Stats, as_df: bool = True, - clean_text: bool = None, + clean_text: Optional[bool] = None, verbose: bool = False, fLOG=None, ): @@ -740,7 +739,7 @@ def fct4(): node.add_called_by(child) child.add_calls_to(node, vv) - for k, v in nodes.items(): + for _k, v in nodes.items(): root = v.get_root() break diff --git a/onnx_array_api/reference/evaluator_yield.py b/onnx_array_api/reference/evaluator_yield.py index 6d6ff48..9c3b6ec 100644 --- a/onnx_array_api/reference/evaluator_yield.py +++ b/onnx_array_api/reference/evaluator_yield.py @@ -190,7 +190,8 @@ def enumerate_results( for i in node.input: if i not in results: raise RuntimeError( - f"Unable to find input {i!r} in known results {sorted(results)}, " + f"Unable to find input {i!r} " + f"in known results {sorted(results)}, " f"self.rt_inits_ has {sorted(self.evaluator.rt_inits_)}, " f"feed_inputs has {sorted(feed_inputs)}." ) @@ -222,7 +223,8 @@ def enumerate_results( for name in output_names: if name not in results: raise RuntimeError( - f"Unable to find output name {name!r} in {sorted(results)}, proto is\n{self.proto_}" + f"Unable to find output name {name!r} in {sorted(results)}, " + f"proto is\n{self.proto_}" ) yield ResultType.OUTPUT, name, results[name], None @@ -325,9 +327,7 @@ def _cost_type(self, t1: "np.dtype", t2: "np.dtype") -> float: def _cost_shape(self, s1: Tuple[int, ...], s2: Tuple[int, ...]) -> float: if s1 is None or s2 is None: return self.rank_cost - if any(map(lambda s: isinstance(s, str), s1)) or any( - map(lambda s: isinstance(s, str), s2) - ): + if any(isinstance(s, str) for s in s1) or any(isinstance(s, str) for s in s2): # dynamic shapes if len(s1) != len(s2): return self.rank_cost @@ -428,7 +428,10 @@ def to_str( d2 = s2[j] d = self.distance_pair(d1, d2) symbol = "=" if d == 0 else "~" - line = f"{symbol} | {_align(str(d1), column_size)} | {_align(str(d2), column_size)}" + line = ( + f"{symbol} | {_align(str(d1), column_size)} | " + f"{_align(str(d2), column_size)}" + ) if ( d1.value is not None and d2.value is not None @@ -457,7 +460,7 @@ def generate_input(info: ValueInfoProto) -> np.ndarray: """ elem_type = info.type.tensor_type.elem_type shape = [ - (getattr(d, "dim_value", None) or getattr(d, "dim_param")) + (getattr(d, "dim_value", None) or getattr(d, "dim_param")) # noqa: B009 for d in info.type.tensor_type.shape.dim ] new_shape = [] @@ -602,7 +605,8 @@ def compare_onnx_execution( :param mode: the model should be executed but the function can be executed but the comparison may append on nodes only :param keep_tensor: keeps the tensor in order to compute a precise distance - :return: four results, a sequence of results for the first model and the second model, + :return: four results, a sequence of results + for the first model and the second model, the alignment between the two, DistanceExecution """ assert mode in {"execute", "nodes"}, f"Unexpected value for mode={mode!r}." diff --git a/onnx_array_api/translate_api/inner_emitter.py b/onnx_array_api/translate_api/inner_emitter.py index 50d4f5e..abdf04a 100644 --- a/onnx_array_api/translate_api/inner_emitter.py +++ b/onnx_array_api/translate_api/inner_emitter.py @@ -38,7 +38,10 @@ def _make_attribute( raise NotImplementedError( f"Cannot create attribute with name={name!r}, attr_type={attr_type}." ) - return f"make_ref_attribute(key={name!r}, attr_type={attr_type}, ref_attr_name={ref_attr_name!r})" + return ( + f"make_ref_attribute(key={name!r}, attr_type={attr_type}, " + f"ref_attr_name={ref_attr_name!r})" + ) def join(self, rows: List[str], single_line: bool = False) -> str: "Returns the separators. `single_line` is unused." @@ -118,14 +121,17 @@ def _emit_io(self, container: str, **kwargs: Dict[str, Any]) -> List[str]: shape = kwargs.get("shape", None) if elem_type and shape: return [ - f"{container}.append(make_tensor_value_info({name!r}, TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, shape={shape!r}))" + f"{container}.append(make_tensor_value_info({name!r}, " + f"TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, shape={shape!r}))" ] if elem_type: return [ - f"{container}.append(make_tensor_value_info({name!r}, TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, shape=[]))" + f"{container}.append(make_tensor_value_info({name!r}, " + f"TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, shape=[]))" ] return [ - f"{container}.append(make_tensor_value_info({name!r}, TensorProto.UNDEFINED, []))" + f"{container}.append(make_tensor_value_info({name!r}, " + f"TensorProto.UNDEFINED, []))" ] def _emit_input(self, **kwargs: Dict[str, Any]) -> List[str]: @@ -184,7 +190,7 @@ def _emit_function_output(self, **kwargs: Dict[str, Any]) -> List[str]: def _emit_function_attributes(self, **kwargs: Dict[str, Any]) -> List[str]: atts = kwargs["attributes"] - if isinstance(atts, list) and all(map(lambda t: isinstance(t, str), atts)): + if isinstance(atts, list) and all(isinstance(t, str) for t in atts): return [f"atts.extend({atts!r})"] raise NotImplementedError(f"Unable to process function attributes {atts!r}.") diff --git a/onnx_array_api/translate_api/light_emitter.py b/onnx_array_api/translate_api/light_emitter.py index 7a7aef9..9c58830 100644 --- a/onnx_array_api/translate_api/light_emitter.py +++ b/onnx_array_api/translate_api/light_emitter.py @@ -54,7 +54,8 @@ def _emit_input(self, **kwargs: Dict[str, Any]) -> List[str]: shape = kwargs.get("shape", None) if elem_type and shape: return [ - f"vin({name!r}, elem_type=TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, shape={shape!r})" + f"vin({name!r}, elem_type=TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, " + f"shape={shape!r})" ] if elem_type: return [ @@ -71,7 +72,8 @@ def _emit_output(self, **kwargs: Dict[str, Any]) -> List[str]: shape = kwargs.get("shape", None) if elem_type and shape: inst.append( - f"vout(elem_type=TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, shape={shape!r})" + f"vout(elem_type=TensorProto.{ELEMENT_TYPE_NAME[elem_type]}, " + f"shape={shape!r})" ) elif elem_type: inst.append(f"vout(elem_type=TensorProto.{ELEMENT_TYPE_NAME[elem_type]})") diff --git a/onnx_array_api/validation/f8.py b/onnx_array_api/validation/f8.py index ecd68f8..13b778d 100644 --- a/onnx_array_api/validation/f8.py +++ b/onnx_array_api/validation/f8.py @@ -9,8 +9,6 @@ class UndefinedCastError(FloatingPointError): Unable to case a number. """ - pass - def display_int(ival, sign=1, exponent=8, mantissa=23): """ @@ -317,25 +315,23 @@ def fe5m2_to_float32(ival: int, fn: bool = False, uz: bool = False) -> float: class CastFloat8Sets: values_e4m3fn = list( sorted( - (fe4m3_to_float32_float(i), i) for i in range(0, 256) if i not in (255, 127) + (fe4m3_to_float32_float(i), i) for i in range(256) if i not in (255, 127) ) ) values_e4m3fnuz = list( - sorted( - (fe4m3_to_float32_float(i, uz=True), i) for i in range(0, 256) if i != 0x80 - ) + sorted((fe4m3_to_float32_float(i, uz=True), i) for i in range(256) if i != 0x80) ) values_e5m2 = list( sorted( (fe5m2_to_float32_float(i), i) - for i in range(0, 256) + for i in range(256) if i not in {253, 254, 255, 125, 126, 127} ) ) values_e5m2fnuz = list( sorted( (fe5m2_to_float32_float(i, fn=True, uz=True), i) - for i in range(0, 256) + for i in range(256) if i != 0x80 ) ) diff --git a/pyproject.toml b/pyproject.toml index 525b648..8ae8a76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,11 +11,36 @@ exclude = [ # Same as Black. line-length = 88 -[tool.ruff.lint.mccabe] -# Unlike Flake8, default to a complexity level of 10. -max-complexity = 10 +[tool.ruff.lint] +select = [ + "B", # flake8-bugbear + "C4", # flake8-comprehensions + #"D", # pydocstyle + "E", # pycodestyle + "F", # Pyflakes + "G", # flake8-logging-format + #"I", # isort + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + #"N", # pep8-naming + #"NPY", # modern numpy + #"PERF", # Perflint + "PIE", # flake8-pie + "PYI", # flake8-pyi + "RUF", # Ruff-specific rules + "SIM", # flake8-simplify + "SLOT", # flake8-slot + "T10", # flake8-debugger + #"TID", # Disallow relative imports + #"TRY", # flake8-try-except-raise + "UP", # pyupgrade + "W", # pycodestyle + "YTT", # flake8-2020 +] [tool.ruff.lint.per-file-ignores] +"**" = ["B905", "C401", "C408", "C413", "PYI041", "RUF012", "RUF100", "RUF010", "SIM108", "SIM910", "SIM110", "SIM102", "SIM114", "SIM103", "UP015", "UP027", "UP031", "UP034", "UP032", "UP006", "UP035", "UP007", "UP038"] +"**/plot*.py" = ["B018"] "_doc/examples/plot_first_example.py" = ["E402", "F811"] "_doc/examples/plot_onnxruntime.py" = ["E402", "F811"] "onnx_array_api/array_api/_onnx_common.py" = ["F821"] diff --git a/setup.py b/setup.py index bc4e87e..69b5b9e 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os from setuptools import setup From 6a70ac59ba0c533fc86905ba7724550d0757d030 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Fri, 30 Aug 2024 14:16:06 +0200 Subject: [PATCH 3/8] exc --- onnx_array_api/_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnx_array_api/_helpers.py b/onnx_array_api/_helpers.py index 83afc59..1d95bb2 100644 --- a/onnx_array_api/_helpers.py +++ b/onnx_array_api/_helpers.py @@ -9,7 +9,7 @@ def np_dtype_to_tensor_dtype(dtype: Any): """ try: dt = helper.np_dtype_to_tensor_dtype(dtype) - except KeyError: + except (KeyError, ValueError): if dtype == np.float32: dt = TensorProto.FLOAT elif dtype == np.float64: From 202562c0a03128e1e7234234ae31cf1fa67bc627 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Fri, 30 Aug 2024 14:25:24 +0200 Subject: [PATCH 4/8] array " --- onnx_array_api/array_api/_onnx_common.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/onnx_array_api/array_api/_onnx_common.py b/onnx_array_api/array_api/_onnx_common.py index 498c296..b9a5c01 100644 --- a/onnx_array_api/array_api/_onnx_common.py +++ b/onnx_array_api/array_api/_onnx_common.py @@ -3,9 +3,12 @@ import numpy as np from onnx import TensorProto -with warnings.catch_warnings(): - warnings.simplefilter("ignore") - from numpy.array_api._array_object import Array +try: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + from numpy.array_api._array_object import Array +except ImportError: + Array = None from ..npx.npx_types import ( DType, ElemType, @@ -107,7 +110,7 @@ def asarray( v = TEagerTensor(np.array(a)) elif isinstance(a, np.ndarray): v = TEagerTensor(a) - elif isinstance(a, Array): + elif Array and isinstance(a, Array): v = TEagerTensor(np.asarray(a)) else: raise RuntimeError(f"Unexpected type {type(a)} for the first input.") From ced1fe98a003929ea80ae91d6b628f755fcbc42c Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Fri, 30 Aug 2024 14:33:33 +0200 Subject: [PATCH 5/8] fix --- onnx_array_api/ort/ort_profile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/onnx_array_api/ort/ort_profile.py b/onnx_array_api/ort/ort_profile.py index 181a696..ebccaba 100644 --- a/onnx_array_api/ort/ort_profile.py +++ b/onnx_array_api/ort/ort_profile.py @@ -101,7 +101,9 @@ def ort_profile( if providers is None: providers = ["CPUExecutionProvider"] sess = InferenceSession(obj, sess_options, providers=providers, **kwargs) - first = next(feeds.values()) + for v in feeds.values(): + first = v + break if isinstance(first, numpy.ndarray): for _i in range(repeat): From cdfceb2742ae1740a2e1548fdbf88ad086976395 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Fri, 30 Aug 2024 16:20:29 +0200 Subject: [PATCH 6/8] fix missing dependency --- .../ut_array_api/test_hypothesis_array_api.py | 16 +++++++++++++--- _unittests/ut_plotting/test_text_plot.py | 1 + .../ut_translate_api/test_translate_classic.py | 8 ++------ onnx_array_api/array_api/_onnx_common.py | 7 +++++-- pyproject.toml | 1 + requirements.txt | 1 + 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/_unittests/ut_array_api/test_hypothesis_array_api.py b/_unittests/ut_array_api/test_hypothesis_array_api.py index 95b1447..602f928 100644 --- a/_unittests/ut_array_api/test_hypothesis_array_api.py +++ b/_unittests/ut_array_api/test_hypothesis_array_api.py @@ -2,6 +2,7 @@ import warnings from os import getenv from functools import reduce +import packaging.version as pv import numpy as np from operator import mul from hypothesis import given @@ -44,9 +45,12 @@ class TestHypothesisArraysApis(ExtTestCase): @classmethod def setUpClass(cls): - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - from numpy import array_api as xp + try: + import array_api_strict as xp + except ImportError: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + from numpy import array_api as xp api_version = getenv( "ARRAY_API_TESTS_VERSION", @@ -63,6 +67,9 @@ def test_strategies(self): self.assertNotEmpty(self.xps) self.assertNotEmpty(self.onxps) + @unittest.skipIf( + pv.Version(np.__version__) >= pv.Version("2.0"), reason="abandonned" + ) def test_scalar_strategies(self): dtypes = dict( integer_dtypes=self.xps.integer_dtypes(), @@ -139,6 +146,9 @@ def fctonx(x, kw): fctonx() self.assertEqual(len(args_onxp), len(args_np)) + @unittest.skipIf( + pv.Version(np.__version__) >= pv.Version("2.0"), reason="abandonned" + ) def test_square_sizes_strategies(self): dtypes = dict( integer_dtypes=self.xps.integer_dtypes(), diff --git a/_unittests/ut_plotting/test_text_plot.py b/_unittests/ut_plotting/test_text_plot.py index df0d3f5..5844ff0 100644 --- a/_unittests/ut_plotting/test_text_plot.py +++ b/_unittests/ut_plotting/test_text_plot.py @@ -94,6 +94,7 @@ def test_onnx_text_plot_tree_cls_2(self): +f 0:1 1:0 2:0 """ ).strip(" \n\r") + res = res.replace("np.float32(", "").replace(")", "") self.assertEqual(expected, res.strip(" \n\r")) @ignore_warnings((UserWarning, FutureWarning)) diff --git a/_unittests/ut_translate_api/test_translate_classic.py b/_unittests/ut_translate_api/test_translate_classic.py index 153a7d4..acee6e5 100644 --- a/_unittests/ut_translate_api/test_translate_classic.py +++ b/_unittests/ut_translate_api/test_translate_classic.py @@ -221,12 +221,8 @@ def test_topk_reverse(self): sorted=1 ) ) - outputs.append( - make_tensor_value_info('Values', TensorProto.FLOAT, shape=[]) - ) - outputs.append( - make_tensor_value_info('Indices', TensorProto.FLOAT, shape=[]) - ) + outputs.append(make_tensor_value_info('Values', TensorProto.FLOAT, shape=[])) + outputs.append(make_tensor_value_info('Indices', TensorProto.FLOAT, shape=[])) graph = make_graph( nodes, 'light_api', diff --git a/onnx_array_api/array_api/_onnx_common.py b/onnx_array_api/array_api/_onnx_common.py index b9a5c01..abc59a9 100644 --- a/onnx_array_api/array_api/_onnx_common.py +++ b/onnx_array_api/array_api/_onnx_common.py @@ -4,11 +4,14 @@ from onnx import TensorProto try: + import array_api_strict + + Array = type(array_api_strict.ones((1,))) +except ImportError: with warnings.catch_warnings(): warnings.simplefilter("ignore") from numpy.array_api._array_object import Array -except ImportError: - Array = None + from ..npx.npx_types import ( DType, ElemType, diff --git a/pyproject.toml b/pyproject.toml index 8ae8a76..a465006 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,4 +59,5 @@ select = [ "onnx_array_api/profiling.py" = ["E731"] "onnx_array_api/reference/__init__.py" = ["F401"] "_unittests/ut_npx/test_npx.py" = ["F821"] +"_unittests/ut_translate_api/test_translate_classic.py" = ["E501"] diff --git a/requirements.txt b/requirements.txt index 4680cfc..5cb31f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ array_api_compat +array_api_strict numpy onnx>=1.15.0 scipy From 650ab569506bc696548a05a6fdbe9202e5c343d0 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Sat, 31 Aug 2024 10:27:50 +0200 Subject: [PATCH 7/8] yml --- azure-pipelines.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 61587f4..31dc11f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,6 +35,9 @@ jobs: - script: | python -m pip install . -v -v -v displayName: 'install wheel' + - script: | + python -m pip freeze + displayName: 'pip freeze' - script: | python -m pytest displayName: 'Runs Unit Tests' @@ -83,6 +86,9 @@ jobs: - script: | black --diff . displayName: 'Black' + - script: | + python -m pip freeze + displayName: 'pip freeze' - script: | python -m pytest displayName: 'Runs Unit Tests' @@ -125,6 +131,9 @@ jobs: export ARRAY_API_TESTS_MODULE=onnx_array_api.array_api.onnx_numpy cd array-api-tests displayName: 'Set API' + - script: | + python -m pip freeze + displayName: 'pip freeze' - script: | export ARRAY_API_TESTS_MODULE=onnx_array_api.array_api.onnx_numpy cd array-api-tests @@ -177,6 +186,9 @@ jobs: - script: | black --diff . displayName: 'Black' + - script: | + python -m pip freeze + displayName: 'pip freeze' - script: | python -m pytest --cov displayName: 'Runs Unit Tests' @@ -213,6 +225,9 @@ jobs: displayName: 'Install Requirements dev' - script: pip install onnxmltools --no-deps displayName: 'Install onnxmltools' + - script: | + python -m pip freeze + displayName: 'pip freeze' - script: | python -m pytest -v displayName: 'Runs Unit Tests' @@ -256,6 +271,9 @@ jobs: displayName: 'Install Requirements dev' - script: pip install onnxmltools --no-deps displayName: 'Install onnxmltools' + - script: | + python -m pip freeze + displayName: 'pip freeze' - script: | python -m pytest displayName: 'Runs Unit Tests' From d0653e0db0feb5496397a0ef5f38aaa8516f5d89 Mon Sep 17 00:00:00 2001 From: Xavier Dupre Date: Sat, 31 Aug 2024 17:23:11 +0200 Subject: [PATCH 8/8] disable some tests --- .../ut_light_api/test_backend_export.py | 17 +++++++++++++++++ ...st_backend_extended_reference_evaluator.py | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/_unittests/ut_light_api/test_backend_export.py b/_unittests/ut_light_api/test_backend_export.py index 8dd9f86..91f4dd4 100644 --- a/_unittests/ut_light_api/test_backend_export.py +++ b/_unittests/ut_light_api/test_backend_export.py @@ -5,6 +5,7 @@ import packaging.version as pv import numpy from numpy.testing import assert_allclose +from onnx.defs import onnx_opset_version import onnx.backend.base import onnx.backend.test import onnx.shape_inference @@ -276,6 +277,22 @@ def run_node(cls, node, inputs, device=None, outputs_info=None, **kwargs): ")" ) +if onnx_opset_version() < 22: + backend_test.exclude( + "(" + "test_dft_inverse_cpu" + "|test_dft_inverse_opset19_cpu" + "|test_lppool_1d_default_cpu" + "|test_lppool_2d_default_cpu" + "|test_lppool_2d_dilations_cpu" + "|test_lppool_2d_pads_cpu" + "|test_lppool_2d_same_lower_cpu" + "|test_lppool_2d_same_upper_cpu" + "|test_lppool_2d_strides_cpu" + "|test_lppool_3d_default_cpu" + ")" + ) + if pv.Version(onnx_version) < pv.Version("1.16.0"): backend_test.exclude("(test_strnorm|test_range_)") diff --git a/_unittests/ut_reference/test_backend_extended_reference_evaluator.py b/_unittests/ut_reference/test_backend_extended_reference_evaluator.py index 06502b2..fbf12b7 100644 --- a/_unittests/ut_reference/test_backend_extended_reference_evaluator.py +++ b/_unittests/ut_reference/test_backend_extended_reference_evaluator.py @@ -217,6 +217,25 @@ def run_node(cls, node, inputs, device=None, outputs_info=None, **kwargs): # The following tests fail due to a type mismatch. backend_test.exclude("(test_eyelike_without_dtype)") +if onnx_opset_version() < 22: + backend_test.exclude( + "(" + "test_adagrad_cpu" + "|test_adagrad_multiple_cpu" + "|test_dft_inverse_cpu" + "|test_dft_inverse_opset19_cpu" + "|test_lppool_1d_default_cpu" + "|test_lppool_2d_default_cpu" + "|test_lppool_2d_dilations_cpu" + "|test_lppool_2d_pads_cpu" + "|test_lppool_2d_same_lower_cpu" + "|test_lppool_2d_same_upper_cpu" + "|test_lppool_2d_strides_cpu" + "|test_lppool_3d_default_cpu" + ")" + ) + + # The following tests fail due to discrepancies (small but still higher than 1e-7). backend_test.exclude("test_adam_multiple") # 1e-2