diff --git a/.circleci/config.yml b/.circleci/config.yml index f8e47a0b7..7f3cd42a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: circleci/python:3.8.6-buster + - image: circleci/python:3.8.7 working_directory: ~/repo @@ -11,8 +11,8 @@ jobs: - restore_cache: keys: - - v3-dependencies-{{ checksum "requirements.txt" }} - - v3-dependencies- + - v2-dependencies-{{ checksum "requirements.txt" }} + - v2-dependencies- # - run: # name: Install omp @@ -23,8 +23,8 @@ jobs: name: Install pandoc command: | sudo apt-get update - wget https://github.com/jgm/pandoc/releases/download/2.10.1/pandoc-2.10.1-1-amd64.deb - sudo dpkg -i pandoc-2.10.1-1-amd64.deb + wget https://github.com/jgm/pandoc/releases/download/2.11.3.2/pandoc-2.11.3.2-1-amd64.deb + sudo dpkg -i pandoc-2.11.3.2-1-amd64.deb - run: name: Install tex @@ -52,14 +52,50 @@ jobs: name: Install graphviz command: | sudo apt-get install -y graphviz - + - run: - name: install dependencies (1) + name: Install llvmlite command: | - python3 -m venv venv + sudo apt-get install lsb-release wget software-properties-common + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 10 + ls /usr/bin/llvm* + + - run: + name: Install protobuf-compiler cmake + command: | + sudo apt-get install protobuf-compiler libprotoc-dev cmake + + - run: + name: Install standard libraries + command: | + python -m venv venv . venv/bin/activate - pip install --upgrade pip - pip install -r requirements_conda.txt + pip install scipy matplotlib numpy cython pandas wheel pybind11 + + - run: + name: Install numba, llvmlite + command: | + python -m venv venv + . venv/bin/activate + # export LLVM_CONFIG=/usr/local/opt/llvm/bin/llvm-config + sudo ln -s /usr/bin/llvm-config-10 /usr/bin/llvm-config + pip install llvmlite numba + +# - run: +# name: Build onnx +# command: | +# python3 -m venv venv +# git clone -b master --single-branch https://github.com/onnx/onnx.git --recursive +# cd onnx +# export ONNX_ML=1 +# export ONNX_BUILD_TESTS=1 +# export ONNXIFI_DUMMY_BACKEND=1 +# python setup.py bdist_wheel +# ls dist +# python setup.py install +# cd .. - run: name: install dependencies (2) @@ -74,13 +110,13 @@ jobs: python3 -m venv venv . venv/bin/activate pip freeze | grep onnx - pip install onnxruntime>=1.4.0 --verbose + pip install onnxruntime>=1.6.0 --verbose pip show onnxruntime - save_cache: paths: - ./venv - key: v3-dependencies-{{ checksum "requirements.txt" }} + key: v2-dependencies-{{ checksum "requirements.txt" }} - run: name: install sklearn-onnx, onnxconverter-common @@ -90,11 +126,13 @@ jobs: pip install git+https://github.com/xadupre/sklearn-onnx.git@jenkins --upgrade - run: - name: pip freeze + name: check list of dependencies command: | + python -m venv venv . venv/bin/activate pip freeze - + apt list --installed + - run: name: compile and build command: | @@ -118,17 +156,17 @@ jobs: mkdir -p test-reports/src cp -r mlprodict test-reports/src - #- run: - # name: documentation - # command: | - # . venv/bin/activate - # python setup.py build_sphinx - - #- run: - # name: copy documentation - # command: | - # mkdir -p test-reports/doc - # zip -r -9 test-reports/doc/documentation_html.zip _doc/sphinxdoc/build/html +# - run: +# name: documentation +# command: | +# . venv/bin/activate +# python setup.py build_sphinx +# +# - run: +# name: copy documentation +# command: | +# mkdir -p test-reports/doc +# zip -r -9 test-reports/doc/documentation_html.zip _doc/sphinxdoc/build/html - store_artifacts: path: test-reports diff --git a/.local.jenkins.lin.yml b/.local.jenkins.lin.yml index ae4c77cc5..90976eb73 100644 --- a/.local.jenkins.lin.yml +++ b/.local.jenkins.lin.yml @@ -2,8 +2,7 @@ language: python python: - - { PATH: "{{Python37}}", VERSION: 3.7, DIST: std, PYINT: python3.7 } - - { PATH: "{{Python38}}", VERSION: 3.8, DIST: std, PYINT: python3.8 } + - { PATH: "{{Python39}}", VERSION: 3.9, DIST: std, PYINT: python3.9 } virtualenv: - path: {{ospathjoin(root_path, pickname("$NAME_JENKINS", project_name + "_$VERSION_$DIST_$NAME"), "_venv")}} diff --git a/.local.jenkins.win.yml b/.local.jenkins.win.yml index bbf942449..7a53dafd0 100644 --- a/.local.jenkins.win.yml +++ b/.local.jenkins.win.yml @@ -2,7 +2,7 @@ language: python python: - - { PATH: "{{replace(Python37, '\\', '\\\\')}}", VERSION: 3.7, DIST: std } + - { PATH: "{{replace(Python39, '\\', '\\\\')}}", VERSION: 3.9, DIST: std } virtualenv: - path: {{ospathjoin(root_path, pickname("%NAME_JENKINS%", project_name + "_%VERSION%_%DIST%_%NAME%"), "_venv")}} @@ -14,13 +14,17 @@ install: - pip install -r requirements.txt - pip freeze - pip freeze > pip_freeze.txt + before_script: - python -u setup.py build_ext --inplace + script: - { CMD: "python -u setup.py unittests", NAME: "UT" } + after_script: - python -u setup.py bdist_wheel - if [ ${DIST} != "conda" and ${NAME} == "UT" ] then copy dist\*.whl {{root_path}}\..\..\local_pypi\local_pypi_server fi + documentation: - if [ ${NAME} == "UT" ] then python -u setup.py build_sphinx fi - if [ ${NAME} == "UT" ] then xcopy /E /C /I /Y _doc\sphinxdoc\build\html dist\html fi diff --git a/.travis.yml b/.travis.yml index 81a950790..2256b1b8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,38 @@ -dist: bionic +dist: focal sudo: true language: python -python: - - "3.8" + +matrix: + include: + - python: 3.9 + name: "Python39" + before_install: - - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - - sudo apt-get update -qq - - sudo apt-get install libomp-dev + - sudo apt-get install libgeos-dev libproj-dev proj-data graphviz libblas-dev liblapack-dev + - wget https://apt.llvm.org/llvm.sh + - chmod +x llvm.sh + - sudo ./llvm.sh 10 + - ls /usr/bin/llvm* + - export LLVM_CONFIG=/usr/bin/llvm-config + # - sudo ln -s /usr/bin/llvm-config-10 /usr/bin/llvm-config + - sudo apt-get -y install graphviz + # onnx + - sudo apt-get install protobuf-compiler libprotoc-dev cmake + - git clone -b master --single-branch https://github.com/onnx/onnx.git --recursive + - cd onnx + - export ONNX_ML=1 + - export ONNX_BUILD_TESTS=1 + - export ONNXIFI_DUMMY_BACKEND=1 + - pip install -e . + - cd .. + install: - - gcc --version - - pip install -r requirements_conda.txt - pip install -r requirements.txt - #- pip install -i https://test.pypi.org/simple/ ort-nightly - - pip install onnxruntime + - pip install -i https://test.pypi.org/simple/ ort-nightly + # - pip install onnxruntime + before_script: - python setup.py build_ext --inplace + script: - python setup.py unittests -g ".*((LONG)|(SKIP)|(notebooks)).*" diff --git a/HISTORY.rst b/HISTORY.rst index 525ef6547..050bf241b 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -5,37 +5,44 @@ History ======= -current - 2020-12-11 - 0.00Mb +current - 2021-01-02 - 0.00Mb ============================= +* `200`: Add support for bfloat16 (2020-12-30) +* `201`: Fixes #200, add support for float16 (2020-12-30) +* `199`: Fix unit tests recently failing due to onnxruntime update. (2020-12-15) + +0.4.1352 - 2020-12-11 - 1.42Mb +============================== + * `196`: Fixes operator Slice for opset 9 (2020-12-11) -* `197`: Add a function to plot an onnx graph into matplotlib (2020-12-09) * `198`: Fixes #197, add function to plot onnx graph with matplotlib (2020-12-09) -* `194`: Add a function to insert a cast operator between two nodes (2020-12-08) +* `197`: Add a function to plot an onnx graph into matplotlib (2020-12-09) * `195`: Fixes #194, add function to add an operator in the graph (2020-12-08) +* `194`: Add a function to insert a cast operator between two nodes (2020-12-08) * `193`: Improves notebook coverage, update CI (2020-11-29) -* `191`: Improves performance of TreeEnsemble (2020-11-28) * `192`: Fixes #191, improves performance of TreeEnsemble (2020-11-28) -* `189`: Introduce parallelization in experimental einsum implementation (2020-11-17) +* `191`: Improves performance of TreeEnsemble (2020-11-28) * `190`: Fixes #189, parallelization of Einsum (2020-11-17) -* `187`: Custom implementation for operator Einsum (2020-11-15) +* `189`: Introduce parallelization in experimental einsum implementation (2020-11-17) * `188`: Fixes #187, custom implementation for operator Einsum (2020-11-15) -* `185`: Add operator LessOrEqual (2020-11-15) +* `187`: Custom implementation for operator Einsum (2020-11-15) * `186`: Fixes #185, add operator LessOrEqual (2020-11-15) +* `185`: Add operator LessOrEqual (2020-11-15) * `181`: Fix converter xgboost when ntree_limit is set up (2020-11-14) -* `178`: Fixes unit test testing OnnxConv (issue with shapes) (2020-11-07) -* `182`: Fixes #178, fix xgboost issue with ntree_limit (2020-11-07) -* `183`: Fix error in OnnxPipeline, parameter black_op not found (2020-11-07) * `184`: Fixes #183, fix missing parameter black_op in OnnxPipeline (2020-11-07) -* `179`: guess_schema_data_type fails with category in dataframe (2020-11-03) +* `183`: Fix error in OnnxPipeline, parameter black_op not found (2020-11-07) +* `182`: Fixes #178, fix xgboost issue with ntree_limit (2020-11-07) +* `178`: Fixes unit test testing OnnxConv (issue with shapes) (2020-11-07) * `180`: Fixes #179, fix guess_schema_from_data for categories (2020-11-03) -* `175`: Add operator Dropout (2020-09-29) +* `179`: guess_schema_data_type fails with category in dataframe (2020-11-03) * `176`: Fixes #175, add operator dropout (2020-09-29) +* `175`: Add operator Dropout (2020-09-29) * `174`: Add support for ReduceSum >= 13 (2020-09-21) -* `172`: Add runtime for operator MaxPool (2020-09-16) * `173`: Fixes #172, add runtime for operator MaxPool (2020-09-16) -* `170`: Add runtime for operator Pad (2020-09-10) +* `172`: Add runtime for operator MaxPool (2020-09-16) * `171`: Fixes #170, add operator Pad (2020-09-10) +* `170`: Add runtime for operator Pad (2020-09-10) 0.4.1259 - 2020-09-03 - 1.32Mb ============================== diff --git a/LICENSE.txt b/LICENSE.txt index 19c28f3a5..47eced036 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2017-2020, Xavier Dupré +Copyright (c) 2017-2021, Xavier Dupré Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/_doc/sphinxdoc/source/conf.py b/_doc/sphinxdoc/source/conf.py index dfedf313b..efc42d744 100644 --- a/_doc/sphinxdoc/source/conf.py +++ b/_doc/sphinxdoc/source/conf.py @@ -28,11 +28,12 @@ local_template = os.path.join(os.path.abspath( os.path.dirname(__file__)), "phdoc_templates") -set_sphinx_variables(__file__, "mlprodict", "Xavier Dupré", 2020, - "alabaster", alabaster.get_path(), - locals(), extlinks=dict( - issue=('https://github.com/sdpython/mlprodict/issues/%s', 'issue')), - title="Python Runtime for ONNX", book=True) +set_sphinx_variables( + __file__, "mlprodict", "Xavier Dupré", 2021, + "alabaster", alabaster.get_path(), + locals(), extlinks=dict( + issue=('https://github.com/sdpython/mlprodict/issues/%s', 'issue')), + title="Python Runtime for ONNX", book=True) blog_root = "http://www.xavierdupre.fr/app/mlprodict/helpsphinx/" extensions.extend([ @@ -42,7 +43,8 @@ ]) html_context = { - 'css_files': get_default_stylesheet() + ['_static/my-styles.css', '_static/gallery.css'], + 'css_files': get_default_stylesheet() + [ + '_static/my-styles.css', '_static/gallery.css'], } html_logo = "phdoc_static/project_ico.png" diff --git a/_unittests/ut__skl2onnx/test_sklearn_label_encoder_converter.py b/_unittests/ut__skl2onnx/test_sklearn_label_encoder_converter.py index 9f3985b26..8767cbb80 100644 --- a/_unittests/ut__skl2onnx/test_sklearn_label_encoder_converter.py +++ b/_unittests/ut__skl2onnx/test_sklearn_label_encoder_converter.py @@ -50,7 +50,7 @@ def test_model_label_encoder_int(self): model = LabelEncoder() data = numpy.array([10, 3, 5, -34, 0], dtype=numpy.int64) model.fit(data) - for op in sorted(set([9, 10, 11, 12, TARGET_OPSET])): + for op in sorted(set([9, 10, 11, 12, 13, TARGET_OPSET])): if op > TARGET_OPSET: continue with self.subTest(opset=op): diff --git a/_unittests/ut_module/test_code_style.py b/_unittests/ut_module/test_code_style.py index 74c92423a..e3bbb668d 100644 --- a/_unittests/ut_module/test_code_style.py +++ b/_unittests/ut_module/test_code_style.py @@ -17,7 +17,7 @@ def test_style_src(self): pylint_ignore=('C0103', 'C1801', 'R0201', 'R1705', 'W0108', 'W0613', 'R1702', 'W0212', 'W0640', 'W0223', 'W0201', 'W0622', 'C0123', 'W0107', - 'C0415', 'R1721'), + 'C0415', 'R1721', 'C0411'), skip=["Instance of 'tuple' has no ", "do not compare types, use 'isinstance()'", "Instance of 'AutoAction' has no 'children' member", @@ -34,7 +34,7 @@ def test_style_test(self): check_pep8(test, fLOG=fLOG, neg_pattern="temp_.*", pylint_ignore=('C0103', 'C1801', 'R0201', 'R1705', 'W0108', 'W0613', 'C0111', 'W0107', 'C0415', - 'R1721', 'C0302'), + 'R1721', 'C0302', 'C0411'), skip=["Instance of 'tuple' has no ", "R1720", 'if __name__ == "__main__":', diff --git a/_unittests/ut_onnx_conv/test_onnx_conv_knn.py b/_unittests/ut_onnx_conv/test_onnx_conv_knn.py index 9b6370911..e018c5c98 100644 --- a/_unittests/ut_onnx_conv/test_onnx_conv_knn.py +++ b/_unittests/ut_onnx_conv/test_onnx_conv_knn.py @@ -233,7 +233,7 @@ def onnx_test_knn_single_classreg(self, dtype, n_targets=1, debug=False, if target_opset is None: opsets = list(sorted(set([ - 9, 10, 11, 12, get_opset_number_from_onnx()]))) + 9, 10, 11, 12, 13, get_opset_number_from_onnx()]))) else: opsets = [target_opset] for ops in opsets: @@ -436,7 +436,7 @@ def test_onnx_test_knn_transform(self): clr = NearestNeighbors(n_neighbors=3) clr.fit(X_train) - for to in (10, 11, 12): + for to in (10, 11, 12, 13): if to > get_opset_number_from_onnx(): break try: diff --git a/_unittests/ut_onnx_conv/test_scorers.py b/_unittests/ut_onnx_conv/test_scorers.py index 736c2085d..297fc47d1 100644 --- a/_unittests/ut_onnx_conv/test_scorers.py +++ b/_unittests/ut_onnx_conv/test_scorers.py @@ -6,7 +6,7 @@ from logging import getLogger from collections import OrderedDict import numpy -from pyquickhelper.pycode import ExtTestCase, get_temp_folder +from pyquickhelper.pycode import ExtTestCase, get_temp_folder, ignore_warnings from sklearn.metrics import make_scorer try: from sklearn.metrics._scorer import _PredictScorer @@ -25,6 +25,7 @@ def setUp(self): logger.disabled = True register_scorers() + @ignore_warnings((DeprecationWarning, UserWarning)) def test_score_cdist_sum(self): X = numpy.array([[0, 1, 0, 2], [1, 0, 4, 5], @@ -37,6 +38,7 @@ def test_score_cdist_sum(self): scorer = make_scorer(score_cdist_sum, greater_is_better=False) self.assertIsInstance(scorer, _PredictScorer) + @ignore_warnings((DeprecationWarning, UserWarning)) def test_custom_transformer(self): def mse(x, y): return x - y @@ -44,6 +46,7 @@ def mse(x, y): rp = repr(tr) self.assertIn("CustomScorerTransform('mse'", rp) + @ignore_warnings((DeprecationWarning, UserWarning)) def test_score_cdist_sum_onnx(self): X = numpy.array([[0, 1, 0, 2], [1, 0, 4, 5], diff --git a/_unittests/ut_onnxrt/test_coverage_runtime_ops.py b/_unittests/ut_onnxrt/test_coverage_runtime_ops.py index f93157594..337fc2f98 100644 --- a/_unittests/ut_onnxrt/test_coverage_runtime_ops.py +++ b/_unittests/ut_onnxrt/test_coverage_runtime_ops.py @@ -13,7 +13,7 @@ class TestCoverageRuntimeOps(ExtTestCase): def test_op_constant(self): - for opv in [9, 10, 11, 12]: + for opv in [9, 10, 11, 12, 13]: for dtype in [numpy.float32, numpy.float64, numpy.int32, numpy.int64]: with self.subTest(opv=opv, dtype=dtype): diff --git a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_.py b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_.py index 74465aa59..9e0f5152a 100644 --- a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_.py +++ b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_.py @@ -49,10 +49,12 @@ OnnxReduceSumSquare, OnnxRelu, OnnxReshape, OnnxShape, OnnxSlice, OnnxSigmoid, OnnxSign, OnnxSin, - OnnxSoftmax, OnnxSqueeze, OnnxSplit, + OnnxSplitApi11, + OnnxSoftmax, OnnxSplit, OnnxSqrt, OnnxSub, OnnxSum, + OnnxSqueeze, OnnxSqueezeApi11, OnnxTopK, OnnxTranspose, - OnnxUnsqueeze, + OnnxUnsqueeze, OnnxUnsqueezeApi11 ) try: from skl2onnx.algebra.onnx_ops import OnnxCelu @@ -67,7 +69,7 @@ from mlprodict.onnxrt.validate.validate_python import validate_python_inference from mlprodict.onnxrt.ops_cpu.op_batch_normalization import _batchnorm_test_mode from mlprodict.onnxrt.ops_cpu.op_global_average_pool import _global_average_pool -from mlprodict.onnxrt.ops_cpu._op_onnx_numpy import ( # pylint: disable=E0611 +from mlprodict.onnxrt.ops_cpu._op_onnx_numpy import ( # pylint: disable=E0611,E0401 topk_element_min_double, topk_element_max_double, topk_element_fetch_double, topk_element_min_float, topk_element_max_float, topk_element_fetch_float, topk_element_min_int64, topk_element_max_int64, topk_element_fetch_int64) @@ -2068,8 +2070,9 @@ def test_onnxt_runtime_reduce_sum(self): [numpy.inf, 1], [1., -numpy.inf], [-numpy.inf, 1]], dtype=float) - onx = OnnxReduceSum('X', output_names=['Y'], keepdims=0, axes=[1], - op_version=get_opset_number_from_onnx()) + onx = OnnxReduceSumApi11( + 'X', output_names=['Y'], keepdims=0, axes=[1], + op_version=get_opset_number_from_onnx()) model_def = onx.to_onnx({'X': X.astype(numpy.float32)}, target_opset=get_opset_number_from_onnx()) oinf = OnnxInference(model_def) @@ -2238,43 +2241,46 @@ def test_onnxt_runtime_slice(self): @wraplog() def test_onnxt_runtime_split(self): - x = numpy.array([1., 2., 3., 4., 5., 6.]).astype(numpy.float32) - y = [numpy.array([1., 2.]).astype(numpy.float32), - numpy.array([3., 4.]).astype(numpy.float32), - numpy.array([5., 6.]).astype(numpy.float32)] - - onx = OnnxSplit('X', axis=0, split=[2, 2, 2], - output_names=['Y1', 'Y2', 'Y3'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y[0], got['Y1']) - self.assertEqualArray(y[1], got['Y2']) - self.assertEqualArray(y[2], got['Y3']) - - onx = OnnxSplit('X', axis=0, - output_names=['Y1', 'Y2', 'Y3'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y[0], got['Y1']) - self.assertEqualArray(y[1], got['Y2']) - self.assertEqualArray(y[2], got['Y3']) - - x = numpy.array([[1., 2., 3., 4., 5., 6.], - [7., 8., 9., 10., 11., 12.]]).astype(numpy.float32) - y = [numpy.array([[1., 2.], [7., 8.]]).astype(numpy.float32), - numpy.array([[3., 4., 5., 6.], [9., 10., 11., 12.]]).astype(numpy.float32)] - onx = OnnxSplit('X', axis=1, split=[2, 4], - output_names=['Y1', 'Y2'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y[0], got['Y1']) - self.assertEqualArray(y[1], got['Y2']) + for opset in [10, 11, 12, 13, get_opset_number_from_onnx()]: + if opset > get_opset_number_from_onnx(): + continue + with self.subTest(opset=opset): + x = numpy.array([1., 2., 3., 4., 5., 6.]).astype(numpy.float32) + y = [numpy.array([1., 2.]).astype(numpy.float32), + numpy.array([3., 4.]).astype(numpy.float32), + numpy.array([5., 6.]).astype(numpy.float32)] + onx = OnnxSplitApi11( + 'X', axis=0, split=[2, 2, 2], output_names=['Y1', 'Y2', 'Y3'], + op_version=opset) + model_def = onx.to_onnx( + {'X': x.astype(numpy.float32)}, target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y[0], got['Y1']) + self.assertEqualArray(y[1], got['Y2']) + self.assertEqualArray(y[2], got['Y3']) + + onx = OnnxSplitApi11( + 'X', axis=0, output_names=['Y1', 'Y2', 'Y3'], + op_version=opset) + model_def = onx.to_onnx( + {'X': x.astype(numpy.float32)}, target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y[0], got['Y1']) + self.assertEqualArray(y[1], got['Y2']) + self.assertEqualArray(y[2], got['Y3']) + + x = numpy.array([[1., 2., 3., 4., 5., 6.], + [7., 8., 9., 10., 11., 12.]]).astype(numpy.float32) + y = [numpy.array([[1., 2.], [7., 8.]]).astype(numpy.float32), + numpy.array([[3., 4., 5., 6.], [9., 10., 11., 12.]]).astype(numpy.float32)] + onx = OnnxSplitApi11( + 'X', axis=1, split=[2, 4], output_names=['Y1', 'Y2'], + op_version=opset) + model_def = onx.to_onnx( + {'X': x.astype(numpy.float32)}, target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y[0], got['Y1']) + self.assertEqualArray(y[1], got['Y2']) python_tested.append(OnnxSplit) @wraplog() @@ -2283,25 +2289,29 @@ def test_onnxt_runtime_sqrt(self): @wraplog() def test_onnxt_runtime_squeeze(self): - x = numpy.random.randn(20, 1).astype( # pylint: disable=E1101 - numpy.float32) # pylint: disable=E1101 - y = numpy.squeeze(x) - onx = OnnxSqueeze('X', axes=[1], output_names=['Y'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y, got['Y']) + for opset in [10, 11, 12, 13, get_opset_number_from_onnx()]: + if opset > get_opset_number_from_onnx(): + continue + with self.subTest(opset=opset): + x = numpy.random.randn(20, 1).astype( # pylint: disable=E1101 + numpy.float32) # pylint: disable=E1101 + y = numpy.squeeze(x) + onx = OnnxSqueezeApi11( + 'X', axes=[1], output_names=['Y'], op_version=opset) + model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, + target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y, got['Y']) - x = numpy.random.randn(1, 20).astype( # pylint: disable=E1101 - numpy.float32) # pylint: disable=E1101 - y = numpy.squeeze(x) - onx = OnnxSqueeze('X', axes=[0], output_names=['Y'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y, got['Y']) + x = numpy.random.randn(1, 20).astype( # pylint: disable=E1101 + numpy.float32) # pylint: disable=E1101 + y = numpy.squeeze(x) + onx = OnnxSqueezeApi11( + 'X', axes=[0], output_names=['Y'], op_version=opset) + model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, + target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y, got['Y']) python_tested.append(OnnxSqueeze) @wraplog() @@ -2435,26 +2445,29 @@ def test_onnxt_runtime_transpose(self): @wraplog() def test_onnxt_runtime_unsqueeze(self): - x = numpy.random.randn(1, 3, 1, 5).astype(numpy.float32) - y = numpy.expand_dims(x, axis=-2) - onx = OnnxUnsqueeze('X', axes=[-2], output_names=['Y'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y, got['Y']) - - x = numpy.random.randn(3, 4, 5).astype(numpy.float32) - y = numpy.expand_dims(x, axis=2) - y = numpy.expand_dims(y, axis=4) - y = numpy.expand_dims(y, axis=5) - onx = OnnxUnsqueeze('X', axes=[2, 4, 5], output_names=['Y'], - op_version=get_opset_number_from_onnx()) - model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, - target_opset=get_opset_number_from_onnx()) - got = OnnxInference(model_def).run({'X': x}) - self.assertEqualArray(y, got['Y']) + for opset in [10, 11, 12, 13, get_opset_number_from_onnx()]: + if opset > get_opset_number_from_onnx(): + continue + with self.subTest(opset=opset): + x = numpy.random.randn(1, 3, 1, 5).astype(numpy.float32) + y = numpy.expand_dims(x, axis=-2) + onx = OnnxUnsqueezeApi11( + 'X', axes=[-2], output_names=['Y'], op_version=opset) + model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, + target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y, got['Y']) + x = numpy.random.randn(3, 4, 5).astype(numpy.float32) + y = numpy.expand_dims(x, axis=2) + y = numpy.expand_dims(y, axis=4) + y = numpy.expand_dims(y, axis=5) + onx = OnnxUnsqueezeApi11( + 'X', axes=[2, 4, 5], output_names=['Y'], op_version=opset) + model_def = onx.to_onnx({'X': x.astype(numpy.float32)}, + target_opset=opset) + got = OnnxInference(model_def).run({'X': x}) + self.assertEqualArray(y, got['Y']) python_tested.append(OnnxUnsqueeze) @wraplog() @@ -2811,5 +2824,5 @@ def test_make_constant(self): if __name__ == "__main__": - # TestOnnxrtPythonRuntime().test_onnxt_runtime_slice() + TestOnnxrtPythonRuntime().test_onnxt_runtime_unsqueeze() unittest.main() diff --git a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_2.py b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_2.py index 658938c78..c1237e7b5 100644 --- a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_2.py +++ b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_2.py @@ -12,7 +12,7 @@ from skl2onnx import __version__ as skl2onnx_version from mlprodict.onnxrt import OnnxInference from mlprodict.onnxrt.ops_cpu.op_array_feature_extractor import _array_feature_extrator, sizeof_dtype -from mlprodict.onnxrt.ops_cpu._op_onnx_numpy import array_feature_extractor_double # pylint: disable=E0611 +from mlprodict.onnxrt.ops_cpu._op_onnx_numpy import array_feature_extractor_double # pylint: disable=E0611,E0401 from mlprodict.tools.asv_options_helper import get_ir_version_from_onnx diff --git a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_svm.py b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_svm.py index bb6a6f442..1174b615e 100644 --- a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_svm.py +++ b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_svm.py @@ -31,7 +31,7 @@ def setUp(self): return self def test_openmp_compilation_float(self): - from mlprodict.onnxrt.ops_cpu.op_svm_regressor_ import RuntimeSVMRegressorFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_svm_regressor_ import RuntimeSVMRegressorFloat # pylint: disable=E0611,E0401 ru = RuntimeSVMRegressorFloat(10) r = ru.runtime_options() self.assertEqual('OPENMP', r) @@ -39,7 +39,7 @@ def test_openmp_compilation_float(self): self.assertGreater(nb, 0) def test_openmp_compilation_double(self): - from mlprodict.onnxrt.ops_cpu.op_svm_regressor_ import RuntimeSVMRegressorDouble # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_svm_regressor_ import RuntimeSVMRegressorDouble # pylint: disable=E0611,E0401 ru = RuntimeSVMRegressorDouble(10) r = ru.runtime_options() self.assertEqual('OPENMP', r) diff --git a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_tree.py b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_tree.py index 635dbda18..a117355a2 100644 --- a/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_tree.py +++ b/_unittests/ut_onnxrt/test_onnxrt_python_runtime_ml_tree.py @@ -356,14 +356,14 @@ def test_onnxrt_python_RandomForestClassifer5(self): self.assertEqualArray(exp, got, decimal=5) def test_openmp_compilation(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_ import RuntimeTreeEnsembleRegressorFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_ import RuntimeTreeEnsembleRegressorFloat # pylint: disable=E0611,E0401 ru = RuntimeTreeEnsembleRegressorFloat() r = ru.runtime_options() self.assertEqual('OPENMP', r) nb = ru.omp_get_max_threads() self.assertGreater(nb, 0) - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_ import RuntimeTreeEnsembleClassifierFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_ import RuntimeTreeEnsembleClassifierFloat # pylint: disable=E0611,E0401 ru = RuntimeTreeEnsembleClassifierFloat() r = ru.runtime_options() self.assertEqual('OPENMP', r) @@ -371,14 +371,14 @@ def test_openmp_compilation(self): self.assertEqual(nb2, nb) def test_openmp_compilation_p(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import RuntimeTreeEnsembleRegressorPFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import RuntimeTreeEnsembleRegressorPFloat # pylint: disable=E0611,E0401 ru = RuntimeTreeEnsembleRegressorPFloat(1, 1, False, False) r = ru.runtime_options() self.assertEqual('OPENMP', r) nb = ru.omp_get_max_threads() self.assertGreater(nb, 0) - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_p_ import RuntimeTreeEnsembleClassifierPFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_p_ import RuntimeTreeEnsembleClassifierPFloat # pylint: disable=E0611,E0401 ru = RuntimeTreeEnsembleClassifierPFloat(1, 1, False, False) r = ru.runtime_options() self.assertEqual('OPENMP', r) @@ -386,14 +386,14 @@ def test_openmp_compilation_p(self): self.assertEqual(nb2, nb) def test_openmp_compilation_p_true(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import RuntimeTreeEnsembleRegressorPFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import RuntimeTreeEnsembleRegressorPFloat # pylint: disable=E0611,E0401 ru = RuntimeTreeEnsembleRegressorPFloat(1, 1, True, False) r = ru.runtime_options() self.assertEqual('OPENMP', r) nb = ru.omp_get_max_threads() self.assertGreater(nb, 0) - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_p_ import RuntimeTreeEnsembleClassifierPFloat # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_p_ import RuntimeTreeEnsembleClassifierPFloat # pylint: disable=E0611,E0401 ru = RuntimeTreeEnsembleClassifierPFloat(1, 1, True, False) r = ru.runtime_options() self.assertEqual('OPENMP', r) @@ -401,7 +401,8 @@ def test_openmp_compilation_p_true(self): self.assertEqual(nb2, nb) def test_cpp_average(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_average # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import ( # pylint: disable=E0611,E0401 + test_tree_regressor_multitarget_average) confs = [[100, 100, False, False, True], [100, 100, False, False, False], [10, 10, False, False, True], @@ -418,7 +419,8 @@ def test_cpp_average(self): *(conf + [b, True])) def test_cpp_average_true(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_average # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import ( # pylint: disable=E0611,E0401 + test_tree_regressor_multitarget_average) confs = [[100, 100, True, False, True], [100, 100, True, False, False], [10, 10, True, False, True], @@ -435,7 +437,7 @@ def test_cpp_average_true(self): *(conf + [b, True])) def test_cpp_sum(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_sum # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_sum # pylint: disable=E0611,E0401 confs = [[100, 100, False, False, True], [100, 100, False, False, False], [10, 10, False, False, True], @@ -452,7 +454,7 @@ def test_cpp_sum(self): *(conf + [b, True])) def test_cpp_sum_true(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_sum # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_sum # pylint: disable=E0611,E0401 confs = [[100, 100, True, False, True], [100, 100, True, False, False], [10, 10, True, False, True], @@ -469,7 +471,7 @@ def test_cpp_sum_true(self): *(conf + [b, True])) def test_cpp_min(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_min # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_min # pylint: disable=E0611,E0401 confs = [[100, 100, False, False, True], [100, 100, False, False, False], [10, 10, False, False, True], @@ -484,7 +486,7 @@ def test_cpp_min(self): test_tree_regressor_multitarget_min(*(conf + [b, True])) def test_cpp_min_true(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_min # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_min # pylint: disable=E0611,E0401 confs = [[100, 100, True, False, True], [100, 100, True, False, False], [10, 10, True, False, True], @@ -499,7 +501,7 @@ def test_cpp_min_true(self): test_tree_regressor_multitarget_min(*(conf + [b, True])) def test_cpp_max(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_max # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_max # pylint: disable=E0611,E0401 confs = [[100, 100, False, False, True], [100, 100, False, False, False], [10, 10, False, False, True], @@ -514,7 +516,7 @@ def test_cpp_max(self): test_tree_regressor_multitarget_max(*(conf + [b, True])) def test_cpp_max_true(self): - from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_max # pylint: disable=E0611 + from mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_ import test_tree_regressor_multitarget_max # pylint: disable=E0611,E0401 confs = [[100, 100, True, False, True], [100, 100, True, False, False], [10, 10, True, False, True], diff --git a/_unittests/ut_onnxrt/test_onnxrt_switch_types.py b/_unittests/ut_onnxrt/test_onnxrt_switch_types.py index fb784917e..8fbfdd30b 100644 --- a/_unittests/ut_onnxrt/test_onnxrt_switch_types.py +++ b/_unittests/ut_onnxrt/test_onnxrt_switch_types.py @@ -58,7 +58,7 @@ def test_onnxt_enumerate_arrays(self): raise AssertionError(mes) @ignore_warnings(FutureWarning) - def test_onnxt_iris_gaussian_process_exp_sine_squared(self): + def test_onnxt_iris_gaussian_process_exp_sine_squared_12(self): iris = load_iris() X, y = iris.data, iris.target X_train, X_test, y_train, _ = train_test_split(X, y, random_state=11) @@ -69,7 +69,50 @@ def test_onnxt_iris_gaussian_process_exp_sine_squared(self): model_def = to_onnx( clr, X_train.astype(numpy.float32), - options={GaussianProcessRegressor: {'return_std': True}}) + options={GaussianProcessRegressor: {'return_std': True}}, + target_opset=12) + oinf = OnnxInference(model_def, runtime='python') + + res = oinf.run({'X': X_test.astype(numpy.float32)}) + ym2, std2 = res['GPmean'], res['GPcovstd'] + self.assertEqualArray(numpy.squeeze(ym), numpy.squeeze(ym2), decimal=5) + self.assertEqualArray(std, std2, decimal=5) + + res = oinf.switch_initializers_dtype(clr) + last = res[-1] + self.assertEqual(last[0], 'pass2') + _linv = 0 + for a in enumerate_fitted_arrays(clr): + if "_K_inv" in a[-2]: + _linv += 1 + self.assertEqual(_linv, 1) + res = oinf.run({'X': X_test.astype(numpy.float64)}) + ym3, std3 = res['GPmean'], res['GPcovstd'] + self.assertEqualArray(ym3, ym2) + self.assertEqualArray(std3, std2, decimal=5) + d1 = numpy.sum(numpy.abs(ym.ravel() - ym2.ravel())) + d2 = numpy.sum(numpy.abs(ym.ravel() - ym3.ravel())) + d3 = numpy.sum(numpy.abs(ym2.ravel() - ym3.ravel())) + self.assertLess(d2, min(d1, d3) / 2) + d1 = numpy.sum(numpy.abs(std.ravel() - std2.ravel())) + d2 = numpy.sum(numpy.abs(std.ravel() - std3.ravel())) + d3 = numpy.sum(numpy.abs(std2.ravel() - std3.ravel())) + self.assertLess(d2, min(d1, d3) / 2) + + @ignore_warnings(FutureWarning) + def test_onnxt_iris_gaussian_process_exp_sine_squared_13(self): + iris = load_iris() + X, y = iris.data, iris.target + X_train, X_test, y_train, _ = train_test_split(X, y, random_state=11) + clr = GaussianProcessRegressor( + kernel=ExpSineSquared(), alpha=100) + clr.fit(X_train, y_train) + ym, std = clr.predict(X_test, return_std=True) + + model_def = to_onnx( + clr, X_train.astype(numpy.float32), + options={GaussianProcessRegressor: {'return_std': True}}, + target_opset=13) oinf = OnnxInference(model_def, runtime='python') res = oinf.run({'X': X_test.astype(numpy.float32)}) @@ -110,7 +153,8 @@ def test_onnxt_iris_gaussian_process_dot_product(self): model_def = to_onnx( clr, X_train.astype(numpy.float32), - options={GaussianProcessRegressor: {'return_std': True}}) + options={GaussianProcessRegressor: {'return_std': True}}, + target_opset=12) oinf = OnnxInference(model_def, runtime='python') res = oinf.run({'X': X_test.astype(numpy.float32)}) diff --git a/_unittests/ut_onnxrt/test_onnxrt_validate_onnxruntime2.py b/_unittests/ut_onnxrt/test_onnxrt_validate_onnxruntime2.py index b2a582418..545c46006 100644 --- a/_unittests/ut_onnxrt/test_onnxrt_validate_onnxruntime2.py +++ b/_unittests/ut_onnxrt/test_onnxrt_validate_onnxruntime2.py @@ -20,7 +20,8 @@ from mlprodict.tools.asv_options_helper import get_opset_number_from_onnx -ignored_warnings = (UserWarning, ConvergenceWarning, RuntimeWarning, FutureWarning) +ignored_warnings = (UserWarning, ConvergenceWarning, + RuntimeWarning, FutureWarning) class TestOnnxrtValidateOnnxRuntime(ExtTestCase): diff --git a/_unittests/ut_testing/test_experimental.py b/_unittests/ut_testing/test_experimental.py index a53e80ec9..df34bd1f3 100644 --- a/_unittests/ut_testing/test_experimental.py +++ b/_unittests/ut_testing/test_experimental.py @@ -7,7 +7,7 @@ from onnxruntime import InferenceSession from pyquickhelper.pycode import ExtTestCase, is_travis_or_appveyor from mlprodict.testing.experimental import custom_pad, custom_einsum -from mlprodict.testing.experimental_c import ( # pylint: disable=E0611 +from mlprodict.testing.experimental_c import ( # pylint: disable=E0611,E0401 custom_einsum_double, custom_einsum_int64, custom_einsum_float, code_optimisation) from mlprodict.tools import get_opset_number_from_onnx diff --git a/appveyor.yml b/appveyor.yml index 6bcbb1057..d11864fca 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,9 +10,26 @@ init: install: - "%PYTHON%\\python -m pip install --upgrade pip" - - "%PYTHON%\\Scripts\\pip install -r requirements_conda.txt" - - "%PYTHON%\\Scripts\\pip install -r requirements.txt" - - "%PYTHON%\\Scripts\\pip install onnxruntime>=1.5.0" + - pip install wheel + # for many packages + - "%PYTHON%\\Scripts\\pip install -r requirements-win.txt" + # install precompiled versions not available on pypi + - "%PYTHON%\\Scripts\\pymy_install3 llvmlite numba" + # onnx + #- git clone -b master --single-branch https://github.com/onnx/onnx.git --recursive + #- cd onnx + #- set ONNX_ML=1 + #- set ONNX_BUILD_TESTS=1 + #- set ONNXIFI_DUMMY_BACKEND=1 + #- python setup.py bdist_wheel + #- dir dist + #- python setup.py install + #- cd .. + # onnxruntime + - "%PYTHON%\\Scripts\\pip install -i https://test.pypi.org/simple/ ort-nightly" + # other dependencies + - "%PYTHON%\\Scripts\\pip install -r requirements.txt --no-deps" + build: off before_test: @@ -27,3 +44,5 @@ after_test: artifacts: - path: dist name: mlprodict + - path: onnx\dist + name: onnx diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e91176474..aa50816d4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,157 +1,119 @@ jobs: - - job: 'TestLinux' - pool: - vmImage: 'ubuntu-latest' - strategy: - matrix: - Python37-Linux: - python.version: '3.7' - maxParallel: 3 - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - architecture: 'x64' - - script: sudo apt-get update - displayName: 'AptGet Update' - - script: sudo apt-get install -y pandoc - displayName: 'Install Pandoc' - - script: sudo apt-get install -y libomp-8-dev - displayName: 'Install omp' - # - script: sudo apt-get install -y texlive texlive-latex-extra texlive-xetex dvipng - # displayName: 'Install Latex' - - script: sudo apt-get install -y p7zip-full - displayName: 'Install 7z, rar' - - script: sudo apt-get install -y inkscape - displayName: 'Install Inkscape' - - script: sudo apt-get install -y graphviz - displayName: 'Install Graphviz' - - script: python -m pip install --upgrade pip setuptools wheel - displayName: 'Install tools' - - script: pip install -r requirements_conda.txt - displayName: 'Install Requirements Conda' - - script: pip install -r requirements.txt - displayName: 'Install Requirements' - - script: pip install onnxruntime - displayName: 'Install onnxruntime' - - script: | - python -u setup.py build_ext --inplace - displayName: 'Build package inplace' - - script: | - python -u setup.py unittests -g ".*((LONG)|(SKIP)|(notebooks)).*" - displayName: 'Runs Unit Tests' - - script: | - python -u setup.py bdist_wheel - displayName: 'Build Package' - # - script: | - # python -u setup.py build_sphinx - # displayName: 'Builds Documentation' - - task: PublishPipelineArtifact@0 - inputs: - artifactName: 'wheel-linux-$(python.version)' - targetPath: 'dist' +- job: 'TestLinux' + pool: + vmImage: 'ubuntu-latest' + strategy: + matrix: + Python39-Linux: + python.version: '3.9' + maxParallel: 3 + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + architecture: 'x64' + - script: sudo apt-get update + displayName: 'AptGet Update' + - script: sudo apt-get install -y inkscape + displayName: 'Install Inkscape' + - script: sudo apt-get install -y pandoc + displayName: 'Install Pandoc' + # - script: sudo apt-get install -y texlive texlive-latex-extra texlive-xetex dvipng + # displayName: 'Install Latex' + - script: sudo apt-get install -y libomp-8-dev + displayName: 'Install omp' + - script: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 10 + ls /usr/bin/llvm* + export LLVM_CONFIG=/usr/bin/llvm-config-10 + displayName: 'Install llvmlite' + - script: sudo apt-get install -y p7zip-full + displayName: 'Install 7z, rar' + - script: sudo apt-get install -y graphviz + displayName: 'Install Graphviz' + - script: pip install --upgrade pip setuptools wheel + displayName: 'Install tools' + - script: pip install numpy + displayName: 'Install numpy' + - script: | + export LLVM_CONFIG=/usr/bin/llvm-config-10 + pip install -r requirements.txt + displayName: 'Install Requirements' + - script: pip install onnxruntime + displayName: 'Install onnxruntime' + - script: python -u setup.py build_ext --inplace + displayName: 'Build package inplace' + - script: python -u setup.py unittests -g ".*((LONG)|(SKIP)|(notebooks)).*" + displayName: 'Runs Unit Tests' + - script: python -u setup.py bdist_wheel + displayName: 'Build wheel' + #- script: python -u setup.py build_sphinx + # displayName: 'Builds Documentation' + - task: PublishPipelineArtifact@0 + inputs: + artifactName: 'wheel-linux-$(python.version)' + targetPath: 'dist' - - job: 'TestLinux16' - pool: - vmImage: 'ubuntu-16.04' - strategy: - matrix: - Python37-Linux: - python.version: '3.7' - maxParallel: 3 - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - architecture: 'x64' - - script: sudo apt-get update - displayName: 'AptGet Update' - - script: sudo apt-get install -y pandoc - displayName: 'Install Pandoc' - - script: sudo apt-get install -y libomp-8-dev - displayName: 'Install omp' - # - script: sudo apt-get install -y texlive texlive-latex-extra texlive-xetex dvipng - # displayName: 'Install Latex' - - script: sudo apt-get install -y p7zip-full - displayName: 'Install 7z, rar' - - script: sudo apt-get install -y inkscape - displayName: 'Install Inkscape' - - script: sudo apt-get install -y graphviz - displayName: 'Install Graphviz' - - script: python -m pip install --upgrade pip setuptools wheel - displayName: 'Install tools' - - script: pip install -r requirements_conda.txt - displayName: 'Install Requirements Conda' - - script: pip install -r requirements.txt - displayName: 'Install Requirements' - - script: pip install onnxruntime - displayName: 'Install onnxruntime' - - script: | - python -u setup.py build_ext --inplace - displayName: 'Build package inplace' - - script: | - python -u setup.py unittests -d 20 - displayName: 'Runs Unit Tests' - - - job: 'TestMac' - pool: - vmImage: 'macOS-latest' - strategy: - matrix: - Python37-Mac: - python.version: '3.8' - maxParallel: 3 - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - architecture: 'x64' - - script: gcc --version - displayName: 'gcc version' - - script: brew update - displayName: 'brew update' - - script: export - displayName: 'export' - - script: gcc --version - displayName: 'gcc version' - - script: brew install llvm - displayName: 'install llvm' - - script: brew install p7zip - displayName: 'Install p7zip' - - script: brew install libomp - displayName: 'Install omp' - - script: brew install pandoc - displayName: 'Install Pandoc' - #- script: brew install graphviz - # displayName: 'Install Graphviz' - # - script: brew cask install mactex - # displayName: 'Install latex' - - script: python -m pip install --upgrade pip setuptools wheel - displayName: 'Install tools' - - script: brew install pybind11 - displayName: 'Install pybind11' - - script: pip install -r requirements_conda.txt - displayName: 'Install Requirements Conda' - - script: pip install -r requirements.txt - displayName: 'Install Requirements' - #- script: pip install -i https://test.pypi.org/simple/ ort-nightly - # displayName: 'Install ort-nightly' - - script: pip install onnxruntime - displayName: 'Install onnxruntime' - - script: | - export MACOSX_DEPLOYMENT_TARGET=10.14 - python setup.py build_ext --inplace - displayName: 'Build package inplace' - - script: | - python -u setup.py unittests -g ".*((LONG)|(SKIP)|(notebooks)).*" - displayName: 'Runs Unit Tests' - - script: | - python -u setup.py bdist_wheel - displayName: 'Build Package' - - task: PublishPipelineArtifact@0 - inputs: - artifactName: 'wheel-mac-$(python.version)' - targetPath: 'dist' +- job: 'TestMac' + pool: + vmImage: 'macOS-latest' + strategy: + matrix: + Python39-MacOs: + python.version: '3.9' + maxParallel: 3 + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + architecture: 'x64' + - script: gcc --version + displayName: 'gcc version' + - script: brew update + displayName: 'brew update' + - script: export + displayName: 'export' + - script: gcc --version + displayName: 'gcc version' + - script: brew install libomp + displayName: 'Install omp' + - script: brew install p7zip + displayName: 'Install p7zip' + - script: brew install pandoc + displayName: 'Install Pandoc' + - script: brew install graphviz + continueOnError: true + displayName: 'Install Graphviz' + - script: brew install cairo pango gdk-pixbuf libffi + displayName: 'Install cairo pango gdk-pixbuf libffi' + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH. + - bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + #- script: brew install --cask mactex + # continueOnError: true + # displayName: 'Install latex' + - bash: conda install -y -c conda-forge numpy scipy + displayName: Install numpy scipy + - bash: conda install -y -c conda-forge llvmlite numba pybind11 + displayName: Install llvmlite numba pybind11 + - script: pip install -r requirements.txt + displayName: 'Install Requirements' + #- script: pip install -i https://test.pypi.org/simple/ ort-nightly + # displayName: 'Install ort-nightly' + - script: pip install onnxruntime>=1.6.0 + displayName: 'Install onnxruntime' + - script: | + # export MACOSX_DEPLOYMENT_TARGET=10.13 + python setup.py build_ext --inplace + displayName: 'Build package inplace' + - script: python -u setup.py unittests -g ".*((LONG)|(SKIP)|(notebooks)).*" + displayName: 'Runs Unit Tests' + - script: python -u setup.py bdist_wheel + displayName: 'Build wheel' + - task: PublishPipelineArtifact@0 + inputs: + artifactName: 'wheel-mac-$(python.version)' + targetPath: 'dist' diff --git a/build_script.bat b/build_script.bat index 7688939ae..b92257b06 100644 --- a/build_script.bat +++ b/build_script.bat @@ -5,12 +5,8 @@ set pythonexe="%1" goto custom_python: :default_value_python: -set pythonexe="c:\Python372_x64\python.exe" -if not exist %pythonexe% set pythonexe="c:\Python370_x64\python.exe" -if not exist %pythonexe% set pythonexe="c:\Python366_x64\python.exe" -if not exist %pythonexe% set pythonexe="c:\Python365_x64\python.exe" -if not exist %pythonexe% set pythonexe="c:\Python364_x64\python.exe" -if not exist %pythonexe% set pythonexe="c:\Python363_x64\python.exe" +set pythonexe="c:\Python391_x64\python.exe" +if not exist %pythonexe% set pythonexe="c:\Python372_x64\python.exe" :custom_python: @echo [python] %pythonexe% %pythonexe% -u setup.py build_script diff --git a/mlprodict/__init__.py b/mlprodict/__init__.py index 5879f72f4..40c28057e 100644 --- a/mlprodict/__init__.py +++ b/mlprodict/__init__.py @@ -4,7 +4,7 @@ @brief Ways to speed up predictions for a machine learned model. """ -__version__ = "0.4.1357" +__version__ = "0.5.1368" __author__ = "Xavier Dupré" diff --git a/mlprodict/onnx_conv/scorers/cdist_score.py b/mlprodict/onnx_conv/scorers/cdist_score.py index 1025a2a9d..14386f8c1 100644 --- a/mlprodict/onnx_conv/scorers/cdist_score.py +++ b/mlprodict/onnx_conv/scorers/cdist_score.py @@ -4,6 +4,7 @@ :epkg:`cdist`. """ import numpy +from onnx import onnx_pb as onnx_proto from scipy.spatial.distance import cdist @@ -61,8 +62,13 @@ def convert_score_cdist_sum(scope, operator, container): axes=[1], keepdims=0, name=scope.get_unique_operator_name('ReduceSum')) else: - raise NotImplementedError( # pragma: no cover - "ReduceSum for opset>=13 is not impelmented yet.") + axis_name = scope.get_unique_variable_name('axis') + container.add_initializer( + axis_name, onnx_proto.TensorProto.INT64, [1], [1]) # pylint: disable=E1101 + container.add_node( + 'ReduceSum', [cdist_name, axis_name], + out[0].full_name, keepdims=0, + name=scope.get_unique_operator_name('ReduceSum')) else: metric = kwargs['metric'] if metric == 'minkowski': diff --git a/mlprodict/onnxrt/onnx_inference_node.py b/mlprodict/onnxrt/onnx_inference_node.py index c14f36924..a4c7594a5 100644 --- a/mlprodict/onnxrt/onnx_inference_node.py +++ b/mlprodict/onnxrt/onnx_inference_node.py @@ -155,11 +155,15 @@ def run(self, values): else: args = list(values[k] for k in self.inputs_indices) - res = self.ops_.run(*args) + try: + res = self.ops_.run(*args) + except TypeError as e: + raise RuntimeError( + "Unable to run operator %r." % type(self.ops_)) from e if not isinstance(res, tuple): raise RuntimeError( # pragma: no cover - "Results of an operator should be a tuple.") + "Results of operator %r should be a tuple." % type(self.ops_)) if len(self.outputs) != len(res): raise RuntimeError( # pragma: no cover "Mismatch number of outputs got {} for names {}.\n{}".format( diff --git a/mlprodict/onnxrt/ops_cpu/_op_list.py b/mlprodict/onnxrt/ops_cpu/_op_list.py index b4671a4f2..d060d0378 100644 --- a/mlprodict/onnxrt/ops_cpu/_op_list.py +++ b/mlprodict/onnxrt/ops_cpu/_op_list.py @@ -87,11 +87,11 @@ from .op_sign import Sign from .op_sin import Sin from .op_slice import Slice, Slice_1, Slice_10 -from .op_split import Split +from .op_split import Split, Split_2, Split_11, Split_13 from .op_softmax import Softmax from .op_solve import Solve from .op_sqrt import Sqrt -from .op_squeeze import Squeeze +from .op_squeeze import Squeeze, Squeeze_1, Squeeze_11, Squeeze_13 from .op_string_normalizer import StringNormalizer from .op_sub import Sub from .op_sum import Sum @@ -103,7 +103,7 @@ from .op_transpose import Transpose from .op_tree_ensemble_classifier import TreeEnsembleClassifier, TreeEnsembleClassifierDouble from .op_tree_ensemble_regressor import TreeEnsembleRegressor, TreeEnsembleRegressorDouble -from .op_unsqueeze import Unsqueeze +from .op_unsqueeze import Unsqueeze, Unsqueeze_1, Unsqueeze_11, Unsqueeze_13 from .op_where import Where from .op_zipmap import ZipMap diff --git a/mlprodict/onnxrt/ops_cpu/op_array_feature_extractor.py b/mlprodict/onnxrt/ops_cpu/op_array_feature_extractor.py index 1414a8a0e..42af26b42 100644 --- a/mlprodict/onnxrt/ops_cpu/op_array_feature_extractor.py +++ b/mlprodict/onnxrt/ops_cpu/op_array_feature_extractor.py @@ -7,11 +7,10 @@ import numpy from ._op import OpRun from ..shape_object import ShapeObject -from ._op_onnx_numpy import ( # pylint: disable=E0611 +from ._op_onnx_numpy import ( # pylint: disable=E0611,E0401 array_feature_extractor_double, array_feature_extractor_int64, - array_feature_extractor_float -) + array_feature_extractor_float) def _array_feature_extrator(data, indices): diff --git a/mlprodict/onnxrt/ops_cpu/op_conv.py b/mlprodict/onnxrt/ops_cpu/op_conv.py index 5b2bcfff6..44abda897 100644 --- a/mlprodict/onnxrt/ops_cpu/op_conv.py +++ b/mlprodict/onnxrt/ops_cpu/op_conv.py @@ -7,7 +7,7 @@ import numpy from ._op import OpRun from ..shape_object import ShapeObjectFct -from .op_conv_ import ConvFloat, ConvDouble # pylint: disable=E0611 +from .op_conv_ import ConvFloat, ConvDouble # pylint: disable=E0611,E0401 class Conv(OpRun): diff --git a/mlprodict/onnxrt/ops_cpu/op_conv_transpose.py b/mlprodict/onnxrt/ops_cpu/op_conv_transpose.py index 959ad02a3..3fd054281 100644 --- a/mlprodict/onnxrt/ops_cpu/op_conv_transpose.py +++ b/mlprodict/onnxrt/ops_cpu/op_conv_transpose.py @@ -7,7 +7,8 @@ import numpy from ._op import OpRun from ..shape_object import ShapeObjectFct -from .op_conv_transpose_ import ConvTransposeFloat, ConvTransposeDouble # pylint: disable=E0611 +from .op_conv_transpose_ import ( # pylint: disable=E0611,E0401 + ConvTransposeFloat, ConvTransposeDouble) class ConvTranspose(OpRun): diff --git a/mlprodict/onnxrt/ops_cpu/op_gather.py b/mlprodict/onnxrt/ops_cpu/op_gather.py index 4f4ac8153..109fd1be2 100644 --- a/mlprodict/onnxrt/ops_cpu/op_gather.py +++ b/mlprodict/onnxrt/ops_cpu/op_gather.py @@ -7,7 +7,7 @@ import numpy from ._op import OpRun from ..shape_object import ShapeObject -from .op_gather_ import ( # pylint: disable=E0611 +from .op_gather_ import ( # pylint: disable=E0611,E0401 GatherFloat, GatherDouble, GatherInt64) diff --git a/mlprodict/onnxrt/ops_cpu/op_max_pool.py b/mlprodict/onnxrt/ops_cpu/op_max_pool.py index 1029209a0..9718edc63 100644 --- a/mlprodict/onnxrt/ops_cpu/op_max_pool.py +++ b/mlprodict/onnxrt/ops_cpu/op_max_pool.py @@ -8,7 +8,7 @@ import numpy from ..shape_object import ShapeObjectFct from ._op import OpRun -from .op_max_pool_ import MaxPoolFloat, MaxPoolDouble # pylint: disable=E0611 +from .op_max_pool_ import MaxPoolFloat, MaxPoolDouble # pylint: disable=E0611,E0401 def _pool_get_output_shape(auto_pad, input_spatial_shape, kernel_spatial_shape, diff --git a/mlprodict/onnxrt/ops_cpu/op_reduce_sum.py b/mlprodict/onnxrt/ops_cpu/op_reduce_sum.py index 36bb94b38..9879de636 100644 --- a/mlprodict/onnxrt/ops_cpu/op_reduce_sum.py +++ b/mlprodict/onnxrt/ops_cpu/op_reduce_sum.py @@ -6,7 +6,7 @@ """ import numpy from onnx.defs import onnx_opset_version -from ._op import OpRunReduceNumpy, RuntimeTypeError +from ._op import OpRunReduceNumpy, RuntimeTypeError, OpRun class ReduceSum_1(OpRunReduceNumpy): @@ -51,12 +51,25 @@ def run(self, data, axes=None): # pylint: disable=E0202,W0221 data.dtype, res[0].dtype, self.__class__.__name__)) return res + def _run_no_checks_(self, x, axes=None): # pylint: disable=W0221 + return OpRun.run(self, x, axes) + def _run(self, data, axes=None): # pylint: disable=W0221 if axes is None and self.noop_with_empty_axes: return (data, ) - return (numpy.sum(data, axis=axes, - keepdims=self.keepdims, - dtype=data.dtype), ) + if axes is not None and not isinstance(axes, int): + if isinstance(axes, numpy.ndarray) and len(axes.shape) == 0: + axes = int(axes) + else: + axes = tuple(axes) if len(axes) > 0 else None + try: + return (numpy.sum(data, axis=axes, + keepdims=self.keepdims, + dtype=data.dtype), ) + except TypeError as e: + raise TypeError( + "Unable to reduce shape %r with axes=%r." % ( + data.shape, axes)) from e def infer_shapes(self, data, axes=None): # pylint: disable=E0202,W0221 return self._infer_shapes(data, axes=axes) diff --git a/mlprodict/onnxrt/ops_cpu/op_split.py b/mlprodict/onnxrt/ops_cpu/op_split.py index 8a3bd13e5..53770db5c 100644 --- a/mlprodict/onnxrt/ops_cpu/op_split.py +++ b/mlprodict/onnxrt/ops_cpu/op_split.py @@ -4,32 +4,30 @@ @file @brief Runtime operator. """ +from onnx.defs import onnx_opset_version from ._op import OpRun from ..shape_object import DimensionObject, ShapeObject -class Split(OpRun): +class CommonSplit(OpRun): """ Runtime for operator *Split*. """ - atts = {'axis': 0, 'split': None} - - def __init__(self, onnx_node, desc=None, **options): + def __init__(self, onnx_node, desc=None, + expected_attributes=None, **options): if 'split' not in options: options['split'] = None OpRun.__init__(self, onnx_node, desc=desc, - expected_attributes=Split.atts, + expected_attributes=expected_attributes, **options) self.nb_outputs = len(onnx_node.output) - def _run(self, mat): # pylint: disable=W0221 - if self.split is None: + def common_run(self, mat, split): # pylint: disable=W0221 + if split is None: div = mat.shape[self.axis] // self.nb_outputs split = [div] * self.nb_outputs split[-1] += mat.shape[self.axis] - sum(split) - else: - split = self.split sli = [slice(0, s) for s in mat.shape] res = [] pos = 0 @@ -39,12 +37,10 @@ def _run(self, mat): # pylint: disable=W0221 res.append(mat[tuple(sli)]) return tuple(res) - def _infer_shapes(self, data): # pylint: disable=W0221 - if self.split is None: + def common_infer_shapes(self, data, split): # pylint: disable=W0221 + if split is None: return tuple([ShapeObject(None, dtype=data.dtype) for o in range(self.nb_outputs)]) - split = self.split - res = [] pos = 0 for spl in split: @@ -53,3 +49,55 @@ def _infer_shapes(self, data): # pylint: disable=W0221 pos += spl res.append(shape) return tuple(res) + + +class Split_2(CommonSplit): + """ + Runtime for operator *Split*. + """ + + atts = {'axis': 0, 'split': None} + + def __init__(self, onnx_node, desc=None, **options): + CommonSplit.__init__(self, onnx_node, desc=desc, + expected_attributes=Split_2.atts, **options) + + def _run(self, mat): # pylint: disable=W0221 + return self.common_run(mat, self.split) + + def _infer_shapes(self, data): # pylint: disable=W0221 + return self.common_infer_shapes(data, self.split) + + +class Split_11(Split_2): + """ + Runtime for operator *Split*. + """ + pass + + +class Split_13(CommonSplit): + """ + Runtime for operator *Split*. + """ + + atts = {'axis': 0} + + def __init__(self, onnx_node, desc=None, **options): + CommonSplit.__init__(self, onnx_node, desc=desc, + expected_attributes=Split_13.atts, **options) + + def _run(self, mat, split=None): # pylint: disable=W0221 + return self.common_run(mat, split) + + def _infer_shapes(self, data, split=None): # pylint: disable=W0221 + return tuple([ShapeObject(None, dtype=data.dtype) + for o in range(self.nb_outputs)]) + + +if onnx_opset_version() >= 13: + Split = Split_13 +elif onnx_opset_version() >= 11: + Split = Split_11 +else: + Split = Split_2 diff --git a/mlprodict/onnxrt/ops_cpu/op_squeeze.py b/mlprodict/onnxrt/ops_cpu/op_squeeze.py index 2c1398e31..d789f669f 100644 --- a/mlprodict/onnxrt/ops_cpu/op_squeeze.py +++ b/mlprodict/onnxrt/ops_cpu/op_squeeze.py @@ -5,16 +5,18 @@ @brief Runtime operator. """ import numpy -from ._op import OpRunUnaryNum +from onnx.defs import onnx_opset_version +from ..shape_object import ShapeObject +from ._op import OpRunUnaryNum, OpRun -class Squeeze(OpRunUnaryNum): +class Squeeze_1(OpRunUnaryNum): atts = {'axes': [], 'keepdims': 1} def __init__(self, onnx_node, desc=None, **options): OpRunUnaryNum.__init__(self, onnx_node, desc=desc, - expected_attributes=Squeeze.atts, + expected_attributes=Squeeze_1.atts, **options) if isinstance(self.axes, numpy.ndarray): self.axes = tuple(self.axes) @@ -34,3 +36,38 @@ def _run(self, data): # pylint: disable=W0221 def _infer_shapes(self, x): # pylint: disable=W0221 return (x.squeeze(axis=self.axes), ) + + +class Squeeze_11(Squeeze_1): + pass + + +class Squeeze_13(OpRun): + + atts = {'keepdims': 1} + + def __init__(self, onnx_node, desc=None, **options): + OpRun.__init__(self, onnx_node, desc=desc, + expected_attributes=Squeeze_13.atts, + **options) + self.axes = None + + def _run(self, data, axes=None): # pylint: disable=W0221 + if axes is not None: + sq = data + for a in reversed(sorted(axes)): + sq = numpy.squeeze(sq, axis=a) + else: + sq = numpy.squeeze(data) + return (sq, ) + + def _infer_shapes(self, x, axes=None): # pylint: disable=W0221 + return (ShapeObject(None, dtype=x.dtype), ) + + +if onnx_opset_version() >= 13: + Squeeze = Squeeze_13 +elif onnx_opset_version() >= 11: + Squeeze = Squeeze_11 +else: + Squeeze = Squeeze_1 diff --git a/mlprodict/onnxrt/ops_cpu/op_svm_classifier.py b/mlprodict/onnxrt/ops_cpu/op_svm_classifier.py index ddba28272..cf328fb62 100644 --- a/mlprodict/onnxrt/ops_cpu/op_svm_classifier.py +++ b/mlprodict/onnxrt/ops_cpu/op_svm_classifier.py @@ -10,7 +10,7 @@ from ._op import OpRunClassifierProb, RuntimeTypeError from ._op_classifier_string import _ClassifierCommon from ._new_ops import OperatorSchema -from .op_svm_classifier_ import ( # pylint: disable=E0611 +from .op_svm_classifier_ import ( # pylint: disable=E0611,E0401 RuntimeSVMClassifierFloat, RuntimeSVMClassifierDouble, ) diff --git a/mlprodict/onnxrt/ops_cpu/op_svm_regressor.py b/mlprodict/onnxrt/ops_cpu/op_svm_regressor.py index 7f83aa42b..b4cbfcd87 100644 --- a/mlprodict/onnxrt/ops_cpu/op_svm_regressor.py +++ b/mlprodict/onnxrt/ops_cpu/op_svm_regressor.py @@ -9,7 +9,7 @@ from ._op_helper import _get_typed_class_attribute from ._op import OpRunUnaryNum, RuntimeTypeError from ._new_ops import OperatorSchema -from .op_svm_regressor_ import ( # pylint: disable=E0611 +from .op_svm_regressor_ import ( # pylint: disable=E0611,E0401 RuntimeSVMRegressorFloat, RuntimeSVMRegressorDouble, ) diff --git a/mlprodict/onnxrt/ops_cpu/op_tfidfvectorizer.py b/mlprodict/onnxrt/ops_cpu/op_tfidfvectorizer.py index 59a4e9bd2..eb78b7339 100644 --- a/mlprodict/onnxrt/ops_cpu/op_tfidfvectorizer.py +++ b/mlprodict/onnxrt/ops_cpu/op_tfidfvectorizer.py @@ -7,7 +7,7 @@ import numpy from ._op import OpRunUnary, RuntimeTypeError from ..shape_object import ShapeObject -from .op_tfidfvectorizer_ import RuntimeTfIdfVectorizer # pylint: disable=E0611 +from .op_tfidfvectorizer_ import RuntimeTfIdfVectorizer # pylint: disable=E0611,E0401 class TfIdfVectorizer(OpRunUnary): diff --git a/mlprodict/onnxrt/ops_cpu/op_topk.py b/mlprodict/onnxrt/ops_cpu/op_topk.py index 627c4de75..66d520069 100644 --- a/mlprodict/onnxrt/ops_cpu/op_topk.py +++ b/mlprodict/onnxrt/ops_cpu/op_topk.py @@ -7,7 +7,7 @@ import numpy from onnx.defs import onnx_opset_version from ._op import OpRun -from ._op_onnx_numpy import ( # pylint: disable=E0611 +from ._op_onnx_numpy import ( # pylint: disable=E0611,E0401 topk_element_min_double, topk_element_max_double, topk_element_fetch_double, topk_element_min_float, topk_element_max_float, topk_element_fetch_float, topk_element_min_int64, topk_element_max_int64, topk_element_fetch_int64) diff --git a/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier.py b/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier.py index 2943c6b36..4da9d7c73 100644 --- a/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier.py +++ b/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier.py @@ -10,11 +10,11 @@ from ._op import OpRunClassifierProb, RuntimeTypeError from ._op_classifier_string import _ClassifierCommon from ._new_ops import OperatorSchema -from .op_tree_ensemble_classifier_ import ( # pylint: disable=E0611 +from .op_tree_ensemble_classifier_ import ( # pylint: disable=E0611,E0401 RuntimeTreeEnsembleClassifierDouble, RuntimeTreeEnsembleClassifierFloat, ) -from .op_tree_ensemble_classifier_p_ import ( # pylint: disable=E0611 +from .op_tree_ensemble_classifier_p_ import ( # pylint: disable=E0611,E0401 RuntimeTreeEnsembleClassifierPFloat, RuntimeTreeEnsembleClassifierPDouble, ) diff --git a/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor.py b/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor.py index 146bb72fb..d1c7f211f 100644 --- a/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor.py +++ b/mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor.py @@ -9,9 +9,9 @@ from ._op_helper import _get_typed_class_attribute from ._op import OpRunUnaryNum, RuntimeTypeError from ._new_ops import OperatorSchema -from .op_tree_ensemble_regressor_ import ( # pylint: disable=E0611 +from .op_tree_ensemble_regressor_ import ( # pylint: disable=E0611,E0401 RuntimeTreeEnsembleRegressorFloat, RuntimeTreeEnsembleRegressorDouble) -from .op_tree_ensemble_regressor_p_ import ( # pylint: disable=E0611 +from .op_tree_ensemble_regressor_p_ import ( # pylint: disable=E0611,E0401 RuntimeTreeEnsembleRegressorPFloat, RuntimeTreeEnsembleRegressorPDouble) diff --git a/mlprodict/onnxrt/ops_cpu/op_unsqueeze.py b/mlprodict/onnxrt/ops_cpu/op_unsqueeze.py index 3b2e784bb..d944ac079 100644 --- a/mlprodict/onnxrt/ops_cpu/op_unsqueeze.py +++ b/mlprodict/onnxrt/ops_cpu/op_unsqueeze.py @@ -5,16 +5,18 @@ @brief Runtime operator. """ import numpy -from ._op import OpRunUnaryNum +from onnx.defs import onnx_opset_version +from ..shape_object import ShapeObject +from ._op import OpRunUnaryNum, OpRun -class Unsqueeze(OpRunUnaryNum): +class Unsqueeze_1(OpRunUnaryNum): - atts = {'axes': []} + atts = {'axes': [], 'keepdims': 1} def __init__(self, onnx_node, desc=None, **options): OpRunUnaryNum.__init__(self, onnx_node, desc=desc, - expected_attributes=Unsqueeze.atts, + expected_attributes=Unsqueeze_1.atts, **options) if isinstance(self.axes, numpy.ndarray): self.axes = tuple(self.axes) @@ -22,13 +24,52 @@ def __init__(self, onnx_node, desc=None, **options): self.axes = None elif isinstance(self.axes, list): self.axes = tuple(self.axes) - self.axes = tuple(sorted(self.axes)) def _run(self, data): # pylint: disable=W0221 - sq = data - for ax in self.axes: - sq = numpy.expand_dims(sq, axis=ax) + if isinstance(self.axes, (tuple, list)): + sq = data + for a in self.axes: + sq = numpy.expand_dims(sq, axis=a) + else: + raise RuntimeError( # pragma: no cover + "axes cannot be None for operator Unsqueeze (Unsqueeze_1).") return (sq, ) def _infer_shapes(self, x): # pylint: disable=W0221 return (x.unsqueeze(axes=self.axes), ) + + +class Unsqueeze_11(Unsqueeze_1): + pass + + +class Unsqueeze_13(OpRun): + + atts = {'keepdims': 1} + + def __init__(self, onnx_node, desc=None, **options): + OpRun.__init__(self, onnx_node, desc=desc, + expected_attributes=Unsqueeze_13.atts, + **options) + self.axes = None + + def _run(self, data, axes=None): # pylint: disable=W0221 + if axes is not None: + sq = data + for a in axes: + sq = numpy.expand_dims(sq, axis=a) + else: + raise RuntimeError( # pragma: no cover + "axes cannot be None for operator Unsqueeze (Unsqueeze_13).") + return (sq, ) + + def _infer_shapes(self, x, axes=None): # pylint: disable=W0221 + return (ShapeObject(None, dtype=x.dtype), ) + + +if onnx_opset_version() >= 13: + Unsqueeze = Unsqueeze_13 +elif onnx_opset_version() >= 11: + Unsqueeze = Unsqueeze_11 +else: + Unsqueeze = Unsqueeze_1 diff --git a/mlprodict/tools/asv_options_helper.py b/mlprodict/tools/asv_options_helper.py index d36faeeb7..083e76b47 100644 --- a/mlprodict/tools/asv_options_helper.py +++ b/mlprodict/tools/asv_options_helper.py @@ -72,7 +72,7 @@ def benchmark_version(): from mlprodict.tools.asv_options_helper import benchmark_version print(benchmark_version()) """ - return [12] + return [13] def ir_version(): diff --git a/requirements-win.txt b/requirements-win.txt new file mode 100644 index 000000000..c81b9be22 --- /dev/null +++ b/requirements-win.txt @@ -0,0 +1,21 @@ +astroid +cython +ijson +importlib_metadata +ipython +isort +joblib +jupyter +matplotlib +nbformat +numpy +pandas +psutil +pybind11 +pylint +pymyinstall +pyquickhelper +pyshp +scikit-learn +threadpoolctl +wheel diff --git a/requirements.txt b/requirements.txt index fcef1f4cc..296546858 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,33 @@ +# conda +cffi +Cython +datashape +jinja2 +joblib>=0.12 +jupyter +matplotlib +notebook>=5.0.0 +numba +numpy>=1.19.0 +pandas +pillow +scikit-learn>=0.23 +scipy +Sphinx +wheel + +# pip autopep8 -git+https://github.com/sdpython/asv.git@jenkins +asv +# git+https://github.com/sdpython/asv.git@jenkins chardet coverage>=5.0 cpyquickhelper jyquickhelper lightgbm memory_profiler -mlinsights>=0.2.491 +mlinsights>=0.3 nbconvert>=6.0.2 -onnx>=1.7.0 -git+https://github.com/xadupre/onnxconverter-common.git@jenkins openpyxl opt-einsum pybind11 @@ -18,11 +36,15 @@ pyensae py-cpuinfo pyinstrument pylint>=2.6.0 -pyquickhelper>=1.9.3396 -git+https://github.com/xadupre/sklearn-onnx.git@jenkins +pyquickhelper>=1.10 sphinx sphinxcontrib.blockdiag sphinx_gallery tqdm wheel xgboost + +# onnx +onnx>=1.8.0 +git+https://github.com/xadupre/onnxconverter-common.git@jenkins +git+https://github.com/xadupre/sklearn-onnx.git@jenkins diff --git a/requirements_conda.txt b/requirements_conda.txt deleted file mode 100644 index b83663689..000000000 --- a/requirements_conda.txt +++ /dev/null @@ -1,16 +0,0 @@ -cffi -Cython -datashape -jinja2 -joblib>=0.12 -jupyter -matplotlib -notebook>=5.0.0 -numba -numpy>=1.19.0 -pandas -pillow -scikit-learn>=0.23 -scipy -Sphinx -wheel diff --git a/setup.py b/setup.py index 0b26979e6..4b44231bf 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,8 @@ import sys import os import platform -from setuptools import setup, Extension -from setuptools import find_packages +import warnings +from setuptools import setup, Extension, find_packages ######### # settings @@ -28,13 +28,13 @@ 'Development Status :: 5 - Production/Stable' ] + ####### # data ####### -here = os.path.dirname(__file__) packages = find_packages() -package_dir = {k: os.path.join(here, k.replace(".", "/")) for k in packages} +package_dir = {k: os.path.join('.', k.replace(".", "/")) for k in packages} package_data = { project_var_name + ".asv_benchmark": ["*.json"], project_var_name + ".onnxrt.ops_cpu": ["*.cpp", "*.hpp"], @@ -216,225 +216,237 @@ def write_version(): extra_compile_args.append('-std=c++11') # extensions - ext_max_pool = Extension( - 'mlprodict.onnxrt.ops_cpu.op_max_pool_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_max_pool_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_gather = Extension( - 'mlprodict.onnxrt.ops_cpu.op_gather_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_gather_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_tree_ensemble_classifier = Extension( - 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_tree_ensemble_regressor = Extension( - 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_tree_ensemble_regressor_p = Extension( - 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor_p_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_svm_regressor = Extension( - 'mlprodict.onnxrt.ops_cpu.op_svm_regressor_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_svm_regressor_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_tfidfvectorizer = Extension( - 'mlprodict.onnxrt.ops_cpu.op_tfidfvectorizer_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tfidfvectorizer_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_tree_ensemble_classifier_p = Extension( - 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_p_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier_p_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_svm_classifier = Extension( - 'mlprodict.onnxrt.ops_cpu.op_svm_classifier_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_svm_classifier_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - op_onnx_numpy = Extension( - 'mlprodict.onnxrt.ops_cpu._op_onnx_numpy', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/_op_onnx_numpy.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_conv = Extension( - 'mlprodict.onnxrt.ops_cpu.op_conv_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_conv_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_conv_transpose = Extension( - 'mlprodict.onnxrt.ops_cpu.op_conv_transpose_', - [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_conv_transpose_.cpp'), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/onnxrt/ops_cpu') - ], - define_macros=define_macros, - language='c++') - - ext_experimental_c = Extension( - 'mlprodict.testing.experimental_c', - [os.path.join(root, 'mlprodict/testing/experimental_c.cpp')], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - include_dirs=[ - # Path to pybind11 headers - get_pybind_include(), - get_pybind_include(user=True), - os.path.join(root, 'mlprodict/testing') - ], - define_macros=define_macros, - language='c++') - - ext_modules = [ - ext_conv, - ext_conv_transpose, - ext_experimental_c, - ext_gather, - ext_max_pool, - ext_svm_classifier, - ext_svm_regressor, - ext_tfidfvectorizer, - ext_tree_ensemble_classifier, - ext_tree_ensemble_classifier_p, - ext_tree_ensemble_regressor, - ext_tree_ensemble_regressor_p, - op_onnx_numpy, - ] + + def get_extensions(): + ext_max_pool = Extension( + 'mlprodict.onnxrt.ops_cpu.op_max_pool_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_max_pool_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_gather = Extension( + 'mlprodict.onnxrt.ops_cpu.op_gather_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_gather_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_tree_ensemble_classifier = Extension( + 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_tree_ensemble_regressor = Extension( + 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_tree_ensemble_regressor_p = Extension( + 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_regressor_p_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_regressor_p_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_svm_regressor = Extension( + 'mlprodict.onnxrt.ops_cpu.op_svm_regressor_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_svm_regressor_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_tfidfvectorizer = Extension( + 'mlprodict.onnxrt.ops_cpu.op_tfidfvectorizer_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tfidfvectorizer_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_tree_ensemble_classifier_p = Extension( + 'mlprodict.onnxrt.ops_cpu.op_tree_ensemble_classifier_p_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_tree_ensemble_classifier_p_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_svm_classifier = Extension( + 'mlprodict.onnxrt.ops_cpu.op_svm_classifier_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_svm_classifier_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + op_onnx_numpy = Extension( + 'mlprodict.onnxrt.ops_cpu._op_onnx_numpy', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/_op_onnx_numpy.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_num_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_conv = Extension( + 'mlprodict.onnxrt.ops_cpu.op_conv_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_conv_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_conv_transpose = Extension( + 'mlprodict.onnxrt.ops_cpu.op_conv_transpose_', + [os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_conv_transpose_.cpp'), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu/op_common_.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/onnxrt/ops_cpu') + ], + define_macros=define_macros, + language='c++') + + ext_experimental_c = Extension( + 'mlprodict.testing.experimental_c', + [os.path.join(root, 'mlprodict/testing/experimental_c.cpp')], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + include_dirs=[ + # Path to pybind11 headers + get_pybind_include(), + get_pybind_include(user=True), + os.path.join(root, 'mlprodict/testing') + ], + define_macros=define_macros, + language='c++') + + ext_modules = [ + ext_conv, + ext_conv_transpose, + ext_experimental_c, + ext_gather, + ext_max_pool, + ext_svm_classifier, + ext_svm_regressor, + ext_tfidfvectorizer, + ext_tree_ensemble_classifier, + ext_tree_ensemble_classifier_p, + ext_tree_ensemble_regressor, + ext_tree_ensemble_regressor_p, + op_onnx_numpy, + ] + return ext_modules + + try: + ext_modules = get_extensions() + except ImportError as e: + warnings.warn( + "Unable to build C++ extension with missing dependencies %r." % e) + ext_modules = None + + # setup setup( name=project_var_name, @@ -452,22 +464,22 @@ def write_version(): packages=packages, package_dir=package_dir, package_data=package_data, - setup_requires=["pybind11", "numpy", "onnx>=1.7", "scikit-learn>=0.21", + setup_requires=["pybind11", "numpy", "onnx>=1.7", "scikit-learn>=0.23", "jinja2", 'cython'], install_requires=["pybind11", "numpy>=1.17", "onnx>=1.7", 'scipy>=1.0.0', 'jinja2', 'cython'], extras_require={ - 'onnx_conv': ['scikit-learn>=0.21', 'skl2onnx>=1.7', - 'joblib', 'threadpoolctl', 'mlinsights>=0.2.450', + 'onnx_conv': ['scikit-learn>=0.23', 'skl2onnx>=1.7', + 'joblib', 'threadpoolctl', 'mlinsights>=0.3', 'lightgbm', 'xgboost'], - 'sklapi': ['scikit-learn>=0.21', 'joblib', 'threadpoolctl'], - 'onnx_val': ['scikit-learn>=0.21', 'skl2onnx>=1.7', - 'onnxconverter-common>=1.7', - 'onnxruntime>=1.1.0', 'joblib', 'threadpoolctl'], - 'all': ['scikit-learn>=0.21', 'skl2onnx>=1.7', + 'sklapi': ['scikit-learn>=0.23', 'joblib', 'threadpoolctl'], + 'onnx_val': ['scikit-learn>=0.23', 'skl2onnx>=1.7', + 'onnxconverter-common>=1.8', + 'onnxruntime>=1.6.0', 'joblib', 'threadpoolctl'], + 'all': ['scikit-learn>=0.23', 'skl2onnx>=1.7', 'onnxconverter-common>=1.7', - 'onnxruntime>=1.4.0', 'scipy' 'joblib', 'pandas', - 'threadpoolctl', 'mlinsights>=0.2.450', + 'onnxruntime>=1.6.0', 'scipy' 'joblib', 'pandas', + 'threadpoolctl', 'mlinsights>=0.3', 'lightgbm', 'xgboost'], }, )