From 81a040ccb33dd9f56e510b4f492468b93913b91f Mon Sep 17 00:00:00 2001 From: mwootton Date: Tue, 16 Aug 2022 04:47:37 +0000 Subject: [PATCH] Update Python API docs to commit eb6aa86 --- docs/api/python/.buildinfo | 2 +- docs/api/python/api_summary.html | 308 ++++--- docs/api/python/auto_examples/index.html | 105 +-- .../python/auto_examples/plot_backend.html | 24 +- .../auto_examples/plot_common_errors.html | 56 +- .../plot_convert_pipeline_vectorizer.html | 61 +- .../auto_examples/plot_load_and_predict.html | 54 +- .../python/auto_examples/plot_metadata.html | 20 +- .../python/auto_examples/plot_pipeline.html | 41 +- .../python/auto_examples/plot_profiling.html | 41 +- .../plot_train_convert_predict.html | 167 ++-- .../auto_examples/sg_execution_times.html | 31 +- .../auto_examples_python.zip | Bin 23740 -> 23574 bytes .../plot_train_convert_predict.ipynb | 30 +- .../plot_common_errors.ipynb | 6 +- .../plot_load_and_predict.ipynb | 8 +- .../plot_pipeline.ipynb | 12 +- .../plot_common_errors.py | 37 +- .../plot_convert_pipeline_vectorizer.ipynb | 12 +- .../plot_backend.py | 9 +- .../auto_examples_jupyter.zip | Bin 41075 -> 40970 bytes .../plot_load_and_predict.py | 8 +- .../plot_metadata.py | 3 + .../plot_metadata.ipynb | 4 +- .../plot_convert_pipeline_vectorizer.py | 23 +- .../plot_train_convert_predict.py | 47 +- .../plot_profiling.ipynb | 4 +- .../plot_profiling.py | 10 +- .../plot_pipeline.py | 25 +- .../plot_backend.ipynb | 6 +- docs/api/python/examples_md.html | 9 +- docs/api/python/genindex.html | 35 +- .../images/sphx_glr_plot_pipeline_001.png | Bin 33881 -> 33881 bytes ...phx_glr_plot_train_convert_predict_001.png | Bin 29828 -> 30302 bytes ...x_glr_plot_train_convert_predict_thumb.png | Bin 23337 -> 23421 bytes docs/api/python/index.html | 13 +- docs/api/python/modules/index.html | 10 +- .../onnxruntime_inference_collection.html | 383 +++++---- .../python/modules/onnxruntime/datasets.html | 127 --- docs/api/python/objects.inv | Bin 1931 -> 1940 bytes docs/api/python/search.html | 7 +- docs/api/python/searchindex.js | 2 +- docs/api/python/sources/api_summary.rst.txt | 192 +++-- .../sources/auto_examples/index.rst.txt | 130 ++- .../auto_examples/plot_backend.rst.txt | 42 +- .../auto_examples/plot_common_errors.rst.txt | 92 +- .../plot_convert_pipeline_vectorizer.rst.txt | 104 +-- .../plot_load_and_predict.rst.txt | 75 +- .../auto_examples/plot_metadata.rst.txt | 32 +- .../auto_examples/plot_pipeline.rst.txt | 70 +- .../auto_examples/plot_profiling.rst.txt | 65 +- .../plot_train_convert_predict.rst.txt | 242 +++--- .../auto_examples/sg_execution_times.rst.txt | 16 +- .../_sphinx_javascript_frameworks_compat.js | 134 +++ docs/api/python/static/basic.css | 16 +- docs/api/python/static/doctools.js | 449 +++++----- .../python/static/documentation_options.js | 6 +- docs/api/python/static/graphviz.css | 2 +- .../{jquery-3.5.1.js => jquery-3.6.0.js} | 227 ++--- docs/api/python/static/jquery.js | 4 +- docs/api/python/static/language_data.js | 102 +-- docs/api/python/static/searchtools.js | 789 +++++++++--------- .../python/static/sg_gallery-dataframe.css | 18 +- .../static/sg_gallery-rendered-html.css | 37 +- docs/api/python/static/sg_gallery.css | 238 ++++-- docs/api/python/tutorial.html | 25 +- 66 files changed, 2495 insertions(+), 2352 deletions(-) delete mode 100644 docs/api/python/modules/onnxruntime/datasets.html create mode 100644 docs/api/python/static/_sphinx_javascript_frameworks_compat.js rename docs/api/python/static/{jquery-3.5.1.js => jquery-3.6.0.js} (98%) diff --git a/docs/api/python/.buildinfo b/docs/api/python/.buildinfo index edb6d7ef139e4..6d32c9085786e 100644 --- a/docs/api/python/.buildinfo +++ b/docs/api/python/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 36e772eb12f6d489cf39825d3e063ad4 +config: 8e1f5fa515073dcc8e8815ff920f1477 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/api/python/api_summary.html b/docs/api/python/api_summary.html index 81645aeb66670..383ecb6ef0b11 100644 --- a/docs/api/python/api_summary.html +++ b/docs/api/python/api_summary.html @@ -6,7 +6,7 @@ - API Summary — ONNX Runtime 1.11.0 documentation + API — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -38,88 +39,125 @@
-
-

API Summary

-

Summary of public functions and classes exposed -in ONNX Runtime.

+
+

API

-
-

OrtValue

-

ONNX Runtime works with native Python data structures which are mapped into ONNX data formats : -Numpy arrays (tensors), dictionaries (maps), and a list of Numpy arrays (sequences). -The data backing these are on CPU.

-

ONNX Runtime supports a custom data structure that supports all ONNX data formats that allows users -to place the data backing these on a device, for example, on a CUDA supported device. This allows for -interesting IOBinding scenarios (discussed below). In addition, ONNX Runtime supports directly -working with OrtValue (s) while inferencing a model if provided as part of the input feed.

-

Below is an example showing creation of an OrtValue from a Numpy array while placing its backing memory -on a CUDA device:

-
# X is numpy array on cpu, create an OrtValue and place it on cuda device id = 0
-ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0)
-ortvalue.device_name()  # 'cuda'
-ortvalue.shape()  # shape of the numpy array X
-ortvalue.data_type()  # 'tensor(float)'
-ortvalue.is_tensor()  # 'True'
+
+

API Overview

+

ONNX Runtime loads and runs inference on a model in ONNX graph format, or ORT format (for memory and disk constrained environments).

+

The data consumed and produced by the model can be specified and accessed in the way that best matches your scenario.

+
+

Load and run a model

+

InferenceSession is the main class of ONNX Runtime. It is used to load and run an ONNX model, +as well as specify environment and application configuration options.

+
session = onnxruntime.InferenceSession('model.onnx')
+
+outputs = session.run([output names], inputs)
+
+
+

ONNX and ORT format models consist of a graph of computations, modeled as operators, +and implemented as optimized operator kernels for different hardware targets. +ONNX Runtime orchestrates the execution of operator kernels via execution providers. +An execution provider contains the set of kernels for a specific execution target (CPU, GPU, IoT etc). +Execution provides are configured using the providers parameter. Kernels from different execution +providers are chosen in the priority order given in the list of providers. In the example below +if there is a kernel in the CUDA execution provider ONNX Runtime executes that on GPU. If not +the kernel is executed on CPU.

+
session = onnxruntime.InferenceSession(model,
+                                       providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
+
+
+

The list of available execution providers can be found here: Execution Providers.

+

Since ONNX Runtime 1.10, you must explicitly specify the execution provider for your target. +Running on CPU is the only time the API allows no explicit setting of the provider parameter. +In the examples that follow, the CUDAExecutionProvider and CPUExecutionProvider are used, assuming the application is running on NVIDIA GPUs. +Replace these with the execution provider specific to your environment.

+

You can supply other session configurations via the session options parameter. For example, to enable +profiling on the session:

+
options = onnxruntime.SessionOptions()
+options.enable_profiling=True
+session = onnxruntime.InferenceSession('model.onnx', sess_options=options, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']))
+
+
+
+
+

Data inputs and outputs

+

The ONNX Runtime Inference Session consumes and produces data using its OrtValue class.

+
+

Data on CPU

+

On CPU (the default), OrtValues can be mapped to and from native Python data structures: numpy arrays, dictionaries and lists of +numpy arrays.

+
# X is numpy array on cpu
+ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X)
+ortvalue.device_name()  # 'cpu'
+ortvalue.shape()        # shape of the numpy array X
+ortvalue.data_type()    # 'tensor(float)'
+ortvalue.is_tensor()    # 'True'
 np.array_equal(ortvalue.numpy(), X)  # 'True'
 
 # ortvalue can be provided as part of the input feed to a model
-ses = onnxruntime.InferenceSession('model.onnx')
-res = sess.run(["Y"], {"X": ortvalue})
+session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider']))
+results = session.run(["Y"], {"X": ortvalue})
 
+

By default, ONNX Runtime always places input(s) and output(s) on CPU. Having the data on CPU +may not optimal if the input or output is consumed and produced on a device +other than CPU because it introduces data copy between CPU and the device.

-
-

IOBinding

-

By default, ONNX Runtime always places input(s) and output(s) on CPU, which -is not optimal if the input or output is consumed and produced on a device -other than CPU because it introduces data copy between CPU and the device. -ONNX Runtime provides a feature, IO Binding, which addresses this issue by -enabling users to specify which device to place input(s) and output(s) on. -Here are scenarios to use this feature.

-

(In the following code snippets, model.onnx is the model to execute, -X is the input data to feed, and Y is the output data.)

-

Scenario 1:

+
+

Data on device

+

ONNX Runtime supports a custom data structure that supports all ONNX data formats that allows users +to place the data backing these on a device, for example, on a CUDA supported device. In ONNX Runtime, +this called IOBinding.

+

To use the IOBinding feature, replace InferenceSession.run() with InferenceSession.run_with_iobinding().

A graph is executed on a device other than CPU, for instance CUDA. Users can -use IOBinding to put input on CUDA as the follows.

+use IOBinding to copy the data onto the GPU.

# X is numpy array on cpu
-session = onnxruntime.InferenceSession('model.onnx')
+session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider']))
 io_binding = session.io_binding()
 # OnnxRuntime will copy the data over to the CUDA device if 'input' is consumed by nodes on the CUDA device
 io_binding.bind_cpu_input('input', X)
@@ -128,11 +166,10 @@ 

IOBindingY = io_binding.copy_outputs_to_cpu()[0]

-

Scenario 2:

The input data is on a device, users directly use the input. The output data is on CPU.

-

Scenario 3:

The input data and output data are both on a device, users directly use the input and also place output on the device.

#X is numpy array on cpu
 X_ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0)
 Y_ortvalue = onnxruntime.OrtValue.ortvalue_from_shape_and_type([3, 2], np.float32, 'cuda', 0)  # Change the shape to the actual shape of the output being bound
-session = onnxruntime.InferenceSession('model.onnx')
+session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider']))
 io_binding = session.io_binding()
 io_binding.bind_input(name='input', device_type=X_ortvalue.device_name(), device_id=0, element_type=np.float32, shape=X_ortvalue.shape(), buffer_ptr=X_ortvalue.data_ptr())
 io_binding.bind_output(name='output', device_type=Y_ortvalue.device_name(), device_id=0, element_type=np.float32, shape=Y_ortvalue.shape(), buffer_ptr=Y_ortvalue.data_ptr())
 session.run_with_iobinding(io_binding)
 
-

Scenario 4:

Users can request ONNX Runtime to allocate an output on a device. This is particularly useful for dynamic shaped outputs. Users can use the get_outputs() API to get access to the OrtValue (s) corresponding to the allocated output(s). Users can thus consume the ONNX Runtime allocated memory for the output as an OrtValue.

-

Scenario 5:

+

In addition, ONNX Runtime supports directly working with OrtValue (s) while inferencing a model if provided as part of the input feed.

Users can bind OrtValue (s) directly.

#X is numpy array on cpu
 #X is numpy array on cpu
 X_ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0)
 Y_ortvalue = onnxruntime.OrtValue.ortvalue_from_shape_and_type([3, 2], np.float32, 'cuda', 0)  # Change the shape to the actual shape of the output being bound
-session = onnxruntime.InferenceSession('model.onnx')
+session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider']))
 io_binding = session.io_binding()
 io_binding.bind_ortvalue_input('input', X_ortvalue)
 io_binding.bind_ortvalue_output('output', Y_ortvalue)
 session.run_with_iobinding(io_binding)
 
+

You can also bind inputs and outputs directly to a PyTorch tensor.

+
# X is a PyTorch tensor on device
+session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider']))
+binding = session.io_binding()
+
+X_tensor = X.contiguous()
+
+binding.bind_input(
+    name='X',
+    device_type='cuda',
+    device_id=0,
+    element_type=np.float32,
+    shape=tuple(x_tensor.shape),
+    buffer_ptr=x_tensor.data_ptr(),
+    )
+
+## Allocate the PyTorch tensor for the model output
+Y_shape = ... # You need to specify the output PyTorch tensor shape
+Y_tensor = torch.empty(Y_shape, dtype=torch.float32, device='cuda:0').contiguous()
+binding.bind_output(
+    name='Y',
+    device_type='cuda',
+    device_id=0,
+    element_type=np.float32,
+    shape=tuple(Y_tensor.shape),
+    buffer_ptr=Y_tensor.data_ptr(),
+)
+
+session.run_with_iobinding(binding)
+
+
-
-

Device

-

The package is compiled for a specific device, GPU or CPU. -The CPU implementation includes optimizations -such as MKL (Math Kernel Libary). The following function -indicates the chosen option:

-
-
-onnxruntime.get_device() str
-

Return the device used to compute the prediction (CPU, MKL, …)

-
-
-
-

Examples and datasets

-

The package contains a few models stored in ONNX format -used in the documentation. These don’t need to be downloaded -as they are installed with the package.

-
-
-onnxruntime.datasets.get_example(name)[source]
-

Retrieves the absolute file name of an example.

-
-
-
-

Load and run a model

-

ONNX Runtime reads a model saved in ONNX format. -The main class InferenceSession wraps these functionalities -in a single place.

-
-

Main class

+
+

API Details

+
+

InferenceSession

class onnxruntime.InferenceSession(path_or_bytes, sess_options=None, providers=None, provider_options=None, **kwargs)[source]
@@ -339,6 +379,10 @@

Main class

run_options – See onnxruntime.RunOptions.

+
Returns
+

list of results, every result is either a numpy array, +a sparse tensor, a list or a dictionary.

+

sess.run([output_name], {input_name: x})
 
@@ -367,7 +411,7 @@

Main classParameters

- + @@ -1199,7 +1277,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/index.html b/docs/api/python/auto_examples/index.html index 88c529d5e42e1..375bb3e3ab934 100644 --- a/docs/api/python/auto_examples/index.html +++ b/docs/api/python/auto_examples/index.html @@ -6,7 +6,7 @@ - Gallery of examples — ONNX Runtime 1.11.0 documentation + Gallery of examples — ONNX Runtime 1.13.0 documentation @@ -17,11 +17,12 @@ + - + @@ -39,74 +40,36 @@
-

Out:

Misspelled input name
 <class 'onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument'>: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid Feed Input Name:misspelled
 
@@ -128,12 +126,12 @@

onnxruntime does not necessarily fail if the input dimension is a multiple of the expected input dimension.

for x in [
-        numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),
-        numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),
-        numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),
-        numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),
-        numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),
-        ]:
+    numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),
+    numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),
+    numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),
+    numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),
+    numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),
+]:
     try:
         r = sess.run([output_name], {input_name: x})
         print("Shape={0} and predicted labels={1}".format(x.shape, r))
@@ -141,12 +139,12 @@
         print("ERROR with Shape={0} - {1}".format(x.shape, e))
 
 for x in [
-        numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),
-        numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),
-        numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),
-        numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),
-        numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),
-        ]:
+    numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),
+    numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),
+    numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),
+    numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),
+    numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),
+]:
     try:
         r = sess.run(None, {input_name: x})
         print("Shape={0} and predicted probabilities={1}".format(x.shape, r[1]))
@@ -154,7 +152,6 @@
         print("ERROR with Shape={0} - {1}".format(x.shape, e))
 
-

Out:

ERROR with Shape=(4,) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: float_input Got: 1 Expected: 2 Please fix either the inputs or the model.
 ERROR with Shape=(1, 4) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: float_input for the following indices
  index: 0 Got: 1 Expected: 3
@@ -186,10 +183,10 @@
 

It does not fail either if the number of dimension is higher than expects but produces a warning.

for x in [
-        numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32),
-        numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32),
-        numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32),
-        ]:
+    numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32),
+    numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32),
+    numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32),
+]:
     try:
         r = sess.run([output_name], {input_name: x})
         print("Shape={0} and predicted labels={1}".format(x.shape, r))
@@ -197,14 +194,13 @@
         print("ERROR with Shape={0} - {1}".format(x.shape, e))
 
-

Out:

ERROR with Shape=(1, 2, 2) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: float_input Got: 3 Expected: 2 Please fix either the inputs or the model.
 ERROR with Shape=(1, 1, 3) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: float_input Got: 3 Expected: 2 Please fix either the inputs or the model.
 ERROR with Shape=(2, 1, 2) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: float_input Got: 3 Expected: 2 Please fix either the inputs or the model.
 

Total running time of the script: ( 0 minutes 0.009 seconds)

- - + @@ -278,7 +274,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/plot_convert_pipeline_vectorizer.html b/docs/api/python/auto_examples/plot_convert_pipeline_vectorizer.html index 063fe38ba0cb9..1c6dd123afd1d 100644 --- a/docs/api/python/auto_examples/plot_convert_pipeline_vectorizer.html +++ b/docs/api/python/auto_examples/plot_convert_pipeline_vectorizer.html @@ -6,7 +6,7 @@ - Train, convert and predict with ONNX Runtime — ONNX Runtime 1.11.0 documentation + Train, convert and predict with ONNX Runtime — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -44,7 +45,7 @@ to download the full example code

-

Train, convert and predict with ONNX Runtime

+

Train, convert and predict with ONNX Runtime

This example demonstrates an end to end scenario starting with the training of a scikit-learn pipeline which takes as inputs not a regular vector but a @@ -57,20 +58,21 @@

-

Train a pipeline

+

Train a pipeline

The first step consists in retrieving the boston datset.

import pandas
 from sklearn.datasets import load_boston
+
 boston = load_boston()
 X, y = boston.data, boston.target
 
 from sklearn.model_selection import train_test_split
+
 X_train, X_test, y_train, y_test = train_test_split(X, y)
-X_train_dict = pandas.DataFrame(X_train[:,1:]).T.to_dict().values()
-X_test_dict = pandas.DataFrame(X_test[:,1:]).T.to_dict().values()
+X_train_dict = pandas.DataFrame(X_train[:, 1:]).T.to_dict().values()
+X_test_dict = pandas.DataFrame(X_test[:, 1:]).T.to_dict().values()
 
-

Out:

/home/runner/.local/lib/python3.8/site-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function load_boston is deprecated; `load_boston` is deprecated in 1.0 and will be removed in 1.2.
 
     The Boston housing prices dataset has an ethical problem. You can refer to
@@ -86,7 +88,6 @@ 

Train a pipelineTrain a pipeline

We create a pipeline.

-
from sklearn.pipeline import make_pipeline
-from sklearn.ensemble import GradientBoostingRegressor
+
from sklearn.ensemble import GradientBoostingRegressor
 from sklearn.feature_extraction import DictVectorizer
-pipe = make_pipeline(
-            DictVectorizer(sparse=False),
-            GradientBoostingRegressor())
+from sklearn.pipeline import make_pipeline
+
+pipe = make_pipeline(DictVectorizer(sparse=False), GradientBoostingRegressor())
 
 pipe.fit(X_train_dict, y_train)
 
-

Out:

-
Pipeline(steps=[('dictvectorizer', DictVectorizer(sparse=False)),
-                ('gradientboostingregressor', GradientBoostingRegressor())])
-
+
+
Pipeline(steps=[('dictvectorizer', DictVectorizer(sparse=False)),
+                ('gradientboostingregressor', GradientBoostingRegressor())])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
-

We compute the prediction on the test set +
+

We compute the prediction on the test set and we show the confusion matrix.

-

Out:

-
0.9209977605173356
+
0.8843586896936388
 
-

Conversion to ONNX format

+

Conversion to ONNX format

We use module sklearn-onnx to convert the model into ONNX format.

from skl2onnx import convert_sklearn
-from skl2onnx.common.data_types import FloatTensorType, Int64TensorType, DictionaryType, SequenceType
+from skl2onnx.common.data_types import DictionaryType, FloatTensorType, Int64TensorType, SequenceType
 
 # initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]
-initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]
+initial_type = [("float_input", DictionaryType(Int64TensorType([1]), FloatTensorType([])))]
 onx = convert_sklearn(pipe, initial_types=initial_type)
 with open("pipeline_vectorize.onnx", "wb") as f:
     f.write(onx.SerializeToString())
@@ -161,12 +160,12 @@ 

Conversion to ONNX formatsess = rt.InferenceSession("pipeline_vectorize.onnx", providers=rt.get_available_providers()) import numpy + inp, out = sess.get_inputs()[0], sess.get_outputs()[0] print("input name='{}' and shape={} and type={}".format(inp.name, inp.shape, inp.type)) print("output name='{}' and shape={} and type={}".format(out.name, out.shape, out.type))

-

Out:

-

Out:

[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Unexpected input data type. Actual: ((seq(map(int64,tensor(float))))) , expected: ((map(int64,tensor(float))))
 
@@ -192,14 +190,13 @@

Conversion to ONNX format
print(r2_score(pred, pred_onx))
 

-

Out:

-
0.9999999999999366
+
0.9999999999999561
 

Very similar. ONNX Runtime uses floats instead of doubles, that explains the small discrepencies.

-

Total running time of the script: ( 0 minutes 0.966 seconds)

-
- + @@ -274,7 +271,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/plot_load_and_predict.html b/docs/api/python/auto_examples/plot_load_and_predict.html index 4a088a2b907c4..6cbc374ea28cc 100644 --- a/docs/api/python/auto_examples/plot_load_and_predict.html +++ b/docs/api/python/auto_examples/plot_load_and_predict.html @@ -6,7 +6,7 @@ - Load and predict with ONNX Runtime and a very simple model — ONNX Runtime 1.11.0 documentation + Load and predict with ONNX Runtime and a very simple model — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -44,12 +45,13 @@ to download the full example code

-

Load and predict with ONNX Runtime and a very simple model

+

Load and predict with ONNX Runtime and a very simple model

This example demonstrates how to load a model and compute the output for an input vector. It also shows how to retrieve the definition of its inputs and outputs.

-
import onnxruntime as rt
-import numpy
+
import numpy
+
+import onnxruntime as rt
 from onnxruntime.datasets import get_example
 
@@ -68,7 +70,6 @@ print("input type", input_type)
-

Out:

input name x
 input shape [3, 4, 5]
 input type tensor(float)
@@ -83,7 +84,6 @@
 print("output type", output_type)
 
-

Out:

output name y
 output shape [3, 4, 5]
 output type tensor(float)
@@ -91,32 +91,32 @@
 

Let’s compute its outputs (or predictions if it is a machine learned model).

import numpy.random
-x = numpy.random.random((3,4,5))
+
+x = numpy.random.random((3, 4, 5))
 x = x.astype(numpy.float32)
 res = sess.run([output_name], {input_name: x})
 print(res)
 
-

Out:

-
[array([[[0.6423601 , 0.65232253, 0.6620137 , 0.708999  , 0.65169865],
-        [0.548968  , 0.59544575, 0.7161434 , 0.525905  , 0.7210646 ],
-        [0.5178277 , 0.5842683 , 0.5627599 , 0.6324704 , 0.5833795 ],
-        [0.69634616, 0.60848683, 0.6746977 , 0.50677085, 0.5549751 ]],
-
-       [[0.5097179 , 0.59407187, 0.56360227, 0.7223234 , 0.5392329 ],
-        [0.5398089 , 0.5622808 , 0.5369593 , 0.5819309 , 0.5735331 ],
-        [0.5688669 , 0.71247685, 0.63964766, 0.63349843, 0.63380575],
-        [0.64378905, 0.60552883, 0.5184905 , 0.6312441 , 0.5047166 ]],
-
-       [[0.63900065, 0.6108959 , 0.5249817 , 0.5055595 , 0.55390376],
-        [0.62443805, 0.550723  , 0.5320551 , 0.5522731 , 0.68858314],
-        [0.69650024, 0.54673976, 0.56964463, 0.58536506, 0.5743989 ],
-        [0.6382853 , 0.5826889 , 0.53635114, 0.52279866, 0.7300966 ]]],
+
[array([[[0.6362598 , 0.69637424, 0.66820115, 0.66656613, 0.66833836],
+        [0.6735109 , 0.7306087 , 0.5827978 , 0.5790133 , 0.5281905 ],
+        [0.5875758 , 0.5256195 , 0.5485236 , 0.6221244 , 0.6873636 ],
+        [0.6726905 , 0.6112579 , 0.52476424, 0.54415625, 0.67545795]],
+
+       [[0.5092699 , 0.69676566, 0.70407355, 0.64738125, 0.59030807],
+        [0.5806675 , 0.56875795, 0.5390076 , 0.54938734, 0.7169268 ],
+        [0.6765016 , 0.6001371 , 0.7239268 , 0.50898796, 0.7079662 ],
+        [0.6985444 , 0.5496287 , 0.6313638 , 0.51122195, 0.65290225]],
+
+       [[0.5237154 , 0.671646  , 0.57126474, 0.6550032 , 0.554477  ],
+        [0.5734256 , 0.53975654, 0.69029194, 0.6799297 , 0.5502332 ],
+        [0.5855049 , 0.68936455, 0.5244481 , 0.6527785 , 0.50686556],
+        [0.512562  , 0.6157843 , 0.6511187 , 0.7200693 , 0.62636346]]],
       dtype=float32)]
 
-

Total running time of the script: ( 0 minutes 0.013 seconds)

- - + @@ -190,7 +190,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/plot_metadata.html b/docs/api/python/auto_examples/plot_metadata.html index c17fbe6318ce8..3527bf225d663 100644 --- a/docs/api/python/auto_examples/plot_metadata.html +++ b/docs/api/python/auto_examples/plot_metadata.html @@ -6,7 +6,7 @@ - Metadata — ONNX Runtime 1.11.0 documentation + Metadata — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -44,7 +45,7 @@ to download the full example code

-

Metadata

+

Metadata

ONNX format contains metadata related to how the model was produced. It is useful when the model is deployed to production to keep track of which @@ -53,9 +54,11 @@ logistic regression model trained with scikit-learn and converted with sklearn-onnx.

from onnxruntime.datasets import get_example
+
 example = get_example("logreg_iris.onnx")
 
 import onnx
+
 model = onnx.load(example)
 
 print("doc_string={}".format(model.doc_string))
@@ -67,7 +70,6 @@
 print("producer_version={}".format(model.producer_version))
 
-

Out:

doc_string=
 domain=onnxml
 ir_version=3
@@ -79,6 +81,7 @@
 

With ONNX Runtime:

import onnxruntime as rt
+
 sess = rt.InferenceSession(example, providers=rt.get_available_providers())
 meta = sess.get_modelmeta()
 
@@ -90,7 +93,6 @@
 print("version={}".format(meta.version))
 
-

Out:

custom_metadata_map={}
 description=
 domain=onnxml
@@ -99,8 +101,8 @@
 version=0
 
-

Total running time of the script: ( 0 minutes 0.005 seconds)

- - + @@ -174,7 +176,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/plot_pipeline.html b/docs/api/python/auto_examples/plot_pipeline.html index c8e8705dc666b..faef40f360dda 100644 --- a/docs/api/python/auto_examples/plot_pipeline.html +++ b/docs/api/python/auto_examples/plot_pipeline.html @@ -6,7 +6,7 @@ - Draw a pipeline — ONNX Runtime 1.11.0 documentation + Draw a pipeline — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -44,7 +45,7 @@ to download the full example code

-

Draw a pipeline

+

Draw a pipeline

There is no other way to look into one model stored in ONNX format than looking into its node with onnx. This example demonstrates @@ -57,18 +58,19 @@

-

Retrieve a model in JSON format

+

Retrieve a model in JSON format

That’s the most simple way.

from onnxruntime.datasets import get_example
+
 example1 = get_example("mul_1.onnx")
 
 import onnx
+
 model = onnx.load(example1)  # model is a ModelProto protobuf message
 
 print(model)
 
-

Out:

ir_version: 3
 producer_name: "chenta"
 graph {
@@ -133,46 +135,49 @@ 

Retrieve a model in JSON format

-

Draw a model with ONNX

+

Draw a model with ONNX

We use net_drawer.py included in onnx package. We use onnx to load the model in a different way than before.

from onnx import ModelProto
+
 model = ModelProto()
-with open(example1, 'rb') as fid:
+with open(example1, "rb") as fid:
     content = fid.read()
     model.ParseFromString(content)
 

We convert it into a graph.

-
from onnx.tools.net_drawer import GetPydotGraph, GetOpNodeProducer
-pydot_graph = GetPydotGraph(model.graph, name=model.graph.name, rankdir="LR",
-                            node_producer=GetOpNodeProducer("docstring"))
+
from onnx.tools.net_drawer import GetOpNodeProducer, GetPydotGraph
+
+pydot_graph = GetPydotGraph(
+    model.graph, name=model.graph.name, rankdir="LR", node_producer=GetOpNodeProducer("docstring")
+)
 pydot_graph.write_dot("graph.dot")
 

Then into an image

import os
-os.system('dot -O -Tpng graph.dot')
+
+os.system("dot -O -Tpng graph.dot")
 
-

Out:

0
 

Which we display…

import matplotlib.pyplot as plt
+
 image = plt.imread("graph.dot.png")
 plt.imshow(image)
 
-plot pipeline

Out:

-
<matplotlib.image.AxesImage object at 0x7feafe274ac0>
+plot pipeline
<matplotlib.image.AxesImage object at 0x7ff7301cd3a0>
 
-

Total running time of the script: ( 0 minutes 0.196 seconds)

- - + @@ -247,7 +252,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/plot_profiling.html b/docs/api/python/auto_examples/plot_profiling.html index e8c9aa4385043..efddea551e8cd 100644 --- a/docs/api/python/auto_examples/plot_profiling.html +++ b/docs/api/python/auto_examples/plot_profiling.html @@ -6,7 +6,7 @@ - Profile the execution of a simple model — ONNX Runtime 1.11.0 documentation + Profile the execution of a simple model — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -44,12 +45,13 @@ to download the full example code

-

Profile the execution of a simple model

+

Profile the execution of a simple model

ONNX Runtime can profile the execution of the model. This example shows how to interpret the results.

-
import onnx
+
import numpy
+import onnx
+
 import onnxruntime as rt
-import numpy
 from onnxruntime.datasets import get_example
 
 
@@ -75,7 +77,6 @@
 print(res)
 
-

Out:

[array([[ 1.,  4.],
        [ 9., 16.],
        [25., 36.]], dtype=float32)]
@@ -95,40 +96,40 @@
 print(prof_file)
 
-

Out:

-
onnxruntime_profile__2022-01-04_17-09-55.json
+
onnxruntime_profile__2022-08-16_04-44-08.json
 

The results are stored un a file in JSON format. Let’s see what it contains.

import json
+
 with open(prof_file, "r") as f:
     sess_time = json.load(f)
 import pprint
+
 pprint.pprint(sess_time)
 
-

Out:

[{'args': {},
   'cat': 'Session',
-  'dur': 56,
+  'dur': 67,
   'name': 'model_loading_array',
   'ph': 'X',
-  'pid': 3089,
-  'tid': 3089,
+  'pid': 3111,
+  'tid': 3111,
   'ts': 1},
  {'args': {},
   'cat': 'Session',
-  'dur': 240,
+  'dur': 236,
   'name': 'session_initialization',
   'ph': 'X',
-  'pid': 3089,
-  'tid': 3089,
-  'ts': 71}]
+  'pid': 3111,
+  'tid': 3111,
+  'ts': 85}]
 
-

Total running time of the script: ( 0 minutes 0.007 seconds)

- - + @@ -202,7 +203,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/plot_train_convert_predict.html b/docs/api/python/auto_examples/plot_train_convert_predict.html index 9b451dc80273b..1cf321928bd24 100644 --- a/docs/api/python/auto_examples/plot_train_convert_predict.html +++ b/docs/api/python/auto_examples/plot_train_convert_predict.html @@ -6,7 +6,7 @@ - Train, convert and predict with ONNX Runtime — ONNX Runtime 1.11.0 documentation + Train, convert and predict with ONNX Runtime — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -43,7 +44,7 @@ to download the full example code

-

Train, convert and predict with ONNX Runtime

+

Train, convert and predict with ONNX Runtime

This example demonstrates an end to end scenario starting with the training of a machine learned model to its use in its converted from.

@@ -56,27 +57,30 @@
-

Train a logistic regression

+

Train a logistic regression

The first step consists in retrieving the iris datset.

from sklearn.datasets import load_iris
+
 iris = load_iris()
 X, y = iris.data, iris.target
 
 from sklearn.model_selection import train_test_split
+
 X_train, X_test, y_train, y_test = train_test_split(X, y)
 

Then we fit a model.

from sklearn.linear_model import LogisticRegression
+
 clr = LogisticRegression()
 clr.fit(X_train, y_train)
 
-

Out:

-
LogisticRegression()
-
+
+
LogisticRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
-

We compute the prediction on the test set +
+

We compute the prediction on the test set and we show the confusion matrix.

from sklearn.metrics import confusion_matrix
 
@@ -84,22 +88,21 @@ 

Train a logistic regressionprint(confusion_matrix(y_test, pred))

-

Out:

-
[[13  0  0]
+
[[17  0  0]
  [ 0 10  1]
- [ 0  0 14]]
+ [ 0  0 10]]
 
-

Conversion to ONNX format

+

Conversion to ONNX format

We use module sklearn-onnx to convert the model into ONNX format.

-

Out:

-
[[13  0  0]
+
[[17  0  0]
  [ 0 10  0]
- [ 0  0 15]]
+ [ 0  0 11]]
 

The prediction are perfectly identical.

-

Probabilities

+

Probabilities

Probabilities are needed to compute other relevant metrics such as the ROC Curve. Let’s see how to get them first with @@ -148,10 +149,9 @@

Probabilitiesprint(prob_sklearn[:3])

-

Out:

-
-

Out:

-
[{0: 2.9595235901069827e-05, 1: 0.05698008090257645, 2: 0.9429903030395508},
- {0: 1.8492364688427188e-05, 1: 0.03936365991830826, 2: 0.9606178402900696},
- {0: 0.013000461272895336, 1: 0.8036782741546631, 2: 0.1833212822675705}]
+
[{0: 0.18216472864151, 1: 0.8135982751846313, 2: 0.0042370399460196495},
+ {0: 0.0008120210259221494, 1: 0.3371346592903137, 2: 0.6620532870292664},
+ {0: 1.2024959232803667e-06, 1: 0.01740385964512825, 2: 0.9825949668884277}]
 

Let’s benchmark.

-

Out:

Execution time for clr.predict
-Average 4.38e-05 min=4.25e-05 max=6.07e-05
+Average 4.46e-05 min=4.3e-05 max=5.6e-05
 Execution time for ONNX Runtime
-Average 1.97e-05 min=1.92e-05 max=2.46e-05
+Average 1.84e-05 min=1.78e-05 max=2.5e-05
 
-1.9671264999914226e-05
+1.838059500016698e-05
 

Let’s benchmark a scenario similar to what a webservice @@ -205,45 +206,48 @@

Probabilitiesn = nrow for i in range(0, n): im = i % nrow - fct(X_test[im: im+1]) + fct(X_test[im : im + 1]) + print("Execution time for clr.predict") speed("loop(X_test, clr.predict, 100)") + def sess_predict(x): return sess.run([label_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for sess_predict") speed("loop(X_test, sess_predict, 100)")

-

Out:

Execution time for clr.predict
-Average 0.00404 min=0.00402 max=0.00409
+Average 0.0042 min=0.00418 max=0.00428
 Execution time for sess_predict
-Average 0.000881 min=0.000874 max=0.000912
+Average 0.000862 min=0.000856 max=0.000878
 
-0.0008813192099997735
+0.0008617829299998903
 

Let’s do the same for the probabilities.

print("Execution time for predict_proba")
 speed("loop(X_test, clr.predict_proba, 100)")
 
+
 def sess_predict_proba(x):
     return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]
 
+
 print("Execution time for sess_predict_proba")
 speed("loop(X_test, sess_predict_proba, 100)")
 
-

Out:

Execution time for predict_proba
-Average 0.00599 min=0.00597 max=0.00606
+Average 0.00617 min=0.00615 max=0.0062
 Execution time for sess_predict_proba
-Average 0.000883 min=0.000876 max=0.000916
+Average 0.000887 min=0.00088 max=0.000915
 
-0.0008830492349999729
+0.0008867338849996997
 

This second comparison is better as @@ -252,13 +256,14 @@

Probabilities

-

Benchmark with RandomForest

+

Benchmark with RandomForest

We first train and save a model in ONNX format.

from sklearn.ensemble import RandomForestClassifier
+
 rf = RandomForestClassifier()
 rf.fit(X_train, y_train)
 
-initial_type = [('float_input', FloatTensorType([1, 4]))]
+initial_type = [("float_input", FloatTensorType([1, 4]))]
 onx = convert_sklearn(rf, initial_types=initial_type)
 with open("rf_iris.onnx", "wb") as f:
     f.write(onx.SerializeToString())
@@ -267,9 +272,11 @@ 

Benchmark with RandomForest

-

Out:

Execution time for predict_proba
-Average 0.717 min=0.715 max=0.72
+Average 0.723 min=0.721 max=0.729
 Execution time for sess_predict_proba
-Average 0.00108 min=0.00107 max=0.00111
+Average 0.00103 min=0.00102 max=0.00106
 
-0.0010817126199989956
+0.0010315913400006592
 

Let’s see with different number of trees.

@@ -293,65 +299,66 @@

Benchmark with RandomForestprint(n_trees) rf = RandomForestClassifier(n_estimators=n_trees) rf.fit(X_train, y_train) - initial_type = [('float_input', FloatTensorType([1, 4]))] + initial_type = [("float_input", FloatTensorType([1, 4]))] onx = convert_sklearn(rf, initial_types=initial_type) with open("rf_iris_%d.onnx" % n_trees, "wb") as f: f.write(onx.SerializeToString()) sess = rt.InferenceSession("rf_iris_%d.onnx" % n_trees, providers=rt.get_available_providers()) + def sess_predict_proba_loop(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + tsk = speed("loop(X_test, rf.predict_proba, 100)", number=5, repeat=5) trt = speed("loop(X_test, sess_predict_proba_loop, 100)", number=5, repeat=5) - measures.append({'n_trees': n_trees, 'sklearn': tsk, 'rt': trt}) + measures.append({"n_trees": n_trees, "sklearn": tsk, "rt": trt}) from pandas import DataFrame + df = DataFrame(measures) ax = df.plot(x="n_trees", y="sklearn", label="scikit-learn", c="blue", logy=True) -df.plot(x="n_trees", y="rt", label="onnxruntime", - ax=ax, c="green", logy=True) +df.plot(x="n_trees", y="rt", label="onnxruntime", ax=ax, c="green", logy=True) ax.set_xlabel("Number of trees") ax.set_ylabel("Prediction time (s)") ax.set_title("Speed comparison between scikit-learn and ONNX Runtime\nFor a random forest on Iris dataset") ax.legend()

-Speed comparison between scikit-learn and ONNX Runtime For a random forest on Iris dataset

Out:

-
5
-Average 0.0637 min=0.0636 max=0.0639
-Average 0.000869 min=0.000857 max=0.000899
+Speed comparison between scikit-learn and ONNX Runtime For a random forest on Iris dataset
5
+Average 0.0519 min=0.0519 max=0.0521
+Average 0.000867 min=0.000856 max=0.000898
 10
-Average 0.0982 min=0.098 max=0.0987
-Average 0.000884 min=0.000873 max=0.00091
+Average 0.0872 min=0.0871 max=0.0875
+Average 0.000881 min=0.000877 max=0.000893
 15
-Average 0.133 min=0.133 max=0.133
-Average 0.000895 min=0.000885 max=0.000921
+Average 0.123 min=0.122 max=0.123
+Average 0.000908 min=0.000896 max=0.000938
 20
-Average 0.168 min=0.167 max=0.168
-Average 0.000915 min=0.000907 max=0.00094
+Average 0.158 min=0.158 max=0.158
+Average 0.000902 min=0.000896 max=0.000918
 25
-Average 0.202 min=0.201 max=0.203
-Average 0.000921 min=0.000913 max=0.000948
+Average 0.193 min=0.193 max=0.193
+Average 0.000929 min=0.000914 max=0.000961
 30
-Average 0.236 min=0.236 max=0.237
-Average 0.000922 min=0.000914 max=0.000948
+Average 0.228 min=0.228 max=0.229
+Average 0.000927 min=0.000915 max=0.000948
 35
-Average 0.271 min=0.271 max=0.271
-Average 0.000941 min=0.000928 max=0.000967
+Average 0.263 min=0.263 max=0.264
+Average 0.000946 min=0.000935 max=0.000978
 40
-Average 0.305 min=0.305 max=0.305
-Average 0.000948 min=0.000934 max=0.000977
+Average 0.298 min=0.298 max=0.299
+Average 0.000952 min=0.000943 max=0.000972
 45
-Average 0.34 min=0.339 max=0.34
-Average 0.000983 min=0.000972 max=0.00101
+Average 0.334 min=0.333 max=0.335
+Average 0.000953 min=0.000943 max=0.000985
 50
-Average 0.375 min=0.374 max=0.375
-Average 0.000972 min=0.000966 max=0.000992
+Average 0.369 min=0.369 max=0.371
+Average 0.000981 min=0.000973 max=0.00101
 
-<matplotlib.legend.Legend object at 0x7feaf2025c10>
+<matplotlib.legend.Legend object at 0x7ff71efab280>
 
-

Total running time of the script: ( 3 minutes 22.159 seconds)

-
- + @@ -425,7 +432,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/auto_examples/sg_execution_times.html b/docs/api/python/auto_examples/sg_execution_times.html index fbc71647b8669..a99f2bc17e27c 100644 --- a/docs/api/python/auto_examples/sg_execution_times.html +++ b/docs/api/python/auto_examples/sg_execution_times.html @@ -6,7 +6,7 @@ - Computation times — ONNX Runtime 1.11.0 documentation + Computation times — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -37,8 +38,8 @@
-

Computation times

-

03:23.370 total execution time for auto_examples files:

+

Computation times

+

03:22.379 total execution time for auto_examples files:

@@ -47,35 +48,35 @@ - + - + - + - - + + - - + + - + - + @@ -104,7 +105,7 @@

ONNX Runtime

Navigation

@@ -124,7 +125,7 @@

Quick search

- + @@ -141,7 +142,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip b/docs/api/python/downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip index 45a147fd36b3443038e5ff7d1134eee2e4d5ad74..3a0c03fd05f7bc157963e64470a32cd77cc82d00 100644 GIT binary patch delta 1508 zcmb7EZA@EL7{2GW6u8i}Frc)w<#741r7cn@LBa8{4-lwOvu+HS!9p+eTH1Sa@5QXj zRI;hj{TS?BmS{ql8U9*kSWetDF^1_9KeA|IvS>{9N7SfcOZ+AAhw-$Kx}twPH}~Fi z?s?90&U>Htc|ZCPUHSl7LPI)z8Ix{j>&?gZIq!ZkYhajJa)$p68L^m2%te{Osh3Ca-0S1Bt12&1QyaCJzP% zSwnI@A*VQK4o(3aDIx2@c@~l(8*CWz$>7MddeFi)`1~jjtf2x-qj^vmuBH82SUK*X zbM3p|t6_O;8-6@y{vY@nGCC?ExP9Uvy)95PR!85J5E*k(vOmioj{o}pM{k_VW0-Tq z>)u9iCs?4v2Qb{K$1v$mF*Muu4+<|pp4u+=3)FV_i| zx*HLOjqZb)rw!~qL3rI}hATZGnCS7eaXuorZiNPk`W~pPRW87&K#=;D); znj#1)-+^~~Ud*fUIU%AX={Jg|V@2cPW846ncm8tEGn!c_-T!?ioX;@f>y~j;x?_!9t4Yb^skBXYIKD)k z2tEy13D*6k14n+)&&jePCbg!WmrE5?by5=(f}6{Avb}J)wU3^ykNnV-$EGtGW_3;| z_8Vc`V}lld2bJ_zfG11-QUvd`H0pU}iifXT-gAz~!%|cTDN=NPT2Q>WU(iCSsHF8P z5jn=e+pUhg%x{F7t$xr4e3Zx^NLV>ZZBkRJCL~-uMPuIx_J!r-EQY~=4>kksU~Oyn zhK3MZru&bIL(gi;)S;cn+9Jb1_k;uI)Dl`x%5y*$4RHRXwK117>tgC;x+2@w7XPS# zg$ZYdGwWRH-r6jLVb&Jc?a+17k8_Md&Em)bB^u$~{OW&&lT8U4PG!!5{v)tG(U93X zD?d$vk{r<15WGKL{bV}ktbmj$Hwft{!^m@zmMt7jaw;^GM{x{OKraW&Fq>oP(ce=S Bxg`Jq delta 1650 zcmbVMZA=?=7{9v~7&jO#w3M~9{L4#U1}zrk9W34E*j8O@7_5{47J9G(y}R8V3oPhH zOxVbD8lT1NgT`PmA(>9uKTb_FQ?pMqgT(k2zvvR9iC^YEm`uOS{~fGQ^^;F?{lDCE z&&%)mJ&N_)R z;pdl>RVziQkDUU?U?XJO#8x(V?3-ofAamS`HmaQ#=1t}epC$7*SiT;*^+a8j?@ z0|RRXzF{|5*#f9&Xxh9K8Z0o`a0}NrmNI#WWkpFCg#c@V@uqRO(=>@&n_Fpos^vKv z?zO(Ps~x4%wSgfo2rU6vZ>xm+ZKH6i#R|U%3*b!q_t4uhv32eMLuVh2FxMHNVZFN? zaF9*&VM4GhLYfq8rn!W~lRHJ8B4V}yU*X+@`q@eUj3Grkd>fw}#cuYugQAtS7jByf# zVs;pd1vn3wU8kd9Cw%y!b854>ZbDmi39DL434B7DgG1FX5YC3Nspd9~e{@~a zmF<8^?OSujvD8@uMV-Z0bB{7ARN!?T&Voyu5f}4gj9#nNn#q2>AgPCE4c+jJu>zhq zCG0BN)}dAwrYoT+Zr7ADT}C>MK%0@31rplJamTP~Dbr=dQnu2Ueu@&O1!Y7` ziQIIG=ltSaG@PA9hT-JvvWx?Y#L?dbsX><(M>ajTwN@7X>>y+fXlZ8%K!PxD>kv!d a9f9|AEv3`_\nto convert the model into ONNX format.\n\n" + "## Conversion to ONNX format\n\nWe use module\n[sklearn-onnx](https://github.com/onnx/sklearn-onnx)\nto convert the model into ONNX format.\n\n" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "from skl2onnx import convert_sklearn\nfrom skl2onnx.common.data_types import FloatTensorType\n\ninitial_type = [('float_input', FloatTensorType([None, 4]))]\nonx = convert_sklearn(clr, initial_types=initial_type)\nwith open(\"logreg_iris.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())" + "from skl2onnx import convert_sklearn\nfrom skl2onnx.common.data_types import FloatTensorType\n\ninitial_type = [(\"float_input\", FloatTensorType([None, 4]))]\nonx = convert_sklearn(clr, initial_types=initial_type)\nwith open(\"logreg_iris.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())" ] }, { @@ -98,7 +98,7 @@ }, "outputs": [], "source": [ - "import onnxruntime as rt\nsess = rt.InferenceSession(\"logreg_iris.onnx\", providers=rt.get_available_providers())\n\nprint(\"input name='{}' and shape={}\".format(\n sess.get_inputs()[0].name, sess.get_inputs()[0].shape))\nprint(\"output name='{}' and shape={}\".format(\n sess.get_outputs()[0].name, sess.get_outputs()[0].shape))" + "import onnxruntime as rt\n\nsess = rt.InferenceSession(\"logreg_iris.onnx\", providers=rt.get_available_providers())\n\nprint(\"input name='{}' and shape={}\".format(sess.get_inputs()[0].name, sess.get_inputs()[0].shape))\nprint(\"output name='{}' and shape={}\".format(sess.get_outputs()[0].name, sess.get_outputs()[0].shape))" ] }, { @@ -116,7 +116,7 @@ }, "outputs": [], "source": [ - "input_name = sess.get_inputs()[0].name\nlabel_name = sess.get_outputs()[0].name\n\nimport numpy\npred_onx = sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0]\nprint(confusion_matrix(pred, pred_onx))" + "input_name = sess.get_inputs()[0].name\nlabel_name = sess.get_outputs()[0].name\n\nimport numpy\n\npred_onx = sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0]\nprint(confusion_matrix(pred, pred_onx))" ] }, { @@ -141,7 +141,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "And then with ONNX Runtime.\nThe probabilies appear to be \n\n" + "And then with ONNX Runtime.\nThe probabilies appear to be\n\n" ] }, { @@ -152,7 +152,7 @@ }, "outputs": [], "source": [ - "prob_name = sess.get_outputs()[1].name\nprob_rt = sess.run([prob_name], {input_name: X_test.astype(numpy.float32)})[0]\n\nimport pprint\npprint.pprint(prob_rt[0:3])" + "prob_name = sess.get_outputs()[1].name\nprob_rt = sess.run([prob_name], {input_name: X_test.astype(numpy.float32)})[0]\n\nimport pprint\n\npprint.pprint(prob_rt[0:3])" ] }, { @@ -170,7 +170,7 @@ }, "outputs": [], "source": [ - "from timeit import Timer\n\ndef speed(inst, number=10, repeat=20):\n timer = Timer(inst, globals=globals())\n raw = numpy.array(timer.repeat(repeat, number=number))\n ave = raw.sum() / len(raw) / number\n mi, ma = raw.min() / number, raw.max() / number\n print(\"Average %1.3g min=%1.3g max=%1.3g\" % (ave, mi, ma))\n return ave\n\nprint(\"Execution time for clr.predict\")\nspeed(\"clr.predict(X_test)\")\n\nprint(\"Execution time for ONNX Runtime\")\nspeed(\"sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0]\")" + "from timeit import Timer\n\n\ndef speed(inst, number=10, repeat=20):\n timer = Timer(inst, globals=globals())\n raw = numpy.array(timer.repeat(repeat, number=number))\n ave = raw.sum() / len(raw) / number\n mi, ma = raw.min() / number, raw.max() / number\n print(\"Average %1.3g min=%1.3g max=%1.3g\" % (ave, mi, ma))\n return ave\n\n\nprint(\"Execution time for clr.predict\")\nspeed(\"clr.predict(X_test)\")\n\nprint(\"Execution time for ONNX Runtime\")\nspeed(\"sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0]\")" ] }, { @@ -188,7 +188,7 @@ }, "outputs": [], "source": [ - "def loop(X_test, fct, n=None):\n nrow = X_test.shape[0]\n if n is None:\n n = nrow\n for i in range(0, n):\n im = i % nrow\n fct(X_test[im: im+1])\n\nprint(\"Execution time for clr.predict\")\nspeed(\"loop(X_test, clr.predict, 100)\")\n\ndef sess_predict(x):\n return sess.run([label_name], {input_name: x.astype(numpy.float32)})[0]\n\nprint(\"Execution time for sess_predict\")\nspeed(\"loop(X_test, sess_predict, 100)\")" + "def loop(X_test, fct, n=None):\n nrow = X_test.shape[0]\n if n is None:\n n = nrow\n for i in range(0, n):\n im = i % nrow\n fct(X_test[im : im + 1])\n\n\nprint(\"Execution time for clr.predict\")\nspeed(\"loop(X_test, clr.predict, 100)\")\n\n\ndef sess_predict(x):\n return sess.run([label_name], {input_name: x.astype(numpy.float32)})[0]\n\n\nprint(\"Execution time for sess_predict\")\nspeed(\"loop(X_test, sess_predict, 100)\")" ] }, { @@ -206,14 +206,14 @@ }, "outputs": [], "source": [ - "print(\"Execution time for predict_proba\")\nspeed(\"loop(X_test, clr.predict_proba, 100)\")\n\ndef sess_predict_proba(x):\n return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]\n\nprint(\"Execution time for sess_predict_proba\")\nspeed(\"loop(X_test, sess_predict_proba, 100)\")" + "print(\"Execution time for predict_proba\")\nspeed(\"loop(X_test, clr.predict_proba, 100)\")\n\n\ndef sess_predict_proba(x):\n return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]\n\n\nprint(\"Execution time for sess_predict_proba\")\nspeed(\"loop(X_test, sess_predict_proba, 100)\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This second comparison is better as \nONNX Runtime, in this experience,\ncomputes the label and the probabilities\nin every case.\n\n" + "This second comparison is better as\nONNX Runtime, in this experience,\ncomputes the label and the probabilities\nin every case.\n\n" ] }, { @@ -231,7 +231,7 @@ }, "outputs": [], "source": [ - "from sklearn.ensemble import RandomForestClassifier\nrf = RandomForestClassifier()\nrf.fit(X_train, y_train)\n\ninitial_type = [('float_input', FloatTensorType([1, 4]))]\nonx = convert_sklearn(rf, initial_types=initial_type)\nwith open(\"rf_iris.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())" + "from sklearn.ensemble import RandomForestClassifier\n\nrf = RandomForestClassifier()\nrf.fit(X_train, y_train)\n\ninitial_type = [(\"float_input\", FloatTensorType([1, 4]))]\nonx = convert_sklearn(rf, initial_types=initial_type)\nwith open(\"rf_iris.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())" ] }, { @@ -249,7 +249,7 @@ }, "outputs": [], "source": [ - "sess = rt.InferenceSession(\"rf_iris.onnx\", providers=rt.get_available_providers())\n\ndef sess_predict_proba_rf(x):\n return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]\n\nprint(\"Execution time for predict_proba\")\nspeed(\"loop(X_test, rf.predict_proba, 100)\")\n\nprint(\"Execution time for sess_predict_proba\")\nspeed(\"loop(X_test, sess_predict_proba_rf, 100)\")" + "sess = rt.InferenceSession(\"rf_iris.onnx\", providers=rt.get_available_providers())\n\n\ndef sess_predict_proba_rf(x):\n return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]\n\n\nprint(\"Execution time for predict_proba\")\nspeed(\"loop(X_test, rf.predict_proba, 100)\")\n\nprint(\"Execution time for sess_predict_proba\")\nspeed(\"loop(X_test, sess_predict_proba_rf, 100)\")" ] }, { @@ -267,7 +267,7 @@ }, "outputs": [], "source": [ - "measures = []\n\nfor n_trees in range(5, 51, 5): \n print(n_trees)\n rf = RandomForestClassifier(n_estimators=n_trees)\n rf.fit(X_train, y_train)\n initial_type = [('float_input', FloatTensorType([1, 4]))]\n onx = convert_sklearn(rf, initial_types=initial_type)\n with open(\"rf_iris_%d.onnx\" % n_trees, \"wb\") as f:\n f.write(onx.SerializeToString())\n sess = rt.InferenceSession(\"rf_iris_%d.onnx\" % n_trees, providers=rt.get_available_providers())\n def sess_predict_proba_loop(x):\n return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]\n tsk = speed(\"loop(X_test, rf.predict_proba, 100)\", number=5, repeat=5)\n trt = speed(\"loop(X_test, sess_predict_proba_loop, 100)\", number=5, repeat=5)\n measures.append({'n_trees': n_trees, 'sklearn': tsk, 'rt': trt})\n\nfrom pandas import DataFrame\ndf = DataFrame(measures)\nax = df.plot(x=\"n_trees\", y=\"sklearn\", label=\"scikit-learn\", c=\"blue\", logy=True)\ndf.plot(x=\"n_trees\", y=\"rt\", label=\"onnxruntime\",\n ax=ax, c=\"green\", logy=True)\nax.set_xlabel(\"Number of trees\")\nax.set_ylabel(\"Prediction time (s)\")\nax.set_title(\"Speed comparison between scikit-learn and ONNX Runtime\\nFor a random forest on Iris dataset\")\nax.legend()" + "measures = []\n\nfor n_trees in range(5, 51, 5):\n print(n_trees)\n rf = RandomForestClassifier(n_estimators=n_trees)\n rf.fit(X_train, y_train)\n initial_type = [(\"float_input\", FloatTensorType([1, 4]))]\n onx = convert_sklearn(rf, initial_types=initial_type)\n with open(\"rf_iris_%d.onnx\" % n_trees, \"wb\") as f:\n f.write(onx.SerializeToString())\n sess = rt.InferenceSession(\"rf_iris_%d.onnx\" % n_trees, providers=rt.get_available_providers())\n\n def sess_predict_proba_loop(x):\n return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0]\n\n tsk = speed(\"loop(X_test, rf.predict_proba, 100)\", number=5, repeat=5)\n trt = speed(\"loop(X_test, sess_predict_proba_loop, 100)\", number=5, repeat=5)\n measures.append({\"n_trees\": n_trees, \"sklearn\": tsk, \"rt\": trt})\n\nfrom pandas import DataFrame\n\ndf = DataFrame(measures)\nax = df.plot(x=\"n_trees\", y=\"sklearn\", label=\"scikit-learn\", c=\"blue\", logy=True)\ndf.plot(x=\"n_trees\", y=\"rt\", label=\"onnxruntime\", ax=ax, c=\"green\", logy=True)\nax.set_xlabel(\"Number of trees\")\nax.set_ylabel(\"Prediction time (s)\")\nax.set_title(\"Speed comparison between scikit-learn and ONNX Runtime\\nFor a random forest on Iris dataset\")\nax.legend()" ] } ], diff --git a/docs/api/python/downloads/1b60ac13d6a5a4b72d4e4d28d1544f8d/plot_common_errors.ipynb b/docs/api/python/downloads/1b60ac13d6a5a4b72d4e4d28d1544f8d/plot_common_errors.ipynb index 78c57d9d0d211..bba0472e83a8c 100644 --- a/docs/api/python/downloads/1b60ac13d6a5a4b72d4e4d28d1544f8d/plot_common_errors.ipynb +++ b/docs/api/python/downloads/1b60ac13d6a5a4b72d4e4d28d1544f8d/plot_common_errors.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import onnxruntime as rt\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\nimport numpy\nfrom onnxruntime.datasets import get_example\n\nexample2 = get_example(\"logreg_iris.onnx\")\nsess = rt.InferenceSession(example2, providers=rt.get_available_providers())\n\ninput_name = sess.get_inputs()[0].name\noutput_name = sess.get_outputs()[0].name" + "import numpy\n\nimport onnxruntime as rt\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\nfrom onnxruntime.datasets import get_example\n\nexample2 = get_example(\"logreg_iris.onnx\")\nsess = rt.InferenceSession(example2, providers=rt.get_available_providers())\n\ninput_name = sess.get_inputs()[0].name\noutput_name = sess.get_outputs()[0].name" ] }, { @@ -116,7 +116,7 @@ }, "outputs": [], "source": [ - "for x in [\n numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),\n numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),\n numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),\n ]:\n try:\n r = sess.run([output_name], {input_name: x})\n print(\"Shape={0} and predicted labels={1}\".format(x.shape, r))\n except (RuntimeError, InvalidArgument) as e:\n print(\"ERROR with Shape={0} - {1}\".format(x.shape, e))\n\nfor x in [\n numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),\n numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),\n numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),\n ]:\n try:\n r = sess.run(None, {input_name: x})\n print(\"Shape={0} and predicted probabilities={1}\".format(x.shape, r[1]))\n except (RuntimeError, InvalidArgument) as e:\n print(\"ERROR with Shape={0} - {1}\".format(x.shape, e))" + "for x in [\n numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),\n numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),\n numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),\n]:\n try:\n r = sess.run([output_name], {input_name: x})\n print(\"Shape={0} and predicted labels={1}\".format(x.shape, r))\n except (RuntimeError, InvalidArgument) as e:\n print(\"ERROR with Shape={0} - {1}\".format(x.shape, e))\n\nfor x in [\n numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),\n numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),\n numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),\n numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),\n]:\n try:\n r = sess.run(None, {input_name: x})\n print(\"Shape={0} and predicted probabilities={1}\".format(x.shape, r[1]))\n except (RuntimeError, InvalidArgument) as e:\n print(\"ERROR with Shape={0} - {1}\".format(x.shape, e))" ] }, { @@ -134,7 +134,7 @@ }, "outputs": [], "source": [ - "for x in [\n numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32),\n numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32),\n numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32),\n ]:\n try:\n r = sess.run([output_name], {input_name: x})\n print(\"Shape={0} and predicted labels={1}\".format(x.shape, r))\n except (RuntimeError, InvalidArgument) as e:\n print(\"ERROR with Shape={0} - {1}\".format(x.shape, e))" + "for x in [\n numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32),\n numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32),\n numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32),\n]:\n try:\n r = sess.run([output_name], {input_name: x})\n print(\"Shape={0} and predicted labels={1}\".format(x.shape, r))\n except (RuntimeError, InvalidArgument) as e:\n print(\"ERROR with Shape={0} - {1}\".format(x.shape, e))" ] } ], diff --git a/docs/api/python/downloads/290d1103c4874727a37c05b400ffb83c/plot_load_and_predict.ipynb b/docs/api/python/downloads/290d1103c4874727a37c05b400ffb83c/plot_load_and_predict.ipynb index 964763966024d..fc384bf89e972 100644 --- a/docs/api/python/downloads/290d1103c4874727a37c05b400ffb83c/plot_load_and_predict.ipynb +++ b/docs/api/python/downloads/290d1103c4874727a37c05b400ffb83c/plot_load_and_predict.ipynb @@ -26,14 +26,14 @@ }, "outputs": [], "source": [ - "import onnxruntime as rt\nimport numpy\nfrom onnxruntime.datasets import get_example" + "import numpy\n\nimport onnxruntime as rt\nfrom onnxruntime.datasets import get_example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let's load a very simple model.\nThe model is available on github `onnx...test_sigmoid `_.\n\n" + "Let's load a very simple model.\nThe model is available on github [onnx...test_sigmoid](https://github.com/onnx/onnx/tree/master/onnx/backend/test/data/node/test_sigmoid).\n\n" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "output_name = sess.get_outputs()[0].name\nprint(\"output name\", output_name) \noutput_shape = sess.get_outputs()[0].shape\nprint(\"output shape\", output_shape)\noutput_type = sess.get_outputs()[0].type\nprint(\"output type\", output_type)" + "output_name = sess.get_outputs()[0].name\nprint(\"output name\", output_name)\noutput_shape = sess.get_outputs()[0].shape\nprint(\"output shape\", output_shape)\noutput_type = sess.get_outputs()[0].type\nprint(\"output type\", output_type)" ] }, { @@ -98,7 +98,7 @@ }, "outputs": [], "source": [ - "import numpy.random\nx = numpy.random.random((3,4,5))\nx = x.astype(numpy.float32)\nres = sess.run([output_name], {input_name: x})\nprint(res)" + "import numpy.random\n\nx = numpy.random.random((3, 4, 5))\nx = x.astype(numpy.float32)\nres = sess.run([output_name], {input_name: x})\nprint(res)" ] } ], diff --git a/docs/api/python/downloads/2dbd202de70c8b6a394b8a1c7c1e12b8/plot_pipeline.ipynb b/docs/api/python/downloads/2dbd202de70c8b6a394b8a1c7c1e12b8/plot_pipeline.ipynb index c79f384172df4..93d0efdcbf5f4 100644 --- a/docs/api/python/downloads/2dbd202de70c8b6a394b8a1c7c1e12b8/plot_pipeline.ipynb +++ b/docs/api/python/downloads/2dbd202de70c8b6a394b8a1c7c1e12b8/plot_pipeline.ipynb @@ -26,14 +26,14 @@ }, "outputs": [], "source": [ - "from onnxruntime.datasets import get_example\nexample1 = get_example(\"mul_1.onnx\")\n\nimport onnx\nmodel = onnx.load(example1) # model is a ModelProto protobuf message\n\nprint(model)" + "from onnxruntime.datasets import get_example\n\nexample1 = get_example(\"mul_1.onnx\")\n\nimport onnx\n\nmodel = onnx.load(example1) # model is a ModelProto protobuf message\n\nprint(model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Draw a model with ONNX\nWe use `net_drawer.py `_\nincluded in *onnx* package.\nWe use *onnx* to load the model\nin a different way than before.\n\n" + "## Draw a model with ONNX\nWe use [net_drawer.py](https://github.com/onnx/onnx/blob/master/onnx/tools/net_drawer.py)\nincluded in *onnx* package.\nWe use *onnx* to load the model\nin a different way than before.\n\n" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "from onnx import ModelProto\nmodel = ModelProto()\nwith open(example1, 'rb') as fid:\n content = fid.read()\n model.ParseFromString(content)" + "from onnx import ModelProto\n\nmodel = ModelProto()\nwith open(example1, \"rb\") as fid:\n content = fid.read()\n model.ParseFromString(content)" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "from onnx.tools.net_drawer import GetPydotGraph, GetOpNodeProducer\npydot_graph = GetPydotGraph(model.graph, name=model.graph.name, rankdir=\"LR\",\n node_producer=GetOpNodeProducer(\"docstring\"))\npydot_graph.write_dot(\"graph.dot\")" + "from onnx.tools.net_drawer import GetOpNodeProducer, GetPydotGraph\n\npydot_graph = GetPydotGraph(\n model.graph, name=model.graph.name, rankdir=\"LR\", node_producer=GetOpNodeProducer(\"docstring\")\n)\npydot_graph.write_dot(\"graph.dot\")" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "import os\nos.system('dot -O -Tpng graph.dot')" + "import os\n\nos.system(\"dot -O -Tpng graph.dot\")" ] }, { @@ -98,7 +98,7 @@ }, "outputs": [], "source": [ - "import matplotlib.pyplot as plt\nimage = plt.imread(\"graph.dot.png\")\nplt.imshow(image)" + "import matplotlib.pyplot as plt\n\nimage = plt.imread(\"graph.dot.png\")\nplt.imshow(image)" ] } ], diff --git a/docs/api/python/downloads/3a2955e44bf8f95a0eee6e71695ad788/plot_common_errors.py b/docs/api/python/downloads/3a2955e44bf8f95a0eee6e71695ad788/plot_common_errors.py index b474574c0fdf6..e4b2b1e05a3ec 100644 --- a/docs/api/python/downloads/3a2955e44bf8f95a0eee6e71695ad788/plot_common_errors.py +++ b/docs/api/python/downloads/3a2955e44bf8f95a0eee6e71695ad788/plot_common_errors.py @@ -15,9 +15,10 @@ trained on *Iris* datasets. The model takes a vector of dimension 2 and returns a class among three. """ +import numpy + import onnxruntime as rt from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument -import numpy from onnxruntime.datasets import get_example example2 = get_example("logreg_iris.onnx") @@ -37,7 +38,7 @@ except Exception as e: print("Unexpected type") print("{0}: {1}".format(type(e), e)) - + ######################### # The model fails to return an output if the name # is misspelled. @@ -76,12 +77,12 @@ # dimension is a multiple of the expected input dimension. for x in [ - numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), - numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), - numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), - ]: + numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), + numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), + numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), +]: try: r = sess.run([output_name], {input_name: x}) print("Shape={0} and predicted labels={1}".format(x.shape, r)) @@ -89,12 +90,12 @@ print("ERROR with Shape={0} - {1}".format(x.shape, e)) for x in [ - numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), - numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), - numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), - ]: + numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), + numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), + numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), +]: try: r = sess.run(None, {input_name: x}) print("Shape={0} and predicted probabilities={1}".format(x.shape, r[1])) @@ -106,10 +107,10 @@ # is higher than expects but produces a warning. for x in [ - numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32), - numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32), - numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32), - ]: + numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32), + numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32), + numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32), +]: try: r = sess.run([output_name], {input_name: x}) print("Shape={0} and predicted labels={1}".format(x.shape, r)) diff --git a/docs/api/python/downloads/3aca744422de94d33f9aaa3ce99633a9/plot_convert_pipeline_vectorizer.ipynb b/docs/api/python/downloads/3aca744422de94d33f9aaa3ce99633a9/plot_convert_pipeline_vectorizer.ipynb index b0882340e1346..1859231ebd515 100644 --- a/docs/api/python/downloads/3aca744422de94d33f9aaa3ce99633a9/plot_convert_pipeline_vectorizer.ipynb +++ b/docs/api/python/downloads/3aca744422de94d33f9aaa3ce99633a9/plot_convert_pipeline_vectorizer.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Train, convert and predict with ONNX Runtime\n\nThis example demonstrates an end to end scenario\nstarting with the training of a scikit-learn pipeline\nwhich takes as inputs not a regular vector but a\ndictionary ``{ int: float }`` as its first step is a\n`DictVectorizer `_.\n\n## Train a pipeline\n\nThe first step consists in retrieving the boston datset.\n" + "\n# Train, convert and predict with ONNX Runtime\n\nThis example demonstrates an end to end scenario\nstarting with the training of a scikit-learn pipeline\nwhich takes as inputs not a regular vector but a\ndictionary ``{ int: float }`` as its first step is a\n[DictVectorizer](http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.DictVectorizer.html).\n\n## Train a pipeline\n\nThe first step consists in retrieving the boston datset.\n" ] }, { @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import pandas\nfrom sklearn.datasets import load_boston\nboston = load_boston()\nX, y = boston.data, boston.target\n\nfrom sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y)\nX_train_dict = pandas.DataFrame(X_train[:,1:]).T.to_dict().values()\nX_test_dict = pandas.DataFrame(X_test[:,1:]).T.to_dict().values()" + "import pandas\nfrom sklearn.datasets import load_boston\n\nboston = load_boston()\nX, y = boston.data, boston.target\n\nfrom sklearn.model_selection import train_test_split\n\nX_train, X_test, y_train, y_test = train_test_split(X, y)\nX_train_dict = pandas.DataFrame(X_train[:, 1:]).T.to_dict().values()\nX_test_dict = pandas.DataFrame(X_test[:, 1:]).T.to_dict().values()" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "from sklearn.pipeline import make_pipeline\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom sklearn.feature_extraction import DictVectorizer\npipe = make_pipeline(\n DictVectorizer(sparse=False),\n GradientBoostingRegressor())\n \npipe.fit(X_train_dict, y_train)" + "from sklearn.ensemble import GradientBoostingRegressor\nfrom sklearn.feature_extraction import DictVectorizer\nfrom sklearn.pipeline import make_pipeline\n\npipe = make_pipeline(DictVectorizer(sparse=False), GradientBoostingRegressor())\n\npipe.fit(X_train_dict, y_train)" ] }, { @@ -69,7 +69,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conversion to ONNX format\n\nWe use module \n`sklearn-onnx `_\nto convert the model into ONNX format.\n\n" + "## Conversion to ONNX format\n\nWe use module\n[sklearn-onnx](https://github.com/onnx/sklearn-onnx)\nto convert the model into ONNX format.\n\n" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "from skl2onnx import convert_sklearn\nfrom skl2onnx.common.data_types import FloatTensorType, Int64TensorType, DictionaryType, SequenceType\n\n# initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]\ninitial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]\nonx = convert_sklearn(pipe, initial_types=initial_type)\nwith open(\"pipeline_vectorize.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())" + "from skl2onnx import convert_sklearn\nfrom skl2onnx.common.data_types import DictionaryType, FloatTensorType, Int64TensorType, SequenceType\n\n# initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]\ninitial_type = [(\"float_input\", DictionaryType(Int64TensorType([1]), FloatTensorType([])))]\nonx = convert_sklearn(pipe, initial_types=initial_type)\nwith open(\"pipeline_vectorize.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())" ] }, { @@ -98,7 +98,7 @@ }, "outputs": [], "source": [ - "import onnxruntime as rt\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\n\nsess = rt.InferenceSession(\"pipeline_vectorize.onnx\", providers=rt.get_available_providers())\n\nimport numpy\ninp, out = sess.get_inputs()[0], sess.get_outputs()[0]\nprint(\"input name='{}' and shape={} and type={}\".format(inp.name, inp.shape, inp.type))\nprint(\"output name='{}' and shape={} and type={}\".format(out.name, out.shape, out.type))" + "import onnxruntime as rt\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\n\nsess = rt.InferenceSession(\"pipeline_vectorize.onnx\", providers=rt.get_available_providers())\n\nimport numpy\n\ninp, out = sess.get_inputs()[0], sess.get_outputs()[0]\nprint(\"input name='{}' and shape={} and type={}\".format(inp.name, inp.shape, inp.type))\nprint(\"output name='{}' and shape={} and type={}\".format(out.name, out.shape, out.type))" ] }, { diff --git a/docs/api/python/downloads/3e23fa9ebb26f4728ee8426ed7da0f63/plot_backend.py b/docs/api/python/downloads/3e23fa9ebb26f4728ee8426ed7da0f63/plot_backend.py index 68096bb8a682e..b441012e637ae 100644 --- a/docs/api/python/downloads/3e23fa9ebb26f4728ee8426ed7da0f63/plot_backend.py +++ b/docs/api/python/downloads/3e23fa9ebb26f4728ee8426ed7da0f63/plot_backend.py @@ -15,15 +15,16 @@ of a simple logistic regression model. """ import numpy as np -from onnxruntime import datasets -from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument -import onnxruntime.backend as backend from onnx import load +import onnxruntime.backend as backend + ######################################## # The device depends on how the package was compiled, # GPU or CPU. -from onnxruntime import get_device +from onnxruntime import datasets, get_device +from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument + device = get_device() name = datasets.get_example("logreg_iris.onnx") diff --git a/docs/api/python/downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip b/docs/api/python/downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip index 70c6d584da4ce2f64913850663ce6b7e533886f3..eba50a649997109d84de3969308df4dd53eeb1ac 100644 GIT binary patch delta 1695 zcmah}Z%i9y7{9v?2DH%ew*|^L3PKB|FeqfOq1!TL3^%|5W8<(~>8(4V?_I8kP(n7* zsY91&@(fvU!c@XODD%&2qS1+S8`BT^VG=dQEQX-j2W8BVsEHDNuXK zu)#|8e%g-r?`WYDSkW&_ipus#yq81pIgVL{^FAkreuVN+6Hq;ya@%1B+v3I5AcP(_=fydH0+0 z2n}DIGvWzxk&f4zaCc<;?TR>xs=%*2Jfw@|kkHTjS;*TG**6s0}+6f8~H@Qv;YCb505*rm1#U8bET*YDHkSxjqTf_SKZo#dcdqgDIU|z`reIOfG z2F@^v9BL1A_Xxa#ina7YV42~!UIPi!m{vv`wG>1N@k+2cC<_j7^yPxP?_rr1$I%I`Iyjo>C;9GpKgmzy?&P=c z7rK?+5F)WZ8Q(BjwB}{OO1cD1vFY$)Mg!2kGZVhCDOO*v)zeyREd;&RI42i2{+B z*l~jGM}l{W8UD356Tuz4t4Pm4UGc&H%Mh~5<6zE|hQBZVQ?nvjlBlhv`3#&a+t@a( zrtI=08cJM!FzNc($yt$GRRkfxS*zLb(ZO=oFiM(K4RmV~MQi(W6?T}exP*Hue`Z3X zIF@?xyQ}dObroOe_?wB?kjtIlriIqi>2#_>Ky?R1pI;KaA<(nnI`5+GFu!>QW}?#Z zHy+C-eD_!Zlf#jHu3Yu6sH^vrEQ0iW;2=9cbltdxZUE2CVla6R%~j0i_UJ44@zF4QIWj8U4r6ZYX!A2 z=#|u3g_n;L|34kx8qFb=T(EMu91gUVkf?aD?KqvlAt~St1Ouwzw~;n49Z7==ZBGC? z`aAAucQQ~o9+w?Se-xDzBE{9$simylaf z6iEpqFX21HJ%|{lN{ltGC%CaFQ~kiSNU}ZP%{z3ZlsxY^U0y}rG#`` zY{b@*&1KhhsL7$(eV|XU!bjtVkhir#BamfAC^}S_ny`nI)&_zot(LK>IXP7DG&GM} l>$SYrfG0|kRassRS9OoQ?o|~Pt@()|cLhUHpS`C2{RgALH;(`S delta 1759 zcmb7ET}%{L6rMY?ScJu0SSmlu%5_0@7ncPDq9AG)s6q>Z6l~SSWno8lTy|!d9jdFb zh%H2oTJ@+gZH3qp5-lZZZ_}8jR31!Ue5kcao0tuvXBv&G1*@AQ-VRjUx}Xw8Sc)h2SXwTOj_W-HuklM;L) z#u)ncFNHgY4RF0Z86xd`rOi_?yDb4u?|6x1`of3|b<`l( z9ki0WJJYzws<04QS=s@qehhbaX2S1XDKHUCUhKxDB_%GO-31+8f)4+t>wCln`CWiy z3w#}H(}eI0{|Uk*e^)XKrJ+XM(-R>lJBLe$k9TjSxEdma|3IAPbSQFAL&1rVm86S_ z2$o6xa8|nFbclXc;rXbe3eWA_*fGZrm8sD%{Z~{6?3Z0IE>EQDBv6y{i?sILWtV6P zOTIP}S!`sO#m2WYk0DE^PHtDAJIsqg>}_e#iFUyqv|J~eW!n+_V#uI5v_Nsf8tCCx zWcb8giWI^6(YZwTN`WAFQ^VwEE)^y9@Txz^KQDCiq$lB{MJd|Fp|N+|#YqfPOqvP? zIk@4fhO3Z89ECTv=m?jl0f(PD@E}G@N_#8}+#Y?LG@V?{fiISI`mhNm!9)+v zm^(%75+$&QS3Gh|ciXGGJbR`RLE*VVgG1?ZknQK*L~C1OK}p@D1mut#Z{pQvd9xJc zTNEkS-_0vNQP$M{9!-zeX@CX16Y9^G+5W-jJh5~G`_C7XiSr?3m!h6%EUNMmr-K^A zMa{UVO%{8wZrMXc4mjlx!RxQwCud)EvoKPUs8iE>i$T*g+G$d&{>H-PHp`>^PUu#*^4+SW2>W=2nky*t>pTvZ)g!o39)*jImGDA^ z8)hrA;95l?nXT|6m|C3+-qli*EXX`1EfNUxer?|?h`ckNulO6BQ8}PQ`E?ruy;0uf zj)Q`EO|J3p+>+uo$NuXuFhNbVB}uzXki>uzgXZdC+E0xnZ{4RXd9dO0M4bT7%PWT* z*$m^zCToqaaT?q3tEnN5apE=C7-1mC3m@dv>b-e2BOlJ#vJIMZRIv=U+m=yfE`ZIN z_?O3I(w2_?|1p@fMb4zsCk=Q{bz5J2*#;IDSMhOj;apV_y-tP5xw#*q%FS8ck7@kPuq1#!Sb nVYpJ_gj*v`_ # to convert the model into ONNX format. from skl2onnx import convert_sklearn -from skl2onnx.common.data_types import FloatTensorType, Int64TensorType, DictionaryType, SequenceType +from skl2onnx.common.data_types import DictionaryType, FloatTensorType, Int64TensorType, SequenceType # initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))] -initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))] +initial_type = [("float_input", DictionaryType(Int64TensorType([1]), FloatTensorType([])))] onx = convert_sklearn(pipe, initial_types=initial_type) with open("pipeline_vectorize.onnx", "wb") as f: f.write(onx.SerializeToString()) @@ -75,6 +76,7 @@ sess = rt.InferenceSession("pipeline_vectorize.onnx", providers=rt.get_available_providers()) import numpy + inp, out = sess.get_inputs()[0], sess.get_outputs()[0] print("input name='{}' and shape={} and type={}".format(inp.name, inp.shape, inp.type)) print("output name='{}' and shape={} and type={}".format(out.name, out.shape, out.type)) @@ -100,4 +102,3 @@ ######################### # Very similar. *ONNX Runtime* uses floats instead of doubles, # that explains the small discrepencies. - diff --git a/docs/api/python/downloads/c647c128e0cf2b3db04ce60b41ef1a14/plot_train_convert_predict.py b/docs/api/python/downloads/c647c128e0cf2b3db04ce60b41ef1a14/plot_train_convert_predict.py index 4aa36b3dce25c..b5033b503b3eb 100644 --- a/docs/api/python/downloads/c647c128e0cf2b3db04ce60b41ef1a14/plot_train_convert_predict.py +++ b/docs/api/python/downloads/c647c128e0cf2b3db04ce60b41ef1a14/plot_train_convert_predict.py @@ -22,16 +22,19 @@ """ from sklearn.datasets import load_iris + iris = load_iris() X, y = iris.data, iris.target from sklearn.model_selection import train_test_split + X_train, X_test, y_train, y_test = train_test_split(X, y) #################################### # Then we fit a model. from sklearn.linear_model import LogisticRegression + clr = LogisticRegression() clr.fit(X_train, y_train) @@ -47,14 +50,14 @@ # Conversion to ONNX format # +++++++++++++++++++++++++ # -# We use module +# We use module # `sklearn-onnx `_ # to convert the model into ONNX format. from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType -initial_type = [('float_input', FloatTensorType([None, 4]))] +initial_type = [("float_input", FloatTensorType([None, 4]))] onx = convert_sklearn(clr, initial_types=initial_type) with open("logreg_iris.onnx", "wb") as f: f.write(onx.SerializeToString()) @@ -64,12 +67,11 @@ # its input and output. import onnxruntime as rt + sess = rt.InferenceSession("logreg_iris.onnx", providers=rt.get_available_providers()) -print("input name='{}' and shape={}".format( - sess.get_inputs()[0].name, sess.get_inputs()[0].shape)) -print("output name='{}' and shape={}".format( - sess.get_outputs()[0].name, sess.get_outputs()[0].shape)) +print("input name='{}' and shape={}".format(sess.get_inputs()[0].name, sess.get_inputs()[0].shape)) +print("output name='{}' and shape={}".format(sess.get_outputs()[0].name, sess.get_outputs()[0].shape)) ################################## # We compute the predictions. @@ -78,6 +80,7 @@ label_name = sess.get_outputs()[0].name import numpy + pred_onx = sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0] print(confusion_matrix(pred, pred_onx)) @@ -97,18 +100,20 @@ ############################# # And then with ONNX Runtime. -# The probabilies appear to be +# The probabilies appear to be prob_name = sess.get_outputs()[1].name prob_rt = sess.run([prob_name], {input_name: X_test.astype(numpy.float32)})[0] import pprint + pprint.pprint(prob_rt[0:3]) ############################### # Let's benchmark. from timeit import Timer + def speed(inst, number=10, repeat=20): timer = Timer(inst, globals=globals()) raw = numpy.array(timer.repeat(repeat, number=number)) @@ -117,6 +122,7 @@ def speed(inst, number=10, repeat=20): print("Average %1.3g min=%1.3g max=%1.3g" % (ave, mi, ma)) return ave + print("Execution time for clr.predict") speed("clr.predict(X_test)") @@ -128,20 +134,24 @@ def speed(inst, number=10, repeat=20): # experiences: the model has to do one prediction at a time # as opposed to a batch of prediction. + def loop(X_test, fct, n=None): nrow = X_test.shape[0] if n is None: n = nrow for i in range(0, n): im = i % nrow - fct(X_test[im: im+1]) + fct(X_test[im : im + 1]) + print("Execution time for clr.predict") speed("loop(X_test, clr.predict, 100)") + def sess_predict(x): return sess.run([label_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for sess_predict") speed("loop(X_test, sess_predict, 100)") @@ -151,14 +161,16 @@ def sess_predict(x): print("Execution time for predict_proba") speed("loop(X_test, clr.predict_proba, 100)") + def sess_predict_proba(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for sess_predict_proba") speed("loop(X_test, sess_predict_proba, 100)") ##################################### -# This second comparison is better as +# This second comparison is better as # ONNX Runtime, in this experience, # computes the label and the probabilities # in every case. @@ -169,10 +181,11 @@ def sess_predict_proba(x): # # We first train and save a model in ONNX format. from sklearn.ensemble import RandomForestClassifier + rf = RandomForestClassifier() rf.fit(X_train, y_train) -initial_type = [('float_input', FloatTensorType([1, 4]))] +initial_type = [("float_input", FloatTensorType([1, 4]))] onx = convert_sklearn(rf, initial_types=initial_type) with open("rf_iris.onnx", "wb") as f: f.write(onx.SerializeToString()) @@ -182,9 +195,11 @@ def sess_predict_proba(x): sess = rt.InferenceSession("rf_iris.onnx", providers=rt.get_available_providers()) + def sess_predict_proba_rf(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for predict_proba") speed("loop(X_test, rf.predict_proba, 100)") @@ -196,26 +211,28 @@ def sess_predict_proba_rf(x): measures = [] -for n_trees in range(5, 51, 5): +for n_trees in range(5, 51, 5): print(n_trees) rf = RandomForestClassifier(n_estimators=n_trees) rf.fit(X_train, y_train) - initial_type = [('float_input', FloatTensorType([1, 4]))] + initial_type = [("float_input", FloatTensorType([1, 4]))] onx = convert_sklearn(rf, initial_types=initial_type) with open("rf_iris_%d.onnx" % n_trees, "wb") as f: f.write(onx.SerializeToString()) sess = rt.InferenceSession("rf_iris_%d.onnx" % n_trees, providers=rt.get_available_providers()) + def sess_predict_proba_loop(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + tsk = speed("loop(X_test, rf.predict_proba, 100)", number=5, repeat=5) trt = speed("loop(X_test, sess_predict_proba_loop, 100)", number=5, repeat=5) - measures.append({'n_trees': n_trees, 'sklearn': tsk, 'rt': trt}) + measures.append({"n_trees": n_trees, "sklearn": tsk, "rt": trt}) from pandas import DataFrame + df = DataFrame(measures) ax = df.plot(x="n_trees", y="sklearn", label="scikit-learn", c="blue", logy=True) -df.plot(x="n_trees", y="rt", label="onnxruntime", - ax=ax, c="green", logy=True) +df.plot(x="n_trees", y="rt", label="onnxruntime", ax=ax, c="green", logy=True) ax.set_xlabel("Number of trees") ax.set_ylabel("Prediction time (s)") ax.set_title("Speed comparison between scikit-learn and ONNX Runtime\nFor a random forest on Iris dataset") diff --git a/docs/api/python/downloads/ccbbfd4f60683438ab99a4c42d3fbbdf/plot_profiling.ipynb b/docs/api/python/downloads/ccbbfd4f60683438ab99a4c42d3fbbdf/plot_profiling.ipynb index 8c91e80384b42..18bf323925921 100644 --- a/docs/api/python/downloads/ccbbfd4f60683438ab99a4c42d3fbbdf/plot_profiling.ipynb +++ b/docs/api/python/downloads/ccbbfd4f60683438ab99a4c42d3fbbdf/plot_profiling.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import onnx\nimport onnxruntime as rt\nimport numpy\nfrom onnxruntime.datasets import get_example\n\n\ndef change_ir_version(filename, ir_version=6):\n \"onnxruntime==1.2.0 does not support opset <= 7 and ir_version > 6\"\n with open(filename, \"rb\") as f:\n model = onnx.load(f)\n model.ir_version = 6\n if model.opset_import[0].version <= 7:\n model.opset_import[0].version = 11\n return model" + "import numpy\nimport onnx\n\nimport onnxruntime as rt\nfrom onnxruntime.datasets import get_example\n\n\ndef change_ir_version(filename, ir_version=6):\n \"onnxruntime==1.2.0 does not support opset <= 7 and ir_version > 6\"\n with open(filename, \"rb\") as f:\n model = onnx.load(f)\n model.ir_version = 6\n if model.opset_import[0].version <= 7:\n model.opset_import[0].version = 11\n return model" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "import json\nwith open(prof_file, \"r\") as f:\n sess_time = json.load(f)\nimport pprint\npprint.pprint(sess_time)" + "import json\n\nwith open(prof_file, \"r\") as f:\n sess_time = json.load(f)\nimport pprint\n\npprint.pprint(sess_time)" ] } ], diff --git a/docs/api/python/downloads/cfe61aca1f0a89486c7024466ea500fd/plot_profiling.py b/docs/api/python/downloads/cfe61aca1f0a89486c7024466ea500fd/plot_profiling.py index 402e7b3baee10..3236f954cc052 100644 --- a/docs/api/python/downloads/cfe61aca1f0a89486c7024466ea500fd/plot_profiling.py +++ b/docs/api/python/downloads/cfe61aca1f0a89486c7024466ea500fd/plot_profiling.py @@ -11,9 +11,10 @@ *ONNX Runtime* can profile the execution of the model. This example shows how to interpret the results. """ +import numpy import onnx + import onnxruntime as rt -import numpy from onnxruntime.datasets import get_example @@ -27,8 +28,6 @@ def change_ir_version(filename, ir_version=6): return model - - ######################### # Let's load a very simple model and compute some prediction. @@ -61,10 +60,9 @@ def change_ir_version(filename, ir_version=6): # The results are stored un a file in JSON format. # Let's see what it contains. import json + with open(prof_file, "r") as f: sess_time = json.load(f) import pprint -pprint.pprint(sess_time) - - +pprint.pprint(sess_time) diff --git a/docs/api/python/downloads/d436e9922b51a71358604ec00f09e7e4/plot_pipeline.py b/docs/api/python/downloads/d436e9922b51a71358604ec00f09e7e4/plot_pipeline.py index 0a002f6223e1b..366aadee1c3ae 100644 --- a/docs/api/python/downloads/d436e9922b51a71358604ec00f09e7e4/plot_pipeline.py +++ b/docs/api/python/downloads/d436e9922b51a71358604ec00f09e7e4/plot_pipeline.py @@ -21,12 +21,14 @@ """ from onnxruntime.datasets import get_example + example1 = get_example("mul_1.onnx") import onnx + model = onnx.load(example1) # model is a ModelProto protobuf message -print(model) +print(model) ################################# @@ -39,31 +41,30 @@ from onnx import ModelProto + model = ModelProto() -with open(example1, 'rb') as fid: +with open(example1, "rb") as fid: content = fid.read() model.ParseFromString(content) ################################### # We convert it into a graph. -from onnx.tools.net_drawer import GetPydotGraph, GetOpNodeProducer -pydot_graph = GetPydotGraph(model.graph, name=model.graph.name, rankdir="LR", - node_producer=GetOpNodeProducer("docstring")) +from onnx.tools.net_drawer import GetOpNodeProducer, GetPydotGraph + +pydot_graph = GetPydotGraph( + model.graph, name=model.graph.name, rankdir="LR", node_producer=GetOpNodeProducer("docstring") +) pydot_graph.write_dot("graph.dot") ####################################### # Then into an image import os -os.system('dot -O -Tpng graph.dot') + +os.system("dot -O -Tpng graph.dot") ################################ # Which we display... import matplotlib.pyplot as plt + image = plt.imread("graph.dot.png") plt.imshow(image) - - - - - - diff --git a/docs/api/python/downloads/f8e5d8e309ca291f68bd029c26838ccc/plot_backend.ipynb b/docs/api/python/downloads/f8e5d8e309ca291f68bd029c26838ccc/plot_backend.ipynb index 3dab79a3dbce2..8aa28adefab18 100644 --- a/docs/api/python/downloads/f8e5d8e309ca291f68bd029c26838ccc/plot_backend.ipynb +++ b/docs/api/python/downloads/f8e5d8e309ca291f68bd029c26838ccc/plot_backend.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n\n# ONNX Runtime Backend for ONNX\n\n*ONNX Runtime* extends the \n`onnx backend API `_\nto run predictions using this runtime.\nLet's use the API to compute the prediction\nof a simple logistic regression model.\n" + "\n\n# ONNX Runtime Backend for ONNX\n\n*ONNX Runtime* extends the \n[onnx backend API](https://github.com/onnx/onnx/blob/master/docs/ImplementingAnOnnxBackend.md)\nto run predictions using this runtime.\nLet's use the API to compute the prediction\nof a simple logistic regression model.\n" ] }, { @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import numpy as np\nfrom onnxruntime import datasets\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\nimport onnxruntime.backend as backend\nfrom onnx import load" + "import numpy as np\nfrom onnx import load\n\nimport onnxruntime.backend as backend" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "from onnxruntime import get_device\ndevice = get_device()\n\nname = datasets.get_example(\"logreg_iris.onnx\")\nmodel = load(name)\n\nrep = backend.prepare(model, device)\nx = np.array([[-1.0, -2.0]], dtype=np.float32)\ntry:\n label, proba = rep.run(x)\n print(\"label={}\".format(label))\n print(\"probabilities={}\".format(proba))\nexcept (RuntimeError, InvalidArgument) as e:\n print(e)" + "from onnxruntime import datasets, get_device\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\n\ndevice = get_device()\n\nname = datasets.get_example(\"logreg_iris.onnx\")\nmodel = load(name)\n\nrep = backend.prepare(model, device)\nx = np.array([[-1.0, -2.0]], dtype=np.float32)\ntry:\n label, proba = rep.run(x)\n print(\"label={}\".format(label))\n print(\"probabilities={}\".format(proba))\nexcept (RuntimeError, InvalidArgument) as e:\n print(e)" ] }, { diff --git a/docs/api/python/examples_md.html b/docs/api/python/examples_md.html index 54d0311599a44..c1766e0226aaa 100644 --- a/docs/api/python/examples_md.html +++ b/docs/api/python/examples_md.html @@ -6,7 +6,7 @@ - Gallery of examples — ONNX Runtime 1.11.0 documentation + Gallery of examples — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -59,7 +60,7 @@

ONNX Runtime

Navigation

@@ -79,7 +80,7 @@

Quick search

- + @@ -96,7 +97,7 @@

Quick search

©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/genindex.html b/docs/api/python/genindex.html index aa4eb6187c7e6..78da6edc42d36 100644 --- a/docs/api/python/genindex.html +++ b/docs/api/python/genindex.html @@ -5,7 +5,7 @@ - Index — ONNX Runtime 1.11.0 documentation + Index — ONNX Runtime 1.13.0 documentation @@ -16,6 +16,7 @@ + @@ -63,16 +64,20 @@

Index

A

Train, convert and predict with ONNX Runtime (plot_train_convert_predict.py)

03:22.159

03:21.167

0.0 MB

Train, convert and predict with ONNX Runtime (plot_convert_pipeline_vectorizer.py)

00:00.966

00:00.956

0.0 MB

Draw a pipeline (plot_pipeline.py)

00:00.196

00:00.218

0.0 MB

ONNX Runtime Backend for ONNX (plot_backend.py)

00:00.014

0.0 MB

Load and predict with ONNX Runtime and a very simple model (plot_load_and_predict.py)

00:00.013

Common errors with onnxruntime (plot_common_errors.py)

00:00.009

0.0 MB

Common errors with onnxruntime (plot_common_errors.py)

00:00.009

Load and predict with ONNX Runtime and a very simple model (plot_load_and_predict.py)

00:00.007

0.0 MB

Profile the execution of a simple model (plot_profiling.py)

00:00.007

00:00.005

0.0 MB

Metadata (plot_metadata.py)

00:00.005

00:00.003

0.0 MB

    +
  • add_session_config_entry() (onnxruntime.SessionOptions method) +
  • as_blocksparse_view() (onnxruntime.SparseTensor method)
  • as_coo_view() (onnxruntime.SparseTensor method) @@ -147,16 +152,18 @@

    D

    E

      +
    • enable_mem_reuse (onnxruntime.SessionOptions property) +
    • enable_profiling (onnxruntime.SessionOptions property)
    • end_profiling() (onnxruntime.InferenceSession method) @@ -179,10 +186,6 @@

      F

      G

      - +
    • get_overridable_initializers() (onnxruntime.InferenceSession method)
    • -
      • get_providers() (onnxruntime.InferenceSession method) +
      • +
      • get_run_config_entry() (onnxruntime.RunOptions method)
      • get_session_config_entry() (onnxruntime.SessionOptions method)
      • @@ -396,6 +401,10 @@

        T

        U

        +
        • use_deterministic_compute (onnxruntime.SessionOptions property)
        • @@ -437,7 +446,7 @@

          ONNX Runtime

          Navigation

          @@ -457,7 +466,7 @@

          Quick search

          - + @@ -474,7 +483,7 @@

          Quick search

          ©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 diff --git a/docs/api/python/images/sphx_glr_plot_pipeline_001.png b/docs/api/python/images/sphx_glr_plot_pipeline_001.png index 34c5fb668a96636b93be1d286db76afdf83eadda..6bd7ae5b27746aff35930e8c70cac82229eaec14 100644 GIT binary patch delta 43 zcmccF!F02OX@ZBGv5rDUNl8JmmA-y%Vo5v>*Jue#(h_Ancw-dG3!PoP+hwpLcL!u{~ynUQK+_y+8N^jXD zdd%0?(?>-{#_hjfAnoCOROaKx!q51S<(@ka`cM>y1Nlvpq4B_(qWo%h>Fh8Kxc$4` z-@>H1hhapCo=L#;nLPJ~=;Y|u?#$?7mz*Z4-L7X>8e8S$#F}}TR-R0&Y5d#T^tCA} z?UTx2Zcb~e1*5&0&eeq5ogy>qR;&=Um$mPx9Us~GNv*K&M@MAI-QeNE6=IPT7k=Gf z-QwsU5shEAn;103@oVL4YNw8l&f!C=s2KdU0V|y-UUwU-3KFS`@e>JStATf*(Y4tvTP$cIC&f zU*}$)X3P@Fvn*g<5ktRW-))JpK$8diqIARqbDyz2VmFZu7_pz8o#ihUxTk$6uauI^Pc+~IDF)YOQXk^bhfoC zmKXW`N-r>&6nR^#v1D!Y%%f9%=h_wc=eBC#{$I+c89C0}xpQaM%f&@X$~^b{iQnIx z8$W*hsB3R88WI}n_czC0!&KwQks}$_h4NTO&mZqD9eVzLTqS%_HGSWm*k8?giGf!4 zG#E7LltZRv`IX$yKRH@^sJ|}7;_>0-9f5s9*Kgc#`2H%Y>W{G61`!bv)zDdPI!1Pd z6Xv$jt8OZIx->pk(Snd3AA8*Q?n zL)^uS`ktP$ha4U2vkz{$ckf<*$e(MQt$Z1ZQu}=xDjOSl@YPivrNNJaCSBs3#(#c% zZ5O@}wQkR~il(M#Eq;^3og%Kyxs}xk8%JL>(-P5BzSm)0c*KXc)xxKI6r>3Unv{p*Q z{rl^(v$M~)3rU?lEPwFf-J|aA>^|eMGaI&T*Z$XWx-4@U-{0TN^0o>nxso!tYlT z0=?p~Q%%0_!2Z%Ehhx{SUDI<;+(vs$wmH{ETT?UQz%<>}rPDQreq~MmouOw{{02$< ziHV7A^X!Uf^6_Xdipt24cu`omWBnB|QBkThWIXOb>Cn(|gB$Y86kVGl4c4DdOypCa zAJIO1^r&m2z?LJd*4Ebc9v&C}v={euhA%bF`5kd`au{rQm|;`A6|2v*e4XSIMc_e)!)Yct10JndAUY*PELJEpwHxzo_V&# z$(xF; zudmT35**X38|nVz^jI&Eyfs~Q`fJr^1ERzeYUhzO?|e1 zjo%He6wQzjRa#nFdnc!5N=iy4QyswpBV8vCh&=b`ywH?m^}4Bv_wV1o{h#l%EH2J@ z#HnOzJ3V)A*Q&j%=5X{VBOf2%c>yJM@4}K6H^1&T%OlU8ef{<8!G(^P*x1h*X+{$H zp5L|T85qdANlQ!jH$1#jH50n5mZqT>V*0{JB_xIK$EmjcS__4&Y;2XIJ#Pz| zvIfs3B=8J2=Uv=;YwJM4$GhsGu}G3sRHEo}=e}5WD zy@jECadzXrJ1Y0hgV*R^(7C@mVS<0zRn+FP5arKbzR0<^ZKEpk9bVhJyI;^f$2-t? zS31Y)IRh0}-WherJX7Vl;!>xQot+)hhUYB1kk*y;d$9*m{E9C2A8#u1*9I?4Hq%gU zt*~}=HOBs_)v|%7SW_L}UU=2fVS9VKe{M?=rL!3dh!T-&^|z1W|RdUI+SOT*+3@526;M``(w9&zED4pqkT z9C{PY^{TDSngnawZ<6yAr$^aLI_hpre`8kSvAX1wlxVuajs1tq$H&HW=KlU(Mv*;y zbol)WE_$LNTYicMZnk5#A9)X~>>bvw(z#?K@pBO~Y9 zw2A!w-rp}#Qd(MhdEK7K^78WQN*;Hoe_Sz)ynp{b%4ts3`0H1%A|E_>faTyp2ymX` z-Mk{lvS0=Err9n$CpYohwe_m1syYS+=PjNczj1xb(F++S4=&{A=W{+VOghlKXZP+E z6!~D(yffDoU9VZ>+n;>l)pI83D++hxq}9`7VuC_Kl^c>m#LH#}H_G|^G^l^(X7wn1 zDa`MVq)9pxm8yM~{m^K4C0QaZsf5_NI-^ThuB1&`qSCxU)vx?~e~)hQiQn|pBW$qv z)HxR`{y{arsXsQPdD3W>%>5}o^!r-@`Q43W>PGvgjhLQnwrl(~RG)TM7FiM}pmZQn zNF&Ue;zW@)PAo-nCfmU(q++_suFN`QqF(=1Q_}%gtL%eM^w4kXADV1<6fk;7F8J^9 z@4tR+ynXw&&i?(Ei);@czL)>_@d_Fm8gVJ9-J7hQ8BF|Xx1uBpe znD8}zxPKi9>zuM$bbMDK^ca)yPy6nwK73T_=H}-2Ov9^Nheq?fpz?l-lZ8)u)0iSp zBZpYz^sl^fdTO*vz$2r^xAZ||z~8b@ORFc4xPF5TT<-4f-8~mIc=ue}#1+S{xMD?& z&O8D|i%ASEdc9s8|2iuAqQ;`dLPr@gJZLT|D$3a{3EMy#+oNOk;&Ltx5@MHj>Xe5q zyt(C3CJB(Gqos9f)i%#$N)%W}aW-@KXhj2X;yWOfC{rn({SQqQJUXmHroW#Rmy(o=HBTV&&cNF}kQ8Nmf{QE%pF#tW`Vax;rXa^6z% z;HBP7417_%HZ|}?A8{Qgqe*G4zv4W<6sgOpTD4UuUACmQ#m1 zN&*KT12=F93U0Etv1x2omyt0fkYS<^z2w!$k9&1=bsyH4hOZS86x4BX$<$joMKgjQ zsVpV`OuTthYSZS;x@Z7V*3#yQG6x^)P@DvdG`SjwKFYK`S6p1&k6M}Hma%G9?LM>T z3|$^)_0sWe+qOk>Xv`ZirL+y3Wtwv3l`j^>@4k<$(8kT;rlJ5qW-tE6_bj7E+xgnEF>Bi3;UY`+PyY}9@-v!QJ*2l%C z*Pv6br=pG1^qe=Fly*i*s8Ah+KKdl^&`_cQl3la4oB49^tEwp0#8ap_&yEkvI~xqHC!2{x)jZF3 zP~ME<){1Uvv53<&x28g-M^Z9OA71Y7C@l^OG^QDOe`P}|VwN_7Y58)lz`#J=vh_S> z8i+z&OUs)t5Ww34Mv?(?%%*hj-=pD-AV9HblcJ&-YKYv4Aq&5+7&lN>{fBLHCV6=& z+BFqH=KnCA-babF@Gp<;nMurZxI=ByFd$$XdVb?sejui^ zL6d_i?(IeVlcwfz57{3cZ+*r_$s)<(%Fxb!P4X)pZ=q1iNS?di7>s}U%&k>4VRykd z0!1S^E&Dz__2{&93_63Yrlo?W{;&aXhsAK~ zp<2&OrOc9!rW#3jVn=@T_NI9CRH<+@ql^mxbm_XYxVpMpSXv$eKvdyypsm2Yq92{^ z?>~0^hT2>Pn~(}OJ3D(zkzbZx==SZ~f&Iq_$GCP>X|NBg2WW}dX`xb=T3tagS z6w!+dbFK|ncHckt?dij&?>ndfe2Stlpkz^tTl!!#=BW5vx3Zpm!pe$X+9~T)&7I>k zYfw5iT)rf}X%j2r6MIdCgoMO~ej5Mw!fOpT^Rn5$zq1}KAmNR(4s4G5ebmh@XHgBk zaq3UIHoCrOWW~Uj2L(+F7`FP4KS5I-86P*%aIZ_I5fl`RZD(A!U|oi~N+NLf(csAa z%sUvnx-c!FYeXXFiaIa{Glz#SiONu7ODF-bprW#J*`GgujJ zVwj}9&eAY!adB}ll!n4q5g^hL{+xNsu{u!;3yTa9CAV+fT1+`#6mD*Hi$&y$%gAtO zzE`J9zd%zLp{1?;$g4+BHDH7apC4shzwb7#n-#T@v9C6%Il~HzlGBG#OTh51>JCdw z{?DI3kBofR4jHZF^YrqnpI(ijBjPAuqIIG7vhbya=LbsBHH-`^d@@Zl8e%w4J7=$~F=KX#FUo{>Ws zlLsSeU1V~ysGw>9C*|2+Cl)6Ywb49RR837NH#gVPO(SgHqNkLV0;>9w`P`>(U(Vvg zPc<6{wz9CWXrpCg`es350?^XoZ4KKJ`>`IlTOAA^=i1j7u?lYEeE9HTOL@3P=7Ai` zOh2mHr}s}sY1XJoi}D5FoRgfizzUzgh4D#S*R_PbfB$}!YJett??@Xcju3ubZ*vJ+9BgVD>vh-LOcVadtk=WZ~ofWjkzQSz^|)`9{bqs3fkXKGUA5pt^V6eb>M)hkwYI)p z^}beWMqe*>g^*Aj^4b9e$W8-;HxH7+Vqd)2HV=e$tR>$eX3qItbM~HH9VWWYjhQ^& zK0aPQ-f>~ijD#jEpS#DQpmcXvp4+)+&ljc$<|tZh-SnU0Vc%R6o^I1n>*5oek?;kB zJoB~syYw|p!7w%D*vc}GV_E1zXC$AOI7EUy40veG2oUbA; zpFdq#Kk^-SM9qBn?p@uq-57Yk#u~PPzrR~8P4-)tg{-C;?BdZ#^#L#QQE%dYn_Skk zB_DoXXge>)%gTg}=A43p=TXwW1M-=bH(_*0LD~-X{rK@iR8sO`%Yx@9nzcdxo*GF-LcA@nwxVp1&eFr&80>xI{!Q0@B>svWqh6 z95`B^syi|=QUQ`c7E{VRuCl*5FUj^dw}SKMwIMUTiDX=DFn7<=J0JqMRG)ZCf79-6 z-HseR?CU6J{>!2EV)MSG0Mov99#wjh9dYBO0t?Jr7%(E8~YH&61_J*{~(64)OEz z$1W`lhwt3CuW1!c$n1n900lkvIv^k*Bk2pS99KieGRt3}HBFwc6c%P@WMuqsTiK+q zFmPsWT9wRwlYwmP>H#)hQCMV639PjT3 zr-hE^i1{`C{o%n~+s4Dcez>W~f;mp2 zR^Jzy{&Kb?2^K#!DV;09PwF?9(}Zd=psYNCM^&gXA6nk`$$WB{E>FcWl)q(2GumRZd9QeF0XXe+dSFc70&X$&DhyJkx zR zws*JtOA}fV3`t9CD_>!!ww6|Y@RU2K2$8#Y?`GJR7R}O1gig=QIN*w|Z}Sq*wJX1X z77gxCc-O97El-_Sc7XLKY%Q986s~~K__)BAxB{>q0e{Ay?M~gKp6KP}MOGhpi;(Z6 z5uW3d(F0p=`|Gx>1MR*f^*BJb9)u`nUL`Q(UO-wQbHATwnCIQK-SMuzo(s*mY3>kb z*VmLD?6!+wJvvJT=(M_g2kp3XzW^@D#wq~YB2=U%H|vvjIXxXfB3NU7gihte5R-?8 zN6Et9)>Rr|s`vIwmd*SWnC#0}ICc88Si){XVS)D4UVkOUruc-V&kz1nWl1!&eKZPJ z(d*9PvW=g++kl_mK<0MPsg<}|-QBxm^=zm^(<9%z(WQ8R)K8Oj1&k z{Nz7GPZQ z<8E%cm}%a8yrndGlR=NESAib4xB^(sd_yIDpOZ!n@nUA%ZP$jamEV_lHb zE(Rh-7OgXh57TuE{fFg$j)$=oRbOvxaq!@B6n8m@j&aWJ%(tY|@|`!0ZTB0z z+TU4TKJxc3FV_A=QBf>vtxL8YQ?KbdpT18#2u&WyM6W6<|1^$dUR?BSJ#bX6L6E2Bi~j;+qk~oH##Ml;OO~H}s63+e#bO(ZYsFe^*qpRLDcv=H)0c zq#BiK=xa$#HG=vjnH+Wc^y#47_h|N`)1!_#vr(ZZL{tMr!3Uqa&5$nIxcH&G6v4b1 zA^t`rd_Lt#Iboo|c3BR$&&Pf{qb1Q-e0BHz!GRF)ev%mK2(uLR{P}Z0?XZ+D6}|(X zbzMW3JvhOo6-}5{!cXqJzdugWf%z6gde`6j$-))gU$>&+evxSI+hRYsR%=y1tL5ig zkb-f$Z1R^Ks?m*3V&QaQ+^Ze%neSUa9OZaITZe)aWhq1HurHjHR^)oFwETTYli zZ7T~EK*uLNv-9oO>mXV{OVFRu%#>Y4y+4e_x%z&m@sT6xRi)c&E^DP|?%T%>iO_au zaIZ1OWvVxBh^<%m&+Ayt0yWei2x*UswRM~#&PK#6c7ky`^I!VdzJ2=$IfSV`*;wCC zy$wR{=+9doWLPC4T*|MK@FjIpZ7V7?TfTlJ1s9b0w&1_nwxO4Iu3aT}h`wy@&vvkN zn(MDPpv6!Tm?H$CDrzQ3nc2I!#i86}+m)Bq`C$iEqj{b+SWooRAhj8c3rv{jK;WN3 zNk5Qnk@Cb2v-tGTliIF-A|nGdrjYs3x9>iEYRc$?O#lf;h@fL_FXT|Xk-*WRbAM^5 zt?q5nxIW~q*xI%9SYc`JV50h~tE*EH=)cnW5UlBzogKxcs(af5Ws7U%#%V zNE1dRC8GmeSMie~>LCWGG^d(tKwek%-cb?c^U-Wxp=cMBC6CV`LT&T^BS_L16b#u@1ju!HC+4=c zwx_cbpSBO%WAy3&@_?i2g3vhteFApCU{oOO6b4ZZc|gXm2MAIl3<22#qGCW}5=4cQ zBi~3tDAmT=dI2+CzcH{_?wn^^N}v{u3(3He{cVL?5G)i0mPrY?kqv-}s0Yy8Dq?vy z5-ZA3XSoRU*G7wGXr^7=-KW3=uK|@u5rYXjoVcp0AVH2-HW=m~|0@5~rIDGabslrT zu{{W_D%1mrL+2VAOozS|uz-3&*6Tvs*1I6M9GoWPn&p(QyFQN?eUbn01uRbY@8_L* zuyX+R%7x7bkP#oFki_WXCP|ytv}AnHWbolvk;~z@AZQl7pz2VwM&Q_CgCun!KsLR; zPj|cq8zg;)TDX*zmH8(pW~&#LmbzGnHbyW_9$ZMBm7ZAvt3?zfWP4S*3!lwCwUTY8Uy0XG#{P*9*}wedhU zC-nv!bgpeZASe_uXwZ6rpgy9Y)xJ3K`)1J)SO%g_6AEBZzHu%E<|A;NhBkLET@r&r z`37;V*o1CogHb+1Ivm!7Pk&jMnV2{M!*!dCzm^0(fhb~_lxy4pEgU4j!rwb(b0&N? zt-1NXFNGh3!pW%>jmTO~5&KL~sdNH%*1_3XvdDKp9DGR8JWYWGaMq)(+RtImUGZtdB1b#&I(jig)piM z&5jH+q+kFoWc^Y)R!0$a0c|I}AQu~Lm$%hP{zj0(9_hrM@}hA*h1cYgh@OQFN)(r{5g;TVO?K>}(FmaSXAKJ{qrT_C9g&2UTz zL$pwAy8lgBPEL-$7fHN~0@-So*4Ei60x)W>aUkwZfot==w9RIPnTG42Vmtx?Ix+Nh zrJ_rNQDSgFK-Wj5&NnIAXGi+$*TnS^?Wt$}8Q}Hz@2}4SvuR+ada!uuAAv9V_fI>E zW??%-h)3{qfq+ha6WZv6I*TA#rRZ{1Z>HsuBV-cnu447M)};H!p27X8D#PA@Q13o| zYz#&%8`eX+MRq>)I;NnaVwsgIroLrHLjaQ43;$tZ%csX^pf4!Uh5k(|8(y9o8+|t7 z{b3L&I(@pLO73kG1%#mQdayKTGXDDY48Kd7FSBA;{>yLz!I&EX7hlsm=rk*wxiLEj zWRgARBJ9ukszU#wPioa7Pa&FQ-dpTO;J^Ozz>r7?IYCfV>zQ8S^CNEDSPdQcp>b_{ zyAT@u;O~PLt-#V01t-Ft-uuhVoSmHmKtHF<8DUU^&4h`G$taPpEf+j6O)_hG5!64* zh~X-sw})CD0c~qPIr6ctz}1|UUx5iiz`8%%liSiUyX8NB-aJ_B5*SwbyY_QkpPCRa z?-?WwoN2r$NSef}hg>X~`FTs%Rx*1q{N+^QxpOS!;*F0)*BYS4uQ$AV-Y#rL*Yy^r zBDy*cjlsFQqM6Y!BJLJjV$wD~^67Srp~eEYv9U1$21bS6PH@GEsi^QXN2NBn34w?s z&4tkK1WLVrO~=d2YfaTrjCfc6WD=V9ZJZAaH8+y87|imp--4AX>u~f&dt}iF*c> zmy3rdiqM8Y0fXamNpHu)j{LteuuT^FUUQGul7KifY%3p_nYCNSrs!V55Ex_66DOo6 zxy1-miAWp;E#`U^jsl}ln%&OFTk>fR95?_vx?xq|LEQhtroQfOTIgbv(fVP_o}c?i zjxNLKohqC{8*%k2H!)k4s@bhY%Y;FIyNKiChYwHn1X=bA?f3KZ(}iUx*6mAeEeGL0 z5$s;Q)jX)pj^KBvL3Gpfi^S9PZf!3OR>GjKphqKPTasaGdso4=i52tcYjA@jfIE&A z5j5z7A|q(R{n>egOJGtJ*y|tMzwaDZH!ycY^7tGEfA&NfyDHGwa!`f*3J0%VJQe%x z;<`Y?kxaYHV*%`NdWARgof46I*=2qX3h6M*t!|F%o)Zc)xcBP*_+~=!otExfN$gWaCOZZ z4U^i9wn?fFXvnxRP~@60eTj=}T|}OQ#!^AVp4gSWa#Z-o&-GA#O)AENY;as zUcSB|xi=O-{l;Prc6b*rcC0>i8JSFm%jWhua^F)xCpZPno`ymkF#b{L(#@N(Kzt3^ z2Uik8?_tww0fBR%U6awxS8YAMiqNF+(EzR=%iaP~`O>9J)7|G}h_psP9LyFK*sOZw zEXc6Gg|=4Cdx046{aRQnS+IeGxq^WTh`j2yvQKPi8L%|;&od|K7*iqPgDe(-i!uK8 z?elPqr2;_Lh1pk;sI zVGP0ANCi2Nm)7NBLh!z{6#8rk!%Y!mmGy{&0Xjz&h_cadu6ZvJ%pfKR5&ylb%jie= zRa}HDY;12TD^p-wB_NKFKVVo~<05~}-54DoKYiuON;o*!0Xd1w5$j9nN;E6-K7y!- zteo#~x@l+HzkQ-lZi7`3S~wz38(~=@5?w8{#wOHY;#EfaV+r@cSk$3&SPN!kCayvh zMP)sv_dH{LMK%Li0BqfkIyuEWa(v5-kauu%+idylxFiUFaqx5#H^u2A2=(#F3AWpU z4703j!1Sq5q7Fg88(bWC!Vdp$+yHpvLx4&DSPVCHTu4w%Oe1xHuk=HGHUl zgbFgaz0LTrlaq5n{rx?BrMBh{Uy8X+O-m6dF(V_MgkU;;{J0L5STQ}BD|LG6HR`r* zK)?%7iQFhRuWD-zS%pU_m0R}#aZhSlBs|!tpS;k>%?uOLGSh~`xN$$Q z=D|)7b7_q}GwLAF)wXr43BfDGZ0lAxW9ZQ_l^zk)gkk9aulapspJ*-NHxbY%4t=4b zaLh|FiP580b`1fu%L8CWhY~c z>s2vKCvbp&K9!i5I2+u?Ek~&{Hage=DiL#iDs$CU!%q2+be-gi*Ps8t`S0)2SyV-G zzJrt6T3YFZd4}NS-SDGiJpMMw8nI#Qdof$m@U^s(Pn4LmfIYovU{(UA_(2SWva z@kSW_#aB@^(O?hu?_U9y00KDB<$Gh{&!UlpP=M$jfAwl4M$sEXk@s|TCJsTly99+r zf}0tW?aQjFs+RT?@9J;g__5DWF&M!1!wKp%B#qMp%ey?aSNBA-^PC;#5*H7upZ=(g zn;>Tl_Q01y1LpwDFp4M4t9jt=MfatnP}SM-=PgG+^_!KiC0tN{fB*i;ODKwXlM^`3 zZ7>jD5YYhba&@EspSB(Nz=wmsR<6Pxyps*!Vp@H^xH$MmQ}`uZ$hOTaTwJA3QCTgC z%1Q_VE2}gxpb%E*FrU*9Pc|F;!!S@2YckFV^iM)wX%yJTShMj`? zD+ak1*OcZT4jztpWQm3OKTNzNg5iPfA_kijjEuzKirnG^Jwa3>{$Iy%nn3UTs*^-= z*}i=Z#zB|{PJ=-L$6W{60!=y@KHC?*1D88O*NCTfOLAA-*KWg!4q);JZB2h`CWCj*3O+w#D@*2Xb(37EO(-)o#aC%gNR(fp+2p-a1&`yM}g~F z0gy=y*Ck7fbJ4I@|MFYObxFSMemd>aB1>Dz%uwfid1ukGAH4%%VL6tXQ-5Th)uu<# zj4TTpqtAa5Jo;NbjJ4(4p!pPfAL3n`%;-HmbQBXSD?LSqS^{MN#2P2h6?6W?97JS* z$4{ORGZnmhgV_(5qhMo`tWWv=%tXe%AS~@r--Pq{lriO#vbCwBzp?o%tYfT z4r>qx0I=shF3PnrGYamGW5-!2kSq+S*c3$+Zk)Y{Pe`a#o{N6>1DjSF{OzQ4_`701 zmUkaFhuIuC5^2wkB98eN**!`UkHfN@FL?dx-YSa>)pX#?2t}OgZY@h_v_cM8T;=u zQ@!8&U_>N@`788aLbt# zZpuz{!-HwRU2Cg76E#{MhM6z?`c89wOG1fkTZ2q|T%5PUr&YfP_edoi!i2vKCstq^ zjR9fg`1#(h7C?rF->}_V$`<}w2`YQjgE!q+?<1h(p6z9pf9uw*19#qD6hY(c2Ejn) z@tUE<@E3k~2T`J6!3CSggaH!Wea(XkyUndyXLfDgw5g#y%f0V`k;Lu^%joFpm0}S~ zi(f*wZCxt=`n57|k2p)(Dw+oz$fi3rA3sSnYM_urVNGUcY_I z2n=&7FHh$0(AU!#Y6nYm5ug-uKp*CTM}EH!Or|uPGVPnksTsc;I1hpO>EMr9XiH3} z2AH~^y0=>%y@Lc7QVW`>u<|Hfrn$O<_!iKPO6?fAjCIB6kxlhyot75(-c^702z7Ul zVk~xPqznxsuB;9&c<7hdSVdP(Y`6P6yB zr{Hf>@&5yh#R*c^_-k+|ir94xZf#`)38sg7p_uM1Sxr3Yd>I65fhar%k3`Xl-^>(o z7>s~K7Db)hx^-*7RJ%U`q!l{?_f8fPP>VA{JN1veOXtV$WabDcE34LiDu3{6DTDaG4j#hI3{TimKGS~YfXclW#V<+J z7MKWKZsZvW@LINdB{^t!`Q?AQ+ zri!v)UcP)eD4V+LPc9%863=odzP16E-!3&pBQbVA+sWwQT5kvu(b)dvIR zb-Q1Bnmwrk$J%E!UWf)@3Pe8_g|lT zh~Na#ITXVR*ofjE`ao z7&J3E2|hVk^)?W`HtY0X8!~son87h~z#w{s4L01uKS4F>hH}83{o+)8j8) zqM=|3J6&A79c;$Kuuov6fU{!o31Gir)6~N7>oB>bR5~#^*{Gr;06!AE_?aSm)~*Pd zY%~w}UC?ar=y)19>^lzn(NJU{!r_Z$6!CCE%!0j(Az76kN?wlbMHD%3iWgApUw-<; z4he*uh>O2=?ToNm5NxgNa5YxMtlXe5>jUi@WsM)=0}&6PamOEQt7E#vCBa?2>*C6l zC#M6t7N$<-%l7WH>8;kRxmMBYL6;QHejF~nt64^HjcPtQQV}m!G4vJKM1rpS%Y*8O z7r{#ThnC5Psn%ujadN*I(Kqezq#s$fLaS?+yPOa2RT=>nft|ZOkN3j<^alKUK8_ns zPfy!_x~muLf7ywaarG3>vWmSMY9vyg)bm--&Wd!Sh<2wnE z_~FiWKH{|_{u0ol0z_Ga;S_No8#?P7f{7d({~8BfWe>e!0_=FKlXvo+(c>ot9Idu5 zDC;8A2?Z%zTg~<&&C;NoOGSmFo|}zz-%``GYVSj7i(l|9b#}d7De}7M^MSk~u!}hK zvl{R#Dmt2psz4~jpeuZbds6S%F$v1P>ilXZ78W|n;JPf0O_47#I|bd_mttg((F3Cj zBSqFE`0vn5tQbW>2B-om(a&)adE=i#~u^*?UvrB}|bGH2DP6^g@fHBG9D+f`jRdgw@TWG|cYcf8(C1 zFU|W9(YKedwBXyW*`W15=Fr^YUu=IAr{-d1Io($f-`+KdAr_q_>Q#BFTuId%T#SQ9PcNd?zw&ZfK@w=05nb?_A=3jQ>*hg=K{P7M5ys(HuOKxU5 z5F!792M3QC#3J<$;#AC~g^k&vq5VO3bW8sNHT9HEb-YG?K5e?s{8nf7-KPWlQucc) z40l(iaun>5>yQwqlfss72=O;{0Wlh7)wYjoH%i!<(ZoRQavA>k$4i4XnQu4de9AorvXW9 z-OZwd`yhT-ry5>zRuXk9e@or_eI);gxf1i+KSL$9l}s*34Ttxa*D*MsmRetEt(@xr zca!JO4^P4|md`7*vlr=)Lp-=!tgmBg32f$sn1|(cqm|g)i(cqTl#U#YC5Gg)69=ije|q@ z*}BxnVqD7%GsH`QKbb)0?=&zf%fIg>cY`er%%pKCaek7nds)8TyT>j#)*4p+pK$M0yEDa=%G12cb03F{QmgKIs zO5|Y;e*eDc*Y<6A^)h-&)!R^qhYcTaBNEuAeDO1DQ265V`K8U71=F)G45i7UPOD|A zMN<=L@S0NJKOK$2jm5sZrheCL+MK|5=m$qI8$VUqwk|$8Lkl!U6gbVbYuENGUXqo0 zoZda6wm&E^u%fr-=8oZ^udh5}eh$qKsj8WEWtp7y8RWV&@LfT+HYKA5I-)Yc=qOdD z5BFE@RJ#{T+>_ckukV5g>)w^KH-@u1-~UJSSYLx=uULEbrr$*?mKzm6`zvPsDNA36 zdT^3v8?D6=a3c`(;&0w$rqJ(=JC&|68C{rHLo}0e;q85BdSln9W7kEEyUWVb^!*GA z54mQk9=7syR}*@EdA)e*(p$>n46NTYnnJWOzFywm`^(J@5;&`aJB5{L1=X|Xr)o6{ zYQJ82A5j%|^5@5s>-S!D0OG<~$=%OmqNO%5RLHNrv=bx+4Q>UtXa3^trtAkTEUy1} z*Lh_F+IcN)XMI{k?$U<9K*`s(<3Bae@m5zHb)I=uyhmr^vjY`E0|&^iu=guzs_RPy zlutA$turs&z;J)*W}PqJ~^(UWwbd8vy26hd$dzJ@kg^*HP%N4ko=w2N&Mq-t}k-8uxB*m`dV>->wcOEJ6mHkKIm zOnY?=n0!2@?)YYx) z)YbY(d-dX&UA|a?l(ud0iRy~xr;=Si4nO^~g6k3&zS7KoV4&izTCLv9Rj&-v&O4wQ6{5huLhX^yb{T^8ZS`mmg)qA}R2aa|h?Ajiac0io-}Q)6Rj;xhza1de}oXm2l0==<_L^lY&@RUo3-)mt0&F5UM z%BgwbNHxp$fcli`P=zCJpT&8AJ`1s$4q@SgUf2SEqEzXaB zmFP^-)^z{#q?ebsI?MO<>x7iNu+V+=S~@yaFR7gqf{Sy8f%Rtwt;@FiDsFlzqsN?y1|{P@Vh7n^nKCqs9(c;#gqs z&#U6aiTedCJGwAaV4fY#($RbKV(hgukG zwjD>d<$b|P6E9C{c9QN4tMRA$w;NByAgOR$>vu8r-r05_m%b?n3}iy@ikLC=V(l}O zS}<)>liu(3xau2N#4FxCRZp}_mgdK^OOEVy>KE9?IWi`1yF?~AdIrs)0ky!?l6c2P zsjlapcN0J+ht5fzwmZkG`eu)gPWtN~bX~4_rDtG`O2Kc7@~~2PzZk^nJ*V@>IEM{2 zBp-MiJ9i4NQe74BTM>`*N|t9IOcVTF95i__ zFpj^vPU#qDSC3#UB@UFVqzJ?N)gt2GGwIpiX+!D?PU@WnG z{!`2rBs&itIg>2G$S$Y}A&>Cn|KWUH8+Yy88G(@n-nF`?&L%K>iO7_tO}tu8BdEq) zG9}#ghn;m5HT3QNCXX+As~LtnmI3Am^zxk106RWkJ;`JbW5}sfr#KSF;QJ5wi z^A~Y07Y{VB`iGtvtdw}9H?mC69Chk%Ei?(dwH3{SW_H4up*&xBE2dU z@45{e7~!ya10d1p1ji*|sKNW}U+-2`St+)4>obEUU?pnbZ6n*tx$-3%4iR;$rlJD* ziPFU)Zz(=pp41Iy0cyCtn6c2B9ST64H~s~4yz%g)Z+{&P%oe&>C-S@s2!SaWu2g>Q zySC18jjubdrw<+PYPL&A@p#LwDQ$ku>L5*N@J9W)Zv{R7HeCB*K204=W;nP2e=>hB z{smmEv_EgBofh@La3jZP*peE~d_Hm7Y$>5_*I5>kmR4T`JLkmbOuQ4w6(Rv)%Yyz6 zEvEp@$e%%?JG6Z=PT6mA5@&TT{Jpb%D!atRte2v^vV|4p33`zn6=j+M5g9%~>ELP9~8qJrP%*0=zJKmnj8ru4dCi7t6Vfo(QEy&%D zyL+V+T}TZu&?{t*z>|r{nWn~zW_Y+xFfmy5 zRmIzT^$zgLhO5i^tdGC(aMSn*#lUXLP#!dS{+k*S)@y!Ix^GQ{=_4i@oXR~f!eL#W zy9pZo^n^*WqkhHh;jKs!?~``#4|5*&3gC)JB|VbvjrcR&A`| z;nDLq4&^A8@KWg^Jo%iU04T?|w9UDaHCkE`Q7k8~ZH{YILS%mC$fFHoPd~u}MZe;@ z9GYVF+dqFat#5nN9_>iShe$D-%q=!W*|nNx2Tw&fypHIycbWziidlKGCNbelk?cIm zjoBtudV{FykIPo9h-k6s`mXJCaJZxT{hcgxC6{JgNWU`Jp?%mrIl1brKpIhroq>1l zEUtUa5ifS_MaJQsucKHrb?EEvpOc?2ETXjwTYg*h{fIu|?J+7YRk1Kv(O<7=FPiVj zXz!3xlJ>T@regar1>bBi@fe?ZrCqUJT86{ok(P4c_`+QEV_`KoT^U`P6x=)U{Tat) zscWxlZK|DZ78k8%wu$2D1&k`bvM$fb3(k89SM(Vf_i+_@>ndLw&nuS_F@H#F zaEqa2PTKy{(h5$l`aQX+Vc`NR%Kz-$8B{dZh{YeaetACawKd-DTxxssJ+>lgMag(=P6^RCV3dM;MKWoNIJw9&gj zziG2wfIrqvirz6iJdshA-kQeg2#H;vKH7r^BXnq4g)(pV)HXK$*JWLx$)`1zh!`$s zTyH?Rx9`7J;G9+xYGo8J7p#Y`;#p2-zszfBm2A+{F*_>5R%m+Or>mg(>Y9HB^I54c z=QJS~)p$>?|K7COzDqOt;1;LpCr{|QyCcT?@YJPMi)0Ufu<}#n;XL)pTC)f4C!(sl=gX`eloKf!@ol94LElWK#a zh9M*lBoaIoJ!u!!Ux9(Tbp3iXe0R*?Mq1#%acRgnNpu0{Oo7jr_W_?w4$_#UOPsa` z83%Pxsgn{GuKI&c#bxHppv>rrCWI%x&|o9&kEGv`1oy>4;bB(1gyX{8&FffoUQXwW z%>64H5==@0g6VvIQlWEWMl$$-)$DyVA?!|y7mf57@{ix}R@ZQKJ)Lt6cU=)ko#gY} zzzHD)$}F@+MyK`$7Lz7_+DFgL_lCSjv7wJXJU}N8qJxKw)=mo`-ltYGG4w~l`1MMB-8|Ka}Ze=$uU@}0#XBfKWy!S z;ro~Z<`kuX^>tkY3A z$bd=y<^TRhlFJo=kt9Bak+S`Q6%a~y3>PVRbi4s)=^lLq`y8FY&ANh0ggXYOH65@w zFFe1WY8pd%C(l(N#$?a4Va!++zA(uL+KRP))4$t0^|F?x1m;6nk0K$ub-_bUBpDnEsmIBs>o*c+ z?)2G8+||~^l8%nd6|?5jf^^Y?p_Q%F5_c{xAD`&D^UpGZ$MEzp96gI`=lQoHJs74> zYQMu?@NkruEC1)ng*U)8?$E&C#j&<->&_4~m_&8#~ z{qG%{X0nIQg=eD_RBzd`MUhsFT*KUj9TTd?!wc}V})3%M%5xe^pXlxKT;QOKUl0Vava35;^a9dZnY zgy`p|g4s(FSP5)=Jv=PGjXwJ_+*qI?;g*OS14De(>iDiOHDO`g*pVW4)T{y3O8p>WW4so8b^((v- zA0L5Yd*KKI$T;foNLBbOXy87%T9DOQWmjIY;1CA8oSo_zoc+ zpp0MRUm@42Iyyp4LmhR%(J)-_mWfPqEAJ@WN-&<50O}0aL+;_QD1!zgeDUANF+UQk zuw~?&(*(2V^xwB1CeuX@zIR;LIRz8j+xU;Gd4|`a3I8W<^{6YCFSC~J{ui^Nr<492 z1=8ugwL_0`JalN}>(Qi_c|U7=)r8WJw)46F&CAUD&bf~F zI_F%MYli6GZ+V{kxu5&~em~E4L0Ik?L&$};&>PGCFKOi62Cn74FV@((=zL;oW@>tH z;hU<-TKURQCnpmKHwgoK_4)|G=|5j>R<6ce(ILJs9H(XvQx6n}w zC9VILMa@^}>)Q)UQ;0HGQx`Az(?3h1VNPLKHf!RL+Oow+)C?55r$7XKKQi+b5E~C^ zRb+BCvV1DElFCLO_Z#KVPjX+!_|fL2il!aDx6zcOk4+pT4{pm>Lo~fzT=Z-!ih8la zm}2nGIt9|PpJVOg7@?&Tj7McCLc6yM)B`WAgT1y-(Z_CXvR#aeYmdYqk)wA}G2)_) zZDjg*XgE7LJ=}RFH#2<`Ot)fgxKxs6?sfgl2-_= zj;0}wrbAGboY+cV6sFprrvw4UUOR-af@HfPo4sSIXvm`U3n(?r_|qID)+q||dc-d) z9Zh>&uMJbddP@zm#1w}fWY(4=sEyHl_5D-+fv=dw^hW0efq~~)2j0KuI^JSa@;H*{ zUYwT~inQoYFYswWK?KoyY(ga_bksQ!?-s0u3YMY43@QnX_T8f#Fjbs04-_ceFBx~o}SZREY^Tc;Vq8qlXF_<{J5oAi!M!cMVSu?VioQb zlO2n@i#Tq?2wgnK^Dv;`;m^f^j;HpQ!t#_T+WfU^ly-1u(Py&&qeop!D5e#=*{PS7 z5%za%2kFR2kGx${hXLb0klkjeLwaWsnb2`uN3&zAb!F@Ra~0{)?Ar%Q2Xs$==GmzWC5; z&fe3{5v9DZ<&=Fry!b)ddb)uRFIlEt|KST6`bJxZXi6fq5jsFwhkC1&A+YBH(cKPx+`(}waYO3t-Y2W{(RmLut@^>=k+mGCAWt1C-$7$9vK4 zplRDXd#t*1JLl+^^47fi^4;K;;@`erZ~Io8wEjFp3P-z!!nHH)dOh{D!T${XOs#7~ zvZG|{?0b#;h|XN|L#^eJMXe?7EEU})YyaLx%M=oHDa!DCMg6WiQb?1MZvDZx^N^&H zGKZoOf|c5m^_-N&k=qltSH^`480^Ldxm!svo6&2bl5^?OIizUP`CnUt?tbgjB{mB8 zR~NBJ!qP+Ar&^J15&zD%{30dfyYG6t#0+dfF~*6f`eo6r*g&7~ShEft+A((F!Mfa4 z=SmG&QauThv<5>_#!JbFy)3FNQ5~R%8rj=m{-O($E)oH2r-wnhcwh0y!1ZjSmOctg z1?!erLElFPgY-(b1=$NHTa{e1>$t4UMfGpTdo5{2)3;#4KbS}Ib*lwsoEUIB($yO=|!dH z2uewt1R253H;)%hjLjtZki1EL*1J8&rO(==lc1}S8;gJM+Gg-lX+`^BKrwC>mZJAY zi=ibc+~>Ipd+9X<%PFkJ!gPooH)+mGnIiI#@22M~6UUEl*QLv)4GCSN`Zpw3H*lXu z4l)qsrzf?aUp1in0a4)}{ zbmFBRo=?%C!qF7XeZvzfnY}&rN&R4$ct86&UWBPAYF`qFMWFyl+sf@D^~WfD3`vXe z>$hUPBPP#zaQgH8=5h^W<4qN4wg|N2UHu?|KwNd`<2q-q>1Xo%vh?~Ie1~(4-y?{= z?khWTu~+tJmV2pp<8~dtB9B%-GY>Fa3VzG5*ay_y3BB|Myq6)!yD-v$Cqnz}R?ZQ6i7RV9U0@)iMG~=M#Re z^Kbj`|KIDAO#B0I|9{+E{Duu16m+pDfz&PocH8C#_S#by?AZfi*8rK?#+VoZBu!ng ziud{|{rMMat))S9s}CJ9GS>g|;|Tu#;s0kh_rLhb=B*W&S>XgbRP)WrH7`)-nIT>Y z-uD1#`RUsv@aCp#Ued!@Y_gcchmr5!?kdu9?hK7c@g@p~ebm=0{8t6yPtMA~nGofiF;^D})gWI6K z)hdvEfor)N4X@f9jF-4OpqzCt9P+wA>k+ltj~=a$#S)jg9Ja1l6`3MjvXz#V~V_Kjl(2Mgsg6^FMcjd>V0`jgYtl~`)6~OYaG>+u9~(e*$~&g zO0?W`k+_?k$fnvd+|$H)-N5?E5uT5-0yd{zDy^!nd3-9nBq|}hq{*Vu+UEnRvW)zH z^B?%YdSvNX!}tMfM(mz;xznhYy0KSurEez=!MOvzIv} zFdgq&#?vUoF-78bqWc{PR3Q+6H>#W*%}hM90^2n0Tr}6U+CSNTz(FZiggE9cSpBG` zZQ+|#@B4dVJia;=9~5J6q1(_sY~`^jTMLgTmgs9`EsSXRX?fdb7M527N(XI?zT|D* z>E_Lt?VI^Y*sM89K*X~9E%jXg(!~oiTVeP8z)AT&jZNz2bnv4fYqe?HjH+R~CnqK( zCaO*qJZap(ceqKDte-C3=rZ4EQumudOF!|sd}-{XE#-yntA?4489%I>cc&98;;$Pv z^($X`GtRT~M*ErO?x&ZU6Vt5Lk@cnaP|v#8Tqcuc=_W>x5>c< zTnShKQHP;dHx{!rZCF#n2cDHHr>rurFuf(*CRdh!JUeJ3HK?(VOguKO@m!Sn_Vqxg zHvW&3!>X%OE?;ziWNKsi!!4_EFXpWqc;VI#JwL-<<9AFtcjv5e&jTe_!U|fMXv7Bo zV}t%3-+F~xGfM}a+*^|77j$l$tdh?IFvrOn$Byckrvx^*aeTwX zCdQdLKW3NJ=&TOcTh51-8rY2u>|WODw9V_u(I?x7)NMMZ!L}XI=g#KX=Pd~66~Jrm zz4T^6%(};yKgx7l_13E?wX-og&Zo!;lDuNRxDhoh>C^tLeAmS{_EFicT6K>|>GDw> z?*Z5EB@EcUxKF>v#2vX!U+A_8kG+Cwp@zEU9c5LMq}?{`fh~iq{`Izs9ci zsXG5pX9vaH{kP@G_)?huwt2F0h!MZ=?IpEEScNI5FEkAkO!&$Oyz3DNEPSx&%DbZN2OiEXE;6b6Ke zhsZ)uaK#PU8`A~EDZJ;~-!zumMq+L5B8+0-tX9a-J9O+=C%4*SFkQlCCXJiFx>>T_^dQI(dFOWj_2Mz%eAcI?>kItXpp z^^d3T)$5^*i9Sd%8y%|DdjfAGHxZ03p!j>?gBCB+F%gr(Yyp6RaFU|tw*$dx(d0I+ zc*NwR^#8$k|M_H<(sm;`;`B=@k?c zN#z;xm#}dum`YVhls%~Ug;p!XdjJBx{GWenD?m+Zedx~V7KAX<+R({zm@>tbfsg$< z;qof?Z%>?XVme%Ze6OSB4b01uI8*-=W492dD1yCx{rvLfVH0}(?wjTI@;AV?%9XdP zIg|sa-|}*3q+uk3V$FV%^v+`Z>6i<}!~xq3 zW^Zxea)=dWbk>4KW&WrZnRiq88+jhqfd_9`3o}WU1-dePjbCUQtQkXcW)&~CJyQr; z9QEMk_OW)Jo~@WzjUYsbgMe6KrV0}13teS~wJRGvk?XOZSby5yAX*A2s_rQ0XjEsQ z2Y4xVsGFz65-fN?)RgH|&3h291-i{xKFd|UV8V!DLAMd^0XA;iMV=WY5Xts0*vl>B*yxD4fme*J(9; zCk_|RR>C5GJ&?|@oR*V8vnEX6UTDs8{FL$M4>-0<(Z}d*Xs>P1w5hpq-`V4f3d>+y zP_DaT(V$^NBZ}W+2RG8yHH2f<$$t>yohg9$jeTiEvLN&5fAO6#VZzzW%%QDpmyC}q zhAq^M*mC4%q0OQa4n`50O;KTc(`!C+a$XE~v|LX^CXQv<+Bx-=k-omt>-hBg=8V|U zX`BW&^?+LhrP_9!o{_hRRL7%+mccrypaR*ae9sAjG?I@VKYnfIbLw|O%U4Kk_GXtYJo7qJbqIH*(WK@rZsl;^LVGJK zefX#xq}3i6RVWyR7KbiVR>kGHafl$$#J-1qRZUG54eP{Jt>CbpxWUtieL3EA6Bu6pm+wb4Es>h>y zLD-hh!-&#U&~S(otOrY-VuwTtWS$Wl@!%}`!q#-T1E!Iu}KvUlq|2R?%k3F^@UA=?~ zK3s1mp>JZyH%v(ZRI~Zir&Tz(`b}Q)Pexs_a8HnFPH9Pwu&4ybLrEXx`TnmxyE|jd z6k=yBcYMaqFZQno7{sH}VwyRLtfuHz2qdt2Ov27rRSf9*2i$ZiBPOYN)X7&)VXSH) z8G=B4xBw31`$!nSwo4}6D-5W0sB;|XbV+%3Eh*7q-bs1Uuq-;0`%4d++7{1rfH78vp%7i$oolW0zM^+fdnGd;GeuD=_wCg< zOi{Ff6h+g?#DJg3*0=t||Lu0uG;uRsJn4~RRTvz2JE9xcU1mb>gd>Pk^;*5qHBbd@waigF#C zImSA+B|p!0w=Qs6aeQ5%5zU^XyUSHZYqtwU1ilRPQmKn#Joo3lQg{3P>oKlFO2#5V z?1CHczhvvyPQF>;Ig*BX#0(;(dL)O(G&{B2m`w@5x?v(z$U` zdQDBlniD;zcsEH%NJQ{Tsd<;3de8Ufr1S$tul!fd@9#*_N#7mF===OyI^tz0hj8bw zUp76b^f=_*`+^R}%C9L}qjiNw@7jl0g^&w$jFq20adLBWryqSHV&OZYxy`(&@#6tu z(Wq~Q&L{9aq1Ud-xfw*feX!d#&!(1JU9Kv9xzO-?xsJ|Y9*e+Bm*^fndeqt79ddVv z?S>sY3>+5m4SPhQ5L0(*++T#I$)MQ-)?gwisjvQB)yB2pd zEp4-aihqQ4)#WusTkBp8ek7&S|>y%;me<1C;=Q+S}VN6%@E<)bdH6WGb8a&Hu=vly9hPPTYTK!NcuO>zeKl zv0?_rwS9P`(6BI3Y3fgVDSxrYP|nBMjMEP?VC1L zOGYN8-HwT2Og+5Z)z#I+#DuqKx8d@wtHaKferRl5{qUjD*ddowryd@>keqo}B|sU= zzghR5%<>i7+pfRu@b2HvBB02-FgsC&xX3&4nl-YyDaV|D&6+j1hf0a^`6L7L#l^*z zB6qQa@ye0h+f8rn8oKXXb_EY?-H@`crzwlazA^nmP!RpQ2fH~J=BBiBElS-opJ;}2 zdoD~gr*^MXIIppHFVm4nCKrCy#`HgB@!Nro-CO!fK(+LR|AM@)pI<@c`h;1w9Kneh z(+b$mO|Fs)dzf}Wnfv-9O8)7(<`e(uW3%FeDX+F&&rOG`^%T-bEX#@6=4?09dw zajw8>=4FbCio=U@L&6FQ#~jL*bBa{_^Uv~U&z|*sN@H7`>0Te(JoZo2W)doVGN&nA z{rQU*i2+NC&;1vQWDcD=B_eY00TUY=+m_YLGG|)YDJ4 z)8C$Dk9YKB8fEF_S}0+m6AaQ0nl34w?`vFs;GWFO41=_fIpzu`rlv`Vc#{|BQfqv7 z@7{f9rz0ONEv=QaGn<2hgWEt0$Jw)I`Np^u%{VzZ>71RN@r`EBT@v58QbX;f;Wvb} zla6GY>TOx=;_9m2QRY|h^@Z=ux#`(iwM4y&wzhTOzkm0f9=5*Gf9`wbG7>gNjvOIJ z^>md<)i@R$N@%b8fJ3r1K?R_Rc>okLj?5K?Mb}XB-{tpV%In zpJ=w^8%t-4ZYy$MfylWO8M*Sog9nm!4I6)UcgGZEAB6|5WC8Hv*In>90j!F4p--d`+D z(7C(6IX7ARnm}GbLG{N(_0*l$*6d(7_Uz1_D3JpxQ=gFL_B)>NQjUoaSbQ=5f`x_U z6%N$X+gVQG!NJS!$=F?de_yWu>3fnQmaX7U*mH>?^y<~m_u7j+oP#c3K8|xby)e}w z`|!)xug5EcmQQ0n&d!e8#rE+loZp7{cxWJzpes`KHd^e)?c104MTyW*TGs?t8WF#HJlq4?CewfCT5a;j}?l4&OVklQiSiP zq2xXOY%49C8tPzEom;CqAvB5zU9PXMPqrTWBIVMlnv$9-q@ci$s^W6~{AFy4*44Ec z6H1IdlWQcsFODbqO#P|+{Q1ZO1&^FYFPc!11NWG;wY8;Of9py)w<~_{?cKU<`*vB2 zfT=&``dLS|BhZ9SeR!}H2UiHkOqdF-Q=ZekC!wNZ={D4EZgTV}${f>U`zBGTQ}1}K z?d?TpCkM0ir}}ft#i`I{3!ei>y}IK=9hNeVUkxetPicoF9=CaUc_kq&(gu1?G#OXt z+tg~fxjpS^NDXhvw+UxgV@f@|waBe^!%6A8o@4Lj{(b<*Vi|>}N-S7+Z>OUu4*ILs z7p~R#H@LL4G~K-TnaQ&=cZWwtI9Bk8uU_vrenS$4BUZuVv!|b)-gOrb51tPnJ{*5{ zN9y=LH#a4zhp^HHP9ua;W)2$|1mC}ZKQtm@wb+qI>|@<^JS+Kku0D0@RM)$^I~shK zFJDd@NG^Ya|p?t7&DG@aCU?>P>l&Yoz?=Js;z6*Qf61p;0~4 zQC9kDA*ucLtoNa|QXgZaQv-_Kxpd<8^zZx5ujD#>g>x*+#gT=#Q=ygt3r41=kRF1s zT)A@kOMa^1`L0*XagnwnBT*l$TyRE42CuCBEs}@G5y$y0`25VI&?y!$qANAVV%7c_ zajvo7?>Q|jEGl2V+_Q1x#=T>~moGCTH-7K$7egX=6~-m@Dv*Ybp2A&@t|~M>cP>Bu zNcO$c9}_N^*#++KA<>i$$O zMI|N8)2GwNeX(k^fxFIj1+lA5ERIc0@f0{Tb2sOhNBuS^munFpj!jGRtRPF+!l zlsQn-lbqU$D&M}?_% z;y~W#2E5wt7Z~OSv-GntHDDi>i9s*W7T>kJJ7R_J__*s^7>!`$@TT=+A`Z(*DE-wr+dqh|SCT@eev38Rs( z4!KvZUuWmw=NG%Yl3#=hO;6tv`K)htjpTWjK<|8?DJR5pu$efI-g@$K!wY8jIzI@>u^cwEG;BxjX2k!as-Pvm?v9Ymx_wB2{Q|?0f4tMUk z5umq1XWu@K-@kv8RJs9qP}CBMhY~DXoOQ@{*AIA{*<9V!WW>TNnb0ENIKB{fnDP0= z3&u=MD*WfqpYKA=;89DT^oit?eTAYDgrx(_QezUrGi?MsO;LFk!n$r1^~$5eFYR#& z5}5rh+mk1m7#SG}kd2%H9uylG9F%>luCBg}B8fZF>%N?`IN*g&s|Eh+Gn1X>%wS;$ zJtgJTx+~kRZ>pGm6Jv#f#~&u3CjCMu^BZ^Wq(6>GDm$H>oh^IY=w4;*UR~YQ=U$k- zi&Hvwq6|51Im%Szxrs9IE%NfFXdw_1D>HOUV>cg)dnBtuSvxu9jJ#0xnS4YgaNG<( z{JGACJP&YR>L}{z(f)XjfPjGSzkiDeDEn@S&bVZ5M@g7Sb>@yrq>Oww+S;oz^qVI&uI>Q~RF9Vd~x6x2s6jr8HDk1K-rvik*#ZY#an8 zU4_Kf^{1`43zdC?q@*&<2Kvhkr74I!lv> zD$LgruYQ?@1BW6gDCl%a8RC|2?%B3@niH?pE4)XM%(_}0pCEwoL!46h%viVZu3fyc z4xhJ;KDdqpvO!Q#)!U-@yyN)bH=g42gKGZ%%0cWc&(8{bPyJabM2~ygtaS0xCDeS8 zb@n*WN_=uo5n7RacJI>4>~;P2+RRN3Qh``cyQiBrY*0&cZ^hrPUAImO=?iNB-r^JYdAS4pXvq2!$ivz9MktiL^Ti6cNL{VU?(>iCE=^tsH<~A*H2Cqg=a2L--51uR0}PJ==RBWOP<~M!Vybh<2ef|1tC>|}}zU?0?MXdu6*!p-ob^XQ-8j3H#gW2HF{zHc(&dpAb z{Ls%fl|@yGHeFBQ zngq1U^4T4zBK3LJRjUq}m7o2=(Aw5kuo$}2snz73g&v@gY+TmTb1zTN)kiIMoq17Q z><}A~V=;8GJM)owG53M{JA;9)(JInx-n{wDw`VKu?CebY_0kT;9&bK$AW_e%y~GR0 zkI~G`Y`AiTgw^8w%yXZq9GPq0<|~{nv5bw`$BZ40p-b2=W`azS-4b~8j&g^=rrwsv z!f3dHUte4Q137`TO(@A9A06F6x&w+p>PU%TJllrt+gBpvo4TubkMI3a%0m4m8JrO# zrh^9YF~*-AxmT|aqM>6D6cuH@di840w?c^{xfa=H#q06l-~ar%+Sim7Q**t zN=gc94jth4sTa3t(mzBO<7R7;pS!LFjAs_2?`zJ@Em#n@C`o_3aP#I($>Xn>z-ySx z2S{((!bCk)=6U$=VY*S)ksI#Zi!5|S<<7OEFSeOolV{27*AIvbn_b&8DtB-}ZvQ&^ z@WZBiw>c!x879^Prlq;k@JLuh?6CcifWt=mx*YT3hX(8H0Tj7G4_qS1P`<+;X3S>) zsLWjXw%YBz#d|Ugb%yTd`!YnBH_074w8mz&`TuYUb zsdgXIb(o231JBp|Q)j=-M@t6`*9Cx_6Tl+?2RzD)(%W>6z zI~pgt4~6gg{rll3USIu=Jv{ueADha$PCf`ARY+FWNSG3h*4d??@S}LBOzhmU3kGt5h4`kw{ZWzp9H1a(ez1iVHRhnW|j7uvRsg`6*-lN>45V_p+O9qW-_ zs=BJf!%NatjnN}&qMMU_yK2>{u(d5F8HOa|0DfvZ@lSaF>hAtg&0|Sw+sI4C^$GgP zT6xc&)!+n@-Lz9l-@2MP(qiD^+qtss{oVOVD(m|K4lm7*9U8}KzVTYbe^FZ=YoDE; z9+@6^Qpe846$}FFaKBMV&6*vjZt?Otx0hV${gjq$S?+IA=DV9u);?%>*k#~rK~|%D zBLe6e04WUx!fV+Jv#Ve)l2M+4^*04}`4on)2;(ZSd^^{c&~F>aONl+0Rd?_HurBhP z`yuT;#yMseqNAh7ZB9ElgwN0W_R<|&3#Q?Lk`FglW&6m-TVTL$>7+JBr9CVYeJs=7 z-oDF!eiu@!Y|-x(&5u2XEKZ(0d3rv^x3^)FU6FEIncp#oydvV z6+9x9q}LBeSq#O99NJxOJ?!m1LrPS|3W<_HiLz;0)XJ#1EH59Q6KMZVqm#HobF58a zaA4rk)S$twosM4(c{e*P1+-|v9_w^AJ2mM6B?w2tb3=hbsm!Fg@W5S|F)`Gv0X`MF=rgnEedVpPqF z3riWQOPw7%(%7vUQ+{@xyc?l7$(QQJ$``yDPADrXNU=6%W+>`ftQXye%#Tij(0AuH zE~gq|{cmqON(;IR@QNS7UCpL4A82gpXO!m6d|%#Ov~0R-h3|O1c0=^HzPKh-NBgI# z!yMuHp0_=+>L+%nD$+la16`!K_&Qm6C}&tG6xXnO(0y*~_ksEOvAUl2QiY%AcHsR_%G{3o|;mKiy|2R!VHeu*%o>ONI-&*yxq z?k%#ClI%-!9ZT15-Abvao1Pvyfj^-~6e4*?S?ur}wgQp#18rHoDZ0}*!$U4Ek|@-Y zwjUmBsCzHgQj_+Vo2ttyFIS=V&N){E(y*(o2BVWx%D+BfUJBGk5c(&p>M*X<56+H` z*#+;jjIu6cIqVd}_@nXxKd;yR!Y(z~C$rN6P)P(Psc@==+RC3UEmMg>n}Y7(HE@nB ztI*JwC))k1A0&bAAbjU@-x=wL2V*m3{Q#0oo}5|<#8?0D!2MM*TpS!Ufa;`ePkWZ7 z{sZOJ>}O{`U~dg*)QbQhI@)gFfg%F~DGe%q8 zfw=S%omrnG=OTZGP^Ccc9Y97WZEU{(im}v6){49y6?F;ZR@dwG0YNb_F>Y6*O+jn1 zuU#7fWVt6%Z|@}+?)m(?3LfHJU0olG+#MqLWSNzfl?fsw3@#vF7YIViu$ylIO}b}y ztOq*}PsrrpH(?NhG2-Txhg24VkR}psYHyQexGtog2a*C!Ya)KyQs^B2q5B5QdgZmq zr0OS6Zd{!H!A5A!yLa!l6njXJCoJ=uOG12s3fY0R3VZcRL&o7V3wq8PEJ_4eqwF!Z z_}j(B3Lx=9$Zvs7fLw&Te*74j>5kuDdaKlXq7th*JX$M}Y+Dz%ckkW`&}rX){J4ai z9i7#VRFnW3i5Ec*)MRCE9|lk)ynFZ2S?5;Jiv$9Jp11Js-GqjM5wv2>=&xFkqUmQ} zhA8)pDg7E8T#3zkWcFee+HItDEj&%?m@r^y=nL2G%Jy~vC=Zlj>3NitSKzG+YI0XF zGgqSIMfUWZe)alwGI~JC9XqO;vWy@5FL-aWDB-1JWDSaqT}PO1;H5;ufP>`v{_|&0 zO3Fq8c_1`MjIO_)Z;B**Tf*{cjHUk?ME#pLZz^~!eQ6XF6hL~=1=_#M$KP9nta|P} zAxa(s5SM@%!fDO4*MhoNH8tg{tg5nha5&cG&&I@5finB}bp3|s#l^`0Lk-LHiiVMt zA02%nY4djVMiG%D6dCZLnrdpaJDuAj3fsL`AZ*kSP=LabfD+$9Hs(EfQdJYlA3s}? zou3|BXXEB3<2^ZW1%+4;l@#RTYtT6$hq69Nqa7q5grK%v=LdL^e<<`8Yn6R@JN)Oi zqw{%Wz@Cqc3vldS#!Ejv^l=1R%&rl1S*z;z$i~f^9p0@_4GIYf z2eo{pG1t-(ePexz*VqP$8;1@a6s?PiD;!D@-@ zO_@fV;H5W+it6Be>>E>pVidtIcd#*CU)|)`v2g54I1)gg3`+!irZp1|gD5F91-8JB zU9%JY4T@j@2!~wR)@F_`yMmvEgL6L3607f`u-dTI(`Z@9K|KSua+lGc`|6)L9wUSb z=rlr%%2;F>idI903rb5%dzy`|MpR8*UG_5DmYhEqKQ&e*fyg>U9uYn0a%c~PbHPGy zCkjw@vp90UjD6!?@`yY?1XeT((@f$Xxh%7uQJKES@;{+O=zvva(Hlt4<-` zHB5UhE1mg$pEkJ0dRxy}oeB>gz7owA(mylE{SgQ-;pk!=-r~=A z1;|ICHP0PWBk8sT*-t+ZQoqaulEUuYyQHsP04O797nl%yGzpDD)?vq*Q3t~ivP|TW z9UZp=R&B&yR^t$-dWoAo7X%s+IdkSrP;zoIVMt|y_P_KqZ^+xI>32E&tB7X(>+byY z@?-pRPOEVxZqP~7)6=0q8@=*-}NZ2*6#?&XjzzlF4Zb}&Gx`hVGcxghq7aBwToHmsM&kX^ zMyHOlNZ{kuUi~uaEoFXKwL8{5r`UTV3NH#L6Vj{q$SHdeuTpvr=_N#?0VcA>sgm!w z`kozGl~r5&wP;(hESj{E*}g0&X_uYCZX+s%(bfS@H26JOX$N>28X0NBlp=bG=6Zw{ z>PztWYMWE1>|2YUY}gvD15vl4va;)Lqw$*5hYxA>+TK`L#{E)$#N7BzT|5T=@E7gY zFr@Khy3@0?fC}D&e&tbi_V>=tKoq|&G#F6G>OzWLzSCOx49cQkT?y#8<@{ZeL{s)f zK_F-3=jR96BD8TMJt|yN#sRDW^!1lu{}{p6As-F2zTl*Wd(+~RPA%pB63;@bb z*v>HsF^R^x7A@rgDyGlQEXVnoo|&-*F+>F-)?e1uu|b4lLS-SqrBz_Zsds^B8mPZX zSXbl{poh!?L=tH67f|zXo<1T;&LaWv)#}Bsa_Ov~i4aiYL%)qK_qL25fOx}P#plo5 z2ZD(Al!rY&Sd%L}DZ&id)ehgs_fT;k$Rbx({}7 z2nYz^dBKhdDKCs0tQN?~+BRpvv&r#V(gzwvuhET2IUwmtGJq_>h+LWaSvaTyRZtIt z77$z_Iw;d`TptH_JVAdz&%i)SK_uJicw$0m3jCGz$Amr5lXm_~PL{N;r2lIH$Z42N zHnkhN!Xd0BxN|2rC38?pDDzzl-CiwWPzvA=K5cPzbEBsQ+KPFEgoKE4hoHRxn0%tQ zAr;Mw5`b4WhcsnHu5Vec{QKSAmVu;R0o_WX zpsjpilAk2(2uPUVBn}^gjvArtH*3}NF%d%2OVUt)t+57t0n$#Zk!D@59DxnA29hB9 z=gm#~C9Nu`jhi+lq6|=hSb#(z7ngJADsjo{K>6rEtE#ItvknlK1p1zESU`@0fg~Ma zQgZUykuJ?M?IlM~v;%K_FKD)?A{YoYcpcHmL48I>iy0HufspkyRDFFt0cGNrWh|Ug zNlS8r9px%OxnwO_)=1MUd5;G|nWQ?=p{pS#tZi*W(6FzEt6 zlzh-)&?BH;y?SK@EhX>q7AeR_B}Mg_O^?w;%lJdx@(0VNmIGsvRrp!oBR z^^V@PYke*S_4Eop`#rm`ojfZI1t3F5J+dqp01@Xo)#d?4VdebD>-8o@Zd-{-0l%`y z%zC=O)H4}J6!^1qla2#lo-iV59`M?!QvYOgXq+pUEN&{yH+^PqZiTI_?Fh&X9UEj2 zE?_C*P&xeNukc8UYiytY=+7%}>gt-e?BBbWC?n`jo-{VovE#GsF6Y#G{Vge=a1zu!3;Qe3zzLF}Ux$PS zWeIVy&n7M|4)Txpc)H;;hh}jaRoEfy8w(KCG^($vtD~PE0M!CL5d}VS6kILwtejn# zbU zjW#LL>uL!jG5Aal)O%7D|E7+SEr?mEVIHTk8U;KQ=-**`f2>D)ea69HHKB=9gkVAn z2*!bc(Ih!AeJhdAa3`Wjfgb@!i~lC?pL-0&jiY@&-Bu)v z7L!VUR{Y|{?#ZE!Ym96Hw_apxenHU&C4qZM`+EaSLVtZlqYaa`UaQ*$H1*>>Uby!k z`T6^IU&+9~6$sSurd=|85cy?um6dlaQ{hKDiEk1>ATkOCx!t=UKBwP2MXzu4O169s0A!%FtNQzw$sA}_cdu?L zz!#HKJ2EoD*WJ$L{zw01LMrqP+1_voSy?VHC0baDg5M4x;I){_z;Z*FBYvOA8F2O} z?}CnXU473A3mGZTzf53l6lkwV|2IYC1nLeo^OJ{IA4XA9*mvbPO!2 zXk-a5;|8A*?ybrpxAaI?bYC=1Iw0CqF#cJq;|%!Oea7kn#*Yde;yLI`AJR7>d@KHz%rxd`vsEo}58K zNTMWLojP?HpZYO3RNj2A{CV8Ek=2E?%@Z4^y83cLcSdV|AIxlDPtwzkJs%p!%T;0^ zCH1rw%RM{uLpO`J$3E8|gJW&$I+0`qz~&&WfEM z{2C0S&^EK@?Bz>~#cs;KKY4zw(}luDM5Na8fc5KrhiQQ1=>h6Veiqh>_-LYKH}`lO zdBDp<7Si5*SvuevAIT1)M|E*?+cw26#J}^5D)`-zCSyyxTPjc(i>OpZ2o?k*fo9#G z+-(C#!Y|V}NHV}ysRGw7GCT7eI&=vAHi%54zC_xclPd9r@1%< z4^~jSFL5TMAPi-g`MuS)-Zc0+zhtv#lZ271BIET4=z;v?%g+y*lG_$l30PD-Khz#6 zpyYka=L`CWEaOv%qUSgVFJdw*a&$#L?NYpb=Z?vrV@VL@=ouLaTfbLF=jK}pi;__6 zq20Tzb^(x@e7_*8&{ElA*W(EvjpzB%9Ut(Sw-U6=8f>JJyjzc6-}fRozles2P}7X- zcqkAcDJHh!P@H1@o!{VGjvYG|sXp@g^Jl)Hw3~$Nn3f`SeRCB-MSThf+pywVLa?@hr6&`wY+fMEDxRtmJ?y% zYb4X)+}zw6>HD${m!TK>qLRa*Cv@@R#bJq=KVpFrRS8@|>Kg&b zkbwyB$$#<$4wL!Amd*e~Tw+J8TJo$<*C#C_P7F}5LR+^kNB^ykw&n4eFVbc&&Mm{v zRKpz!N{kN8Fc8`r5bT6+O8vEro}N&jcVr#7p;$56+IAnW+tiO!iF=3u&9VUv7rZZ3 z*uoJs@sKOkeq3Zz|39))#jBR|&jB!^%(Jgs7im%Iod_0gm+Nnq^8+o3O`JLXwl&|r z@w2kB5-tZKHQMe-&`HU_H-v@4-?{XE-cF(dY1&jN@?RSjXdggV0aFUNOBSf3BmRP! zZY*vSQuRBM1>Pn-O%$8_(@*o~0a^fRS}AJK-@1 zKLm{toM8SN8-SoN7+&<#4z9C?6_J?EZf!Mq1r+$Sj{xn1{YI_B;=$1}9l+0;E-rb1 zmK?BRCIMjcsefeBpPhpP_#n>H3LhUI!rGv86SeFW?m3uU?f-?FiTu?Hn1e_(AhZgV z`e!I2f<+1d8WN=VyLaz2aDJ;VE?XgU`2a`KnYkxYmV_zmPo^z|g%|P+vCz5W za(4FiA-a7U8itxoLPTfx@bG{w)z*@i&T99onwkv&StxnLvzvHd9e@4H1xg5Xq}q?~ zC7Ifn|J(`|?&ZsuG;+@E+a|Qe@Cn1+DQRg{RaJCs>y?ARMkU@q!9GCa%iLF022ajk zPrgxvRD7Au1IDtywte3Jn{8i_G4JAXA<`%TDyho_iweCkW5s$UE3*ZMhQ=u|R50HH zB@d5{pqN-%V#*$-3lAQw zO?mimgOCsn6lS@vH2bcE_Ix=`JrcxI>WM}V4-W@I$HTKm-%3s0guQox8|Po#MCHc= zWNx71&t>KsfpwxQJA^ef#vhH`5Bc|W!OeCEIcL7)FQcyCxkEg^)6<@@za_%4|3cU- zGe({>?2uK*Iy+paW%(CVp`8gIHjQw=S(qh`<2t1@U{GPa-z~p3MumX?K?qfX$ zz7?{e;SP$9=0Xt-f!)8qb?1f+qUKKGE@L7t1H5_uO6;6;y7$nm($0^DCmx&f?Goy= z-OE(LenRcoQJNywJ)V$RNh^y(^tx7}JOYQ4aPw+Rk4zrZ-nen&4x|_8oY!Ifg_Z4A z(Yt|xGvxDFQzCPsqkZ~&2DpfLo(W@6R#s-ix7rK0i{wU2AOJ$-1mL1)Z)%JSXfv?W z>rp`WsH#%R)17oAjiMIt?mWYblv0nY*zHDZUQML&>`!PuC<=DOYA^^ydGKiWB0PwE zwj2jXM%k28+hL`}8SM$ZrJO~tshmEA{4EoGG=8&+-*)oTF;v)Y5nGY>*lTh^*_+WrS_?#<`Q-a1eXxV14s(5Vcoa^zX4dmWUQTyX**Od!V%4b z%Y(~&+b0J$xDNnEdS~DylmxPg^djRi$N>U? zJvKI5R@FmQRrSW;>90>S#)}c^l;EaK%iwht|1`_aVZ^1g>H5vXZs}sv#W~sqj~-EM z*Ot`GUk0Wv_Wq=IF=@07p&4G2pMQ9wW=)cXIZzql08nwOQLu@Z7|JsjkbszR8_0(W zxG6}{O9T$F@pc4wlf8TcnsNQTZU7YYX}jF}R+Elh=Kj)d- z4Lcxz%k<9dgYt{&{bXhWsA7|NIR2U;JwXUFgdg`tWsU)F%KBMKZ`P?Eqit73MOZ|?3+ChRB-Nr1Hpve%wG z*#Q{x*tPp0nNt8YS{)~0qKDZ75*tJfh0jC-hxP`#LGr}leMqDd7Y8w=fE$Ckj1Sa) z5E=^9$IQb)da;LMZqc_sPn1KT7Fqy&p{dyn3gCC)_D#>Dgd-pA)OLO5pYw;)2A|R zax5JB%WB^nO*C-v4BxyNxU~L8mPX&$V3yngUpPIa&ieDT~ain zxd}Wl^3qA|^Un{y6gxZht#JSPxexDG4v!vQR+K~=$0}^VVYG%N@E1Eje|SraN#vgJ zE1~JfQ_~!#+PUWM#+r}zJDv$Fa=#$&E)(!MJB!(W?Z-P2%K>m8)d?#qniWMn0Iskg z73tJSsb^|z$mW(IzK%yXSc`YA8++SU%06BFPWDZ_Ar?t}i6-KV4 z)BgIE!CLRs!RkA?1}O`KMqqJqW}&zwJFooeJG(ijN3;c%Ew~nS4_sha8Q5NWVP6y+ zR1~WK{mm#Nj}N>2*P0Zv-jV0xRpe!2qB4zbr-d__Tj-`)fNG=?{3>e~hqjSe=ZS8hFjR60WX;;$=QQqt!gVJg6RD&c zb6k?J?!1dt;6cH@47P+A<6(wlBO-p)<&{#9)R}6oz8i7iI${r-1~ZC^U^)_{9j4c1GI448!ASzVjBA_D{mEcp1gQ z8tf_+Nb)v(1B3@6f*go0cqJX4Zh}7>;?AY0D1*DrUJ%iFF+NIJ0h$x@Co$iYj5q9W zNVGt+7wJlcH((H^1d=2bh{&=A4Zwu?HjEn}y@Nvg`phvL1?YKE(FS>WK1g2C-o*QP z4Z|OTpc^p-b^RHezL$+{7OlDdo}tBsE=ybMM0wp~yMD@^rf!W&2_|*31K^_tlZRcf zzRb@j18oUQwrN2n2-j2!Mq~rKqW=Z*FeJ$P+8?tjVL&?s)9mTS2_k3`?&IeDA8}0%Mng(4l0vNGxj7bQT<&Ept z0}&lDFIJxP4Wj!X`vmCv9^n3j+ZH5fv z4rYt(S;{4kwhd<+PTQN_)qNN0LC=^8T#PsO3M~}9Zz-O}y zvmF+Fci~QKXlTeg`Ohk3DJy^|v}jczb@uz3gTTzgeEImFHp2N}z}57w1pCPNco1?Q zK0!vYfaoe~v{brJ`47KjJpJk6N&v1)aO`s8yGffv^aS|JdQ(|5OM>(wZ=|t$_T_o> z9vvP6f)TfWkIXm24=Q!;=U#%} zU}W&RXLJ*@imO2gRX`;q4t*veVviz&XA-q(Z-r%zp2!Wg?uL39rsC#sf=GoUS{ozF))uG0xKV^#sa*GAQNhud?TRWYO?qN$ z6|RMfDggONi|VA>Z;7t#?lmuaRCGd1zqR!#TifjPaM-a8nMHsJJufx}_1(5v=7Y#E zj!iReRdN~}SX|+?tjZ#iukP6(ZaEUKBgiayDr1xPT_--#Bx`*@q+8SCB0kmSg68R4s zhLsM>2nC{PIQU?C= z)2ns(wR><{2;ur5HrCq4W>cHoZ6>{mc^exWAv9eGP?$=0z^Zb0+^w^5>wAb@a!?lB-u}YIXv-XA1CV*HH||dKd5}hJT(lF&{BuP_@!<$!RdQx+`>yh$)DxbYlq1{ z=4EE%N-q364TBXYsygCBT&{$Q($ZNiyZO&admI%eqenI|d3))3kh3ncK<9u|^mTx2kxIim~OWMqpo9tC+Ej&*X;(G$704 znyWR(B%Nw+moSQR+z^tYR_SL1Q8#bm0|#Rd$JQF(DP0KIb7-M++FL^-dIjK~-M)jL z1^hS38u=*i-`|w@?P96VL|;Zthwz4^x8XF`-@H-sP50Au(x(%;+a-EWKzw)Mqp}b5goV@GXMm)5E~v>L<=SfF;+{3D&!AQ{bOo@aQb; zFueBTwUKcj_mRS!-(Ei3O{r(k>dHz1)d}KO(mv;E)ZJfQok81iL-?!luc8-rlLG~3 zmN%wb-B_zC6jyhyxFutn(%W* zq3jjGE0)$ZD7jFc!>X=ve6oQDV;5KWt>l*;#``ry7*vyVbeTH87A&#$)>P934{bYb z%SgX0!+Wa8O}|YcrYet}Lw_HlSoCg6%2H*!b2-h@eDdzLhE+W+BjxHv+f7}zaDxNl z_jhDp)6!OaPsz7A*WsX?9OKt#3q#kPvW{d*qsbUOPHptASzIu7{}VT>SQgGBn^yZP z^Lm^*wq zw*9=)giu@5W}~Wt)j#{^I)vJIEC9~rbdOyLeX|Q6Qc4{-)3k19V~AV8lKC9w5&D-r z_7)m!uBfgSJb?Kz+6ro~;VCb#uO8n#=S^G%*w_*rjE#EwTaQkle@M?qq8ANjuZRzT zl^z@M@{+37<==|p;`cnhr5}sAB*Dp{{|j#{F{Bp?++iCy(QkCEQvHcxZjM)Bq*f#^ zxz#>gVm4q?u=4)erAmt!an(-`OTICn`!Qz;JlPmTb^W*y?=LDpJ~6PIg)e2+&e1XN z6l`X_Xg=1gbMHA;ZoxIrI|~A|1s#LFRS$HASvERBr9$S*WfT3#CyVz_*)1RMpC9}8BGpB)w_AG@&=ACvyq7i1YP-G9jHhw1rJZ>e$c9MP|O=sF2yhoV7fA80I> zz^w*Ll3(`5*E3dt(h`Q#6~B{pGw4~$7%I(DPRn)aS+RU(XgCM{uCIigHd^CH4K!wO zLi2XUOIMWKdko?~85{N(OpX8j9;H|vKep?F_a@p?acnKMk&b97H^vnu1&XiDa#hZm+)b(r()I3-UqRgp(iHtZ9q zfDwv#sX^)Wbd;BW9*5l>@0hvq9}_Kj9dz$MV0Okd4g;FrIY?B8`U~K-x?EiB6P!zD zC))C<&|k^r*V}+ktC`=s&hkzY)>bQ(H4sDy>|9&V&n9VxOG5W2gF#f@xnDZOyA02k ztjM7_77CNO0o(^tSKZ>CZS4N{1M^4AQ@3HNWdvPY37sTG8biHq{hwFD_L6m79_G#) zv9a5gpseOz_m1N!bfyzCrd3%qaqHoiVd`nSpNQkrb2KZTW*80+5I`Z};o({@!oydH zn-`^worC^&87&1~C&P)VUkN-9E9|!o-H}(XY8e_f8WeovonMfX3{cMVmc1U8EGou3 z>pej`Fu?Ln3ncf6BQ|siWuRJ(yS>tM?_R{qFM7Saz2%|lh$bC1Y6xDT>LxQ>zC<%K zlbJs`2;5*a@vrAHVl~=H$;->DiN_Fcd9osu&YYYauES|yu+Rvc8Q`h7UzBCW3HZ9p|c5WDF59UNSTtyr@9q^l8!_T!Cjn2)G9> zi3X#WDFJGff(NbZZz_Z>>n%_puV2(=y0Ws%j<_O6bk1SM3iKdEnrd*JnDIzVOeB*F z1aLxqI1aiFlXl`nH3q$vy+VC_`@ahF8{_z%Q}nlVnylX8(zYMc-@bc);fC;qsSd`z z&$4Ic@RWN!q=kYc-GnnU$H(2s=pzhq=j(d8Sb;~w<&%ZqF*mv!6_r`&Jbs$>ml}$VA`%o;u`pNBkXmtbQ)UNEMHQXrkWy!)oMDI`#GIa) z3hMOFKkduVA)1t#HO()>rg3;j(sepIxPp}e>s};l8%_1Ll`WL#EBgg* zH3;14$kHs1IF(+@P|vR>AV4LpU+%)(Vh%fr6DQ&VAO_WGR%@~sJhQlYQ zN0s?cF1YsxdW{A4HyhcUKduq8As)$?4JdWA5#{rA_>wYiH zyLOJ8FuHr~n*H!^V+$JH7gOXIt>qOGO>}5B8MftQA6nmZ#~*jB zfg)zI9Pa>N4xrdqr!f1s6^)#C#LrXKvjj$e{P|C2xZ*=yny-a&ZVtFyk5?5w4j;*x zHv66=kePmH3Cuwr=J3d%-B8IGD;T2*{q5vNqc2(H z&^mp4ww=793X|*=DM9>A?eN49BLY&Ui0+-?r%ilob8-J0GQFo4-ea?vJ5+IpMr`Hf z@h^=kAh;omzea@;EfOUkYq-!(XQiP*UpCt(Mr983U=9{kbp>Qo%hEro0KW42gWEgw1OByLc{wChB+qc&D*yZF%a+JPCjI) z^>Egr6P^tzkW6@c6M3f?XeTNVtUhrX%;sDrOZ#^35RD7E&C?Aj%bhS_33Du_q9_WE zG?cGLL;qU;h+V9m2A#W*MgA_zgd1xooU{pJCD@c#Py)vPyVkUwcniwM=Vwp6i&t5X z(c8v*aZvW)<@*6IESWSOh5@rL*_14!C}ZgZI!{=i=Rpw?Q|Ck7yR;y3o( z#}M;4z)Z?0ChNX~i);MPPI<3qbb%5z4TOW?IDRrx*xKC8)0}Jh-_7(MqR~BYAQ;Ez zh}Wr8548k|9=)OJqYni>aTChBh>~$g8DV4L-)Z{qg;nT@-iEO6gusdSLXcVBvv?C0 zdFvbc_K*Ml;1JEg$3!|zl#x++&`8AP2sb(zR>J!-#?9CLJxd(U%cfR)imf3l7J>xr z!eoM%sx5=<2l6}LFE}l;(?$QTE~7VFAkd8(4mYN{Ln~v$;n&AOn$5ZSH|$i0Xe4ox zSMteJV8C-324GkhNO&3k)1yS;MF}0`O%bT$X+xUEeE-tiZJb4L6Gr>I%bA~}+7sfX zjOSPebbudtIP#jD#QT3QaSDq?LW+ZrFATDCGT1YWo_)I04kgXc7?2c4C}E279B7dO zD@%_Y^zmLzxGK3XmP11!fk0v5#If!1r}e_&j7Cq%dGhdU;&3iuw+kn4OM?TvBb?Yc zHYi~W2H@I;w{yJIg#4s|voxNr1(V{s;8NfMy&NAO|5;Oz5MUnBe%NOLS(D0BmtSzCBJ2IX zybSU$M}p~1khn6$OoIG|IT#=2l4zFyKYxfZ1s;<~@M1=1 zCY*S9V0*ZP_c)bh{S6Q4k8?&9L=P$~lp~oQ{^=huK*469hEPNj-St1QAW(s^0`h7A zZ5RmSwPIX=0+$j@W+su9L)dB6 zn8=_D8J#6s_Wyhf^&E65h~8wREI8%^@xlwDiIV~Jk*@0hDNx;%{H|S{Fcj9nMYblC60K5-_L&k|v}lte zH7!C@lp>^3(=ukXXpvA_)pQkU5vFA>5|aD+Xzncc+&TBo|D6AwGiPRw$!~d{@ALV7 zmiPPh-DSQ89b3sFSw~4}Ue+xA}gMIFJ;KVWn8Io-!DA$o6o;-)24Me{KllxmJ`3tZ*Jzcty|%aXdPNWJ<1MO z^6SQC#SrBkw#NxiF;v*0VEN}hv4us6L_`)9Hin)gDTMyFaCeNc_=(M|=J3nJ{In(Q zS$V6;AR%XjFdyvtT|;oz81bsA(KXyUJf$g^g(G(+8TB2bA1(@TpjTpoSU#r8l@$q1 z)Qh71F-i~dUSX{vFdn*9wxrLHe{NB2lskvrQ&&?D%cxNJs1+5->t|Oa3DW>fCuObQ z&X{>5;J<8Xhe(1t_nX;&(z}28@+CG2p=jk~)Z51#`onE~hcP+XRYd5fu8Fe`$EgRUQHC3;U^sgfo zfP?!HUu^^P0O`*o%ELK-%&)+cc{3@;tkVn8WZc|6>}A2(%^25&x_UiT@^)LdaF0fX zn9ksV7}R;}I`&YD_IVR}6PHFzK0dQ8E~X#>)+qAoJZF!{LNn;&t0-vtKhC4i5XMl_ z6QvLeh)Id%(`U?ZlC-&U>qNG4}vM=9d0@Eu^AkuKYZw+eMdz> z0s@O|%dTC?qoQ~1QbUz@`i{sWE7EQ_wk{;;h%2x}IVPl66f}Uxnl}Vs^w$Aeb1pNL zLjH=eUz^5CbF2P^6<8Q$I{NF2D2C7FGIOKiUN={8U9)R*d9^wkj@wgyjLGGn=~l>1 z-anjl3Gp}}~A$zyM@$PbSLiSWmOt-VQpNg5~?duDzMINU}ThCQd*k9vG>nTG@|LSdVq-1CP5VlY$1`qF9 zwFhpeRB7*C1=er-vVI|cEepI)Iv)}QHmIJ3_=pR^En2&{v_s_m6INbqP8~_1O=*5e+sCv<(I>y}T(jm8}6yrbVVGeP}GJpC>%w~v-f1A=1 zad=Se1B|v^dHwuGFQ=HnTByr@&8ID!EJJH6v*tF|vZO?8fhAZK5ThuRNUdv)ZB6)_YPJ^MO!tt6jOndK{giBAFQD^pWbXWmX|d-BT% zA!JcybB>00{H0v2T&BJ!Dyj>Lzt~(m$u71;m(=Neg$_06YqQpvSZh4|;?jKtxt*YY ztJZvFsY=WjbLWask-{siL?AUY{F_}e^7f#=Hz*h_Iz~3+a?nO`w3z8{1Hd?Qb5? zawT7m&H4H#^bu^xM$RN9^c&D%;CAy4=-T}H#fuUYvBSFj!1y?XPU*~zO*0#=MCMm- z>keJ^oPzKAM3zTjo&WMrqa~PB*v?b=>T$j7<8G};*^L|i>&yR^OrE`JQ6td~Cppbq z)X2oX+b|h4ls>95Tl#@`uKq95>Hqe1CHeg~xO7oawba(u#-^)@Jc+-&b=zCFurZ5G zD!RI#UrOq}BJi8$4LJ4ZqV#HL;vfk7T?YLJFD@_lr&;WV!3etK$uc&+etkHXLPy^; zs*QE$@7lV#(NJc-4E#?tdp2ew!}dG(YTnP5dMy#E{l9%KNr(S5V7@_7e;&3q__%dn zs&e&4MO|6j=KS@rge0tgfDAUH{6lTr1*bU^Uo5voM!i}B1X}OC=EhWVYwGY)=;P%8#lxVSJ zb>fg0V=_SP(!@%6gYeOeYviqwI?s|`)oF&kX8t5{HlpE0Rm;?2Khq-g;@)eUG zU8Z5BqA(1XEdmQJ!=(a78r4zB!i(OrH`7+b{F&aiD=ACLr=!?%)}MpBlQyWhjg*xx z(vxT|eIRPVh}2C4^L=z1J7csRQ4V}Wm=M@hQD7MOF6ZM_{PZu#L#p}l3e6`?*ddvFyf=ZJ~ z5qBxEZRXkQ@5yR*4zIgp>xhXopYo4y{Ytiu$i{Tk>>=p;lA_IM&d=xO9=TUdt|LTqv9z+D>Z-c1{i-;h51@?E{4o7WH4xT-e0d2DUYjZcR@esHenuQL*sCCycC z2g@L4@L-SP>VF+A?eQj;r8!WoqrD`{;)y}|-VP37L(hB?`=j2ogX_IJ?&@P^Io5R9 z(~^!)qP+)f%YKsb*{OBmQ5wltT`gMT2Mdef&(~_(bP#QWHA=GNhU_={QLs`QKgD#L*wJ$joCK*8e@cI`c~Iki&h) zR+>((9DTQMWqIH563;Fb+NSMI!+OMPTnka1dui>rMbAvPecdIXe`uWg?i#fn{z-RC zDrOIg;A{2+7>NCV?XdTx&atlgN9Pp`M#-0v64vWxFaJ+Id7F7HH_s?LJ8xEWY=B)- zk&Tsq-GubAd$*ZprA>K$ur&B>NUt?&x_#S+1?Sryu6EbGn{8ot^+2{oY4wx7sbhNF z>YwTMX8s$)$V{gxI%Xy{FGgy(@*I+gP=^i=h(_pze??A)pfzAmZNb)dOs8h^jMDE_Iw?+NQ2BRriFwXXTK@-eSAkLx~WZ*hdXZg5n- z+Oq||kx>aNc4l8ak###aRDWBv<PVZOEhoA#5TwlUy|dLGiCbJ zc;FCspsXYf9X5PjeIxtylu;U4!@YDTJaW`Jta`W?vtYLYq#=X?4pxdh0V&Qn{e~k3BSWqK(-aB4+ex ziwlwb`!@%k{M#{$v9a^2h%JB6t^T7#;@pBlV`JitYq(G6$OGrHGyfnd7;R&=M}M@o z%%9EXJMw8hA6xqBi)n*fZc=%z=jG+4C=|_V`R!ywKS)=DL1x$Qx-?4HFIoO;N^>z?l4+C}=o9 zMFoG`K(J9=RlD!l&+pUe<>rt}AKJSc8L<6_3@7@2`kLl9IJ*E_kqts=l2OfDL2aa( z5`#AuE$QBq(XX48+!n}zJ!DWkoZ^?DkbZ=eK(idSN)zTf!k~fl(f}0c-MeeTrQB0^ zRYk&la|#{%lb0x;_m|{%TGyXyiy+Lc`P@6dcWxfBf}>vgb*Eg}8t)tEss9JoMY2MHzcGT2WUy zR;U`H+v8r{I2#z)_+(8r_`**`j4YZ2_AR083%WV5uCkNzvZW3B%O(WxATV>YxBJFe zEX9cRt#9$B3MMcq{laSZt!|++s8J7SX@-Nw>W80)>}@zM#Y%ta+t;vkIur%g*T$$! zn7Pcw#ifbj!_cSa+S#>V(}bq)<5=#Vws@4%hQ_<8t7(`6s)dWd-mWb7w88@(%XOWK zAXo?f`bKR_j~3~6)O>@>N+%n7T4RDyzo1*50=x9)|-7e-3i zhO<&eiztBYs7w`Bl-KO%&90Zfpbk_NrWaug_{S_wH$f>t>^nZMpgYhdl|A=+V~w3Z zfByBzh}!){;+>WoPlW{Kc?}PRoR&f-CcjfN%5Td;8nQCT$m_RaaP(=KLDOgy3BN~r zUHEGS99WziQ~W-`iibS+D0Q6>>mM)E40t0<41zx2l`c#x;Qf~%)2KZ#+~-Fj%601w zZ(|j{1|&QRhP(X*)OsPjg*eqL>ng<2-|F76;;yY#Mh7kM_iu`I{UjMl+$>iUQKQ0f z)!~dDZq3%LNs}gRAy*;anw^uo+{Gv7>Q(8+aso{cWYT!S_5%mNpbTjP^I zR)4(q98z@2y2N>gM`lw-1$;=LY_opchCQ*Dp5BJqCtVdX;1w&eHNrK1ef$+t`xSN8&V3`i3 z#n&(yAYRcyHFe(?Gfkc|n%iOwzW|SApmPSv9mn5@djc2zD%3Nw4HL;abJ~gM$-!B4 z{u=rL$0k0h4-RVOdH~QL)t;_4>B~?|oo7%bs6Om`K1?q!d{$#V=Jpw- zhq$`0meZ;>38?}f;k#D3b(P><0-Y~29(*@*5vHAuk4YV`v z2UxNvuqs3y%@CD2%)IB%+O*Z!K(&(f1wwzCvv^4l+gGCbb;zb?LmjrAOZBM<{X)Pb`zK+F`wXB{G@8Z z+BQPeuPWQH-a)KS&T-7q=llEH`T6-BEysvzQ#OAl492vywEe}9HmsOIz+UYpV{BG8 zW-?n3kM2^DG$dpwve-RN>@lfh$SsI4+9W(4#uz}v_`dTY zA6%Ru?0BF$YzZe@%J#bI3*AlZb*e#)gvXTXd!XMW{2P4DNONCZ9ER9%_MX@%!*dLr zKp#x_8Gj3u>1Ts4rxnr6BtFX=9l;d@EAjA)!%+I;DV{b_dGiP-uglBVV5yd)tJwZ} znwox->Hm?=%=IZ|0490Fl@?#{xVez{-@UjrDp0edy{y4=#ie=Ii*M?#tOgLR2u!zIAIf z(>+IT26r7eIBI)z@zbZ`X8GxCeVtH~tgTloJ@{w_SGUpOCo_^x8*qV!V_1+!+)b$E z2aQ(BynuItLC6R|>~S(RQ8))!omlUC7`5N@1$RPmkB8Upu|K^Ckuy2wPNXR$I78~DIopYG-Pwch__T7oOXX5h#mK)WY!qnMu^A`}%|W7?ue^Ep z2&v8U`zH+W&kNO;{dgLyU5+Mrc;5-N3Qe|>OM=NJL6U*Ipl~9m!UG%+(9JEsdQ zHO*Y_zT>xeJH)vZFQkjx0`*M>-|%=m(QnvUVsTkoPKaxY7T~f*il{p=G2M=Ih8|qL z{rC#{`)sZ0Y#&ECE zad9w{Z8_~p^C?@LHD*6CxL|Y=Oqa+bCZ1;EbuVp+DQ#1Mu3O*`MN_M+ z?9QT%Nes+b{0q2+uLcY*>cIUlT+BfePG5we__fo6F6=ZH#)ZymB7t| z48mqN-AP+qSXP3f!OJdK8H+oqtAnnR-7;U2pUE)?A`u~+Hc=Aq8qxFMSqhGc(PqCY zZhIH3!HVzj>1ZeMhcp8VFR#u|J33-bQzK!^dbim z&$K{sSpLI;=Q&Qa{Mnhz>axNG{rbjGZBP7xq8}dp^@iuwI_-m;bEHEWTdesXOO)T& hhkvG1`mA0#c;%u)&BdagoCvB6vm0T1*m}z9e*lyWnvVbg diff --git a/docs/api/python/images/sphx_glr_plot_train_convert_predict_thumb.png b/docs/api/python/images/sphx_glr_plot_train_convert_predict_thumb.png index 6eeb0f2bb9225fafdb5c3b1e5129913306d07723..64204dbac8eb4f1a3b3811f99cb7cd84d17b055f 100644 GIT binary patch literal 23421 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 Qn_6wf5#6zR|6$A3KLlc(3jhEB literal 23337 zcmafbcR1H?`~F)?QyNHQG)bYdGfGIv%*-s=WUqvh2&F=jjEwBahzQxCl9jBiBuZ9B z=I^{epXWKg$M=ul@An)>&vQJyz2C3*ec#u0o!5Du*L_D>@$8n3yEjrOlr86ErBo>t zs{8o2YyCR>#9lYnjY82GKPPqig6q@KZWmX&D;;n9dd$x$x*wu__-WORPl3LB*`&=^ z-P|i})f=E?dpcCH(1zc5@Jeu{1X8rk&;v-Tq%UYi;3+|au#yyoFh z$&1&DF|%UU(QZYGDmznS<#@JBuD4TfQXiC_ANlA@E9qZ&dX+!^=kNo{-dnVBa{Im4 zv)@YIzJX10J$tIu|N7O4F~v?K>Q{GBIKSoRESE9;fWSb#N1s1Nopc*XNz#3_GScrT z5+Uk#oSKF?dFDC;9i825w~NE_;$Mkr4{4QmwY6m?IqKK+b^GoLel^68LqkKygS{4g za!eaETs_)e=!q_lS5S7+)2m*%;8?q~IMaDmbm3PHcf(buFRvXAH76;Re!CnHmvyyA zTq9He!-IWia~Gl%4;8tL9pvOZS2XskJ*Q)|vQld1S9`pehO+Y8XJ`BxOyrb9HlrJng7W zY#M1{!_7%kll44PQwt_t~{B2&N1X8c zJ2hlrFX86q_Ef~FuC+abzN)HdM@KJKhjOa9{v8a*`hT$! zsJ^$SKFa0mIdgMPip1jh>apTk777;e`~1($L)_dn-uuqp8-KSim|{Em?c70y$ERdu z)=_xgjIY|nz?~ktoUWZi-b*{rf-YEWW*1M%++M|`DW1|&yv6a$)tg5JnRe``&~xdY z4xd%)WV94nt=Ta#P}5#ux9{RBtFrFyJw@I3x^1Y*7T&sbi)_b8TV})KW0!e%ZKf># zX;xwub-k~Vp>ym~<@(L*Rx2ijuzD>%C@2up$+!9N?!i8)=>~q&kIYBtH=RCxx}d1Y z;5d)v=X9fmnb9?C*V@(WaiQJ4yKZ@DLA%65czJm_XwS(<-rkh{{(d3%KOC{qM%`Gv zZ-avq1HlqaCD*Ur-pqKj)#6HDxv!LzRMzzc=O+Tzb$eX8ZYU;QURnO<7==E1blkT0 zl!(*FEo@C=oHTjvYqK`Dx3Vglm^`OH<@tAzVP>?`FD8aHUgqxJBS(Txn10N%?UURo zZS?Kk13vSnTP-aY1gyTCDt4d#Qs~5Weg4n0v%xH3U(@{js4wQ*41RfeIrnN$beRwJ zYGnT=&r=M)v6TeiLUGu9I`+L@o@K5em6`Wb$3%hz|??%i@V_x6x4h{K0tnvF%w z&d&bPQz~Kl@u?A>Q0oXic{&A!&6Fg?s7v?>c3$Ql^EpRHzC%jU#zP;Y)~s8XZQUub zZu73UTLin5IUAS+ZH%YBe<*nUnk+q*K~63GDapRH5bS4;lh{{A6y$F^;!aZG%DeUE5mQGCkCnQ`g4?&9m6(f0G$Zm$)2ZiAAi z-9;|V>DniL7yjf9lG#@i%xXGV7xryv$f5bXU}Ksl4_2$}=Gt3+emF`jh0ddL_V&k( zjEsJLdFdl_clR-i7LKC^gV;!|Vt0NV^gln_f|+azsH9cqmKVl0Y}s<9AzEw=HT4Ob zE+K`3JLm&_-KM@jh=~c#%;Yi2dEI0>Gf~4D5*k{$RbtUQICv}8;PSis?2f;?B5+)q zvy9FhKYm>6l@+7QSGPkl@!LXb*La7AGaS{)?QK?)7+jj|Ih)yLxe_IQeLm|_)yA)0 zE7!^5ArWY28=p)3b5~{`qIu{BHA^p!Y0$1?H_x(O4^2qekE1GfZKm?l%PiN4OE_P2zgnEU(JD5w4L zNf+*kiHTizWkf|qDRZ->D<6Jlmfpj+av1tZz7cgVQi0KMQ=*i#^hCv03A5Rig`O3Y zssK9t;H6>ND)IRr`*uqAMVKOR3Z3vq;>f9TUb^0|9fl?|y_NzITLA$9@7}-P&&_?$ zYjJ=T=f`et+=#{f2Rkzjwcl3O?|pu(2M-+Z{qx5WC$M($@6^Q1%y(Y~eZ#S@#XlTH zzPb)<`Rch~{ieA1?|8-5zsQ(WLLPIx(b3U3X_MbVlLpD5DjOY9Y0|Ntnw?Vo`+&U=wRty`BaIZT|RFxMGKrXc_Xw#Q3=3{GZ{3goF$4rlQ5Jxi0@5+OTQU znWSdB-(A8uH6e$TOc0T`Zr^_R@Zrs>OJt+0zP@3MZ}eA8sxaf5{Cx51OZ!2&Cw%6T zl9H?NML11zB6@obZ~FM$xp%MR8&yG9QjBL^evha8g$p~=G&1_}*fqnB+gVwI6_fVu z-+zn2z~ce(3y#;^ubc+*1jiyjxL&(9)gQ<+*?5+$S0}ni^{F`RSi0?7zu+&JQ2jDP3lK{Fr&u{_pQ2e7bEi$9u9mM@iPkso%lM znz{Coy^{Ff{hhC@FE=HeQ-~C}`}XZyc~9rTL${FH$}1{X=d{1CzRRSI;E9dS^}y$n zoHGB%oaOo-73W`HZWI-rY<_-z-@bi5_wUo%VQ^kFM7z06T_C7Jd&Djg<`CITRg>r`*ZFkV6u|7N+Wl z2jm|MSnuA#B#=;0@R-$e?uLG``%7eV`lC8hW@a1|#Cqm^>a^B6O@r%I^*p8T&kJ@Z zbW2>HcOV|FtJRVe5Ag5=|L!h2frO33A}J@g@ubV| zgzF14Kc?N6|2B9vA=m2Unw24HUJpfI+a=*Cx?#fx1WT5A^FaZdF4;i(qvHtC2WMIO zaKhHUH9l^{x4X8!zQXu;WAQZ?l!lGTi8-;cZ2H$m`6<6k7HohrWc+CMtlzqIsEWa$ zvb#Gf{%o-Qc<<>^r$Iz6Rv`(gj+7i!#g077nnI_auA_Nv>o;%Sf9%);;22a)=H2`j zl~^~k)>JxncJ{@^sfMS*4!03{NF;ae+}VHV&HG6V z(LH1je7E*DZutDCM$;p$bTl>xLpFre-oiWf*^W2K^BD2&nnP$KkDg9y?)&}wUZYt8 zzKpA@tL;#fi~i(nO50CPF0OyJ7+byX;K6nAjqf6_megJj7OMv66LOo}|N8aoU!D2E z(?8oB2JQ-8;@$O_*XX9khyLHcKLVZo_?*FHV`GzkG5=ntO;LuVj!U-_1HLg1atKlMQ{=W-3rqa)g?&m3*?JI%jjvE$?n#RrS`11p|RTDTtY+ESqkTSJs`?rOVSi2%x->^^_<@Km6y_*unEp#*r)Hnump4$JvnXpW_4~ zGVFmX`}_J%>*zdrq>1&wI=Fs&aMlcu*&sH{j5sQ5ZVrjGDZB%Sk#nV<9`FW`2uGA8 z^ahEQ_gFpWS`UM?5nT!ufi_DEvqLztqAQD2{2GNK;s7O+~MY&wOlI>g3CQI@|TEiKIva1%vy%Wggj+upsa{3=eP$XqR+rpKWm zM-1o=C75#fP0yrze|Glqbz4~!5O%@h^BgQJEN^ByEEAHFnhWeMAI(hB4&c}CQ z!2!74e1T`kQDg%R&F4vG7M6Qem)OO`qPn_tHPW@HlD(EMUM;2zth!mz_tqkBmBlB) z2n7O=JIWT@47{ogd1)CL&*5W`pgd6KfbcF|zKjlJOX>1Fm$tSxSs^?s;?k@=`@q_@ zYXOkWPrq$$R+CTD&D1YOb7O*}`(@Nw-?eWoupOS`g`H&-@TK+-&R!kgd2E9pq@0xNpDh& z5kC*SOPP+Pr=v?u>>CpgLZ3AcEALz@C@6^ISDBVsA_wTl z6)I^Zz=Wz{3RH(iGr!!l7#$Ztomtz9J@^zO)Q>Q6gQVu#(fpo|I1*)kte&!$E?x2+ z8w$qpL$lR!d9V~OxYIlgxMs$`6UnPsWBSMM--^b@`%Q8f(Yxg53nnHe0s=e?3#%ef z@`FjddYVSAb>}P9`L;q4hEsK3%!ovUsKd{U{7IC&XB-><{{6du|Nc)%P#Jwi_#o8u z$xmmtHaE9t-M%=V_UawU0hs5bQ${k*rUJ5 zT`hytmy(h~`U)TFtrmCP0^-ar{$D zyZmP6 z>FVwVHj6_te)IQxBwf?pz`%XSk3R$^DJowY9OVjM*jzWY*z2=(lKcabpTfTrSL$|x z8aQiX^TOG7dBAiCFa&72a$&4g>C`Do@wM3(fBuGgnV?Jrv54))DaZaGgEx9cB5qCp z{Ai@>2$`Ik(k^m73iu|Bm^ZBp<<#McpY)kxZ7%FuK;#>bcH}JrZK9pCMNTp+{<=K3 zpt{o+C;^aG_Wbz+LPC$x4PO{J{~ad)N#!rV!RygioxBkWBsBv#JU<`#e2F_%JQ|ZXD6cO_nq-@3Za28l#qx2->i9D|Jf~LEax*Qq+*vNlVk^{xgGaSz-{tjpRg> zpKqwOR~F|cTGBLw(JHOJ9}-dl1|e_egTyjD%9?vIOHsG}v-2aD27CGvmxBZ1KB1es zx96lrpP+Uti;-py&K?%6Momd9F)G8lBlixtf@f_%N!=j$<40q>ReQEC)^X?6t5;b( z=Zu~!M#+V9>v0@DO!i0g@3#N7~?{>ecODVLmbyMlh!>$OwIW!-n z-ubWu1)uo_8imZSJoG? z?AWgk#vkbDwDWED3{>CUcldAsO4bRdkqf`yOeubTp;tdQF>uG1F3AGB?ssaRyldw3Io z;XI!q@Ed25CceCJ%W)n*iZVCO0{$p(?6Xb2<_IG_E$u1bI}-cAz&e+gSZ4=qg*c8L ztwK3IcDZ`|%jICZiYccu*9+u`g-7Fv{5vE@l96&S}a!D$w9-K4LFMAsdiPBPDqrL zq^EBVtSbNX>xbIZWO=z)S5Sa3ZN0?`KgfIs=z8q1%;rQL>eGv zgoIIkC)%uLnp_G>V?Uw-{f_1IG6l?IFNm1Axw%g%YKH(UY(=67jfjf0jfqKKQIRI< zq|1xY@VPlx8WvGm7lI0*ynFY~5SbnYVLL6YcT&=!^N|8q&_m!9?)LKX0x5#G zs;sQ+brfkYxqcEEp6}|{rwIF17Nv_gV^}Ms!|H~HV9=2L0|R-h`#@)qQm!nf89fA) zj#A)%=T3_9(;oaidZxV`9RA1?J9h0#R^K{5Ki`yTAYpHBk5d}sEK>@!2&OGVJr4wH zmfe8N#*G`1*b{*2&~&R@xKN3d2XL8y6(`gQK6Lwz9eHCeI06Vzi-lFwR$d5RG{lX` zD*J5SOvs!Pn>vyyhlZ3u!^*0vzQI9hDXCjC-L7tKq}jpQ$D3iJZW21DsQV*60jmrkorc zYzGhC#sQFDeqk*TIl~ek7nj@6-e-%T(CEm&N*JZs8MA<(p#1^@k5Gd9fBsAhJB*h8 zEDi}NrAzbEmDSZ2>J`9_Bjp!e@@_fJlL zVaf%B8=cYi96#jPR~@rOZc`>K*M1%IT$*mP=n+&-OgXXqUcA1@a-|VL z{1&IWvFoCGe3>r>c|h(mYKyeMb4v?+~qMsTY;#` zwP+0(AGbv&L2GgVbO}Nqcrn?awB%Lh`}Ycn!rOp<*zs^H9ue#)c6a}Q1C7X(fXK)` zz}6y;KTaW41jNxYFq}0sWJ9anl4(#{Ugm*_LDIGoxad19j=((!z#$^?1XL&0NP9lG zWDvFcd3o=D`J#1?MNH1!U8GIVMbB4&9ghmK@LfYgCU2GLaZppu~;{xUI(y+z*|UB zjqaUcj~->?3D8Xe6-CS}Jr%$H1dv{>)bl!egfjrXfebv~@fEP8pOAOuR!>*vomnNj z2ag&AG9Ay1<39;*kksDYf;P}vj7GUiOU`>tnY@6thkR}8PUIl^= z0L3$>v?H_l-6erYTUN%4Su!%rF*h8hTkj_A|Hd zM?}=(u$zPQ0J(WjfUR-Z(W2}UDA-)9_J@REC;A6Y;l~(>1^^@l@Itd)4qK7((9fY& zuLDUU1dNXAq9m~tiq`olU;%;OPXw(#S8 zUJYox>cCrq6$M2!@$ux?gd#!kq@W;{zb=w>|abgF!7X&K-V`xYYf+ePAarH*R zw;O5UY-(!Kf|3MM#;Ut8Y_L8&zU?QJ4-<%R$e-jpAajFnOv39y+WG)%PF6ErC5^AD z>UOL!E132DTwH;G>4v=@vCP zPtTI3M0tiQh`)e1jyiy@7hPT}O99*ME;IJ1v?F1jYBrz;GjNuBJxTFQyXK$r6RI4DtRm7R&2nfi6;bTT;t;@(VsJShk6 zhc5ENbHpGAzV3yO(P9_by^!(cV#Ke9LhCzl;)I%c+lwf|ljH9PaVReU+NYv|b0B9# z5z>wPd??0C1GM9FASDiv4|QmRU%ZbxsR__>H57vAVH&?PonByUn!xgbMa*n6okGlT zT&@lx-v}5XlZU!Qxo9r?}1W@q~;WbCw%AJrdu`18bZb3z`qON z4>IsaNRf%Txfirw+b7!BAI;~$Ge!trjXqAg=o50#RaE!SUpA+dTL_8M@1jb)@?4QH)0VF;L zb7o&BoW0S({yRGkP5v$#BT5I6)Na%4(dlzaQi?GFprJVa z`tkrmL&nIjcGH+vxd5mwLd-PQiploSta@`A#4D@>LLNRWcWTq~Yc%^tM6r~lXd;dJ zvAFx=$!!t+-y32YuyasVlRTH^JH#yqa#@@nthq1J-*2%QYl^DC!OdL_oeZ@WMJe~y zgUR~9D3lT?0=FOs1we3^0*#`V{Y(qmoVpCrHleV1ER5zu&gF$j;Y9gGY~US6wPY2HbHGg!f|zHR#6j&K;@eWcW~_UNTnCsgxNTdn%H544j~= zySs(juaZ`QTs_hr-uUi~+mx(=!nZI@{l0FOp23$jEX@ZuFUEU& zdvDya#pKEr^PEj96W13r7Y#;Et|~w{GotMQA^&YSDdss8$_`y?(2`6MG$T)yffkAU zdTquE;FC}X!qBY2G1>aMeLfXsVT`mWI#Ia;u@g>22hffb(#FFr5TDT{=<-_^!jIcz z?V-FKcPFbolbYSy7XvK=fvOZ=^SXSlGW7t#P0$L-OArtI(0K)++yC>h;pk9b-wiY$ zOafM)o-dcQtP*A@{o2{dgqZl8uI&Rc94*OaW+CNkU#lGWQKbRKBndlk?D9GYg9FH7 ziRc(f?*xu3+GFw@&P$!w@)WD}jfBb9VRf?(uZ1h>grgLX27>}cKQr#NGV4Vc1+2jY z91ZI8%+N;5A$>>iTheFfK(`Jy;1t=+j5^3Q3AZj{=T@)N>+B=z^aoVg|VRjAM&1P9$Yz zDO<*fpb8@^fcYcDJP{O$HUe@8UJyhR=*JyMCNhM;a-V)EaNqK=<3Pq>on~`UK_OJX zW0s$f0OV9ayNNh{CE%5K6``$dZEX{mQ0XV|F;K6iw6z&=0OJJCey)-U+V$+i4tjd} zYOc&TR*7G~apS63r06b>sSo&))=h7|eKU@B`_71EUiB7PN(mhB zm*Q)JDCH7Ji4;Sq$~trxzz*!~FH_^mh9uFdNp>!zI7`x<+Cb;(@+CXle;;42|{qL;$c$$)qVE{ZoO^%VW{=?ube z0-1UnD{Di^^@YO;-OtZ6nKVS7hkzLnHxA%-Ss>E9CHcXOI2CAgU2}6IL@r@kkO0g& za#Lo+Pe=Xs#0NuwQO?vCLrk0j+P(T_;`V2z)Gp}RwGgu3qaZQz8d8)*C)OMcxwB!% zL2@n$(g7)#%ijgt&qpv7THpskpOZz?%FqB|RRt{jS|S zKSo)O0XY|P|9-4`#PR^^3L7AM7?-And}n}VNRSi*oKO22VU5xi-hS#9t>lF}YiQYT z(WP@p2gDew5ts2TrgcF3#(&|{e~EKO!U@4IHn5MxV#$k)3s;_~CUu-j z*Rb@Z(t=~_fF76S#G<8!Iomo+x%5&?R!Ir0t;Lk! z9f^iv$4mL0DVmuq5VQYj4CyqIR?FJi9fOaeoR76XvlhBZL4g(=UQWtUBBRR#tHf;o zYM;-{O;0}pOow{eu{nuB!Wo-WU-B8c{F5g-`&w-^>xT~ADwrIRqM%cOJaHe#Q}4LH z?iMuW=aiHV2@6MnkGrsb9T;&aCLv(hA;4=6=MC=Is&BDnBl|7eFcB4B^{;mYIXP3R ztG!U!$03W}M+bN`ze^H4L3Fn=XHfJ&og!ZIOa;3V9kV z?bay88U)?zzS~S@$QyS(WF&P*e>uND#YGDdP5vb87Pc8tghCyj@%`Mn z8x?*l`Xc9_oKkq7$a)Q>3Md=$!6P67@x}2oi%UyjF`i{*-3PM(9iS3u#LmItGIBT6 zy~n`P*^o5=0_#zkm1JetqkBhCsml?)5+`9h3(JcP$vNaeEQ=Bt%e>)ND-*$9;}H0p zU?wA3mf(%%;RF(rgqH*2%`-_zr}ets3Z;TBe`=`jJ)`V-_59GC@9I`X(fo1exAmB& z)72`-R!rSNmC)s7xlgNeK66u&x`5IJ6XsD}j{4c{bw0Vz6DAEaW=c%fx9q{(oDYNm*&hE+o zWyMdc`zGonwY0Rd>Z-)Vk;JN1(b2RlFKkp)K4mbqWNs}hqurIPudg-#{9~#b)wfc{ z6YG8#42+Fd%o&J(AZTUBAw^>50%%#2>=O{=<@%takL~#J?Gh3aGrzm#5r=s-=!!Ky z&@nRBg5gJ9K}!x^4&F6jBo>eH)1bW3M1$F!0?9uC%^~FR<9BGi!7!4olP&TPvk9r) zZ_U~Nq|Y&xdNG%epEe;e<$zx$l!V_3NoLVvHj%dPEVWNZu4vxl-!d^mYg0F+QhG>`@H^K)*3qu+jM34}@#MTHM z*BeD#RaMmtj2}#(mTlaVlappx69mswSao1mXo3R_?iMq+L;gcvKzReV3Bslf?CPys zYhY9i4i0XJaW~MMJh3xRUgbd{9et`bO-joBr|C9HN@@A>@~sveerJkXezrE9j+ZID zx^0_9*u&CN9gFd4b)R>w=mp$hqLK+_(QDTJ8-F-MmV;`I@Z8d#NyY&Amz}M*%>&mq zHGA)d)*hF^%!VvSyr zl8)zGw?!s*h3`x@hsXyzkdDQOr z&x>qMVOd=H;=swTK02eLzgAr}&e`(lSanCiu|GeatqYp8fLS5o58Gjql63W0dx&Ed zawGJ%Lok&fYO{Z5E^X%)h_(D?bFi0I^5 z_?8*=BJlZ8v?EjUA@2gSqNKvegf_B&Y%I9l>L5RV7@REN$WZ#8qJ??)PWI-_o30S< z?ckE?DzHPtLW_>CqVH36(tjieU?QCNA3w}aMa=+MM#F3e^NmhL%%$!G4hzk;F5Nu6 zy__5Fv8d-K?9W?cl%Ff{1D8LG zzdv~5tIgMNk6(!6Hxt!Nz^fsVk@e^iU4K0DD;RuqQ3ysEFb&_32>OBe62ZTJ`}Pf# z*9Y<6(Ja&NymmrCge_EgE4unxux1@jWsgZsvo|strUI1N7i~8ai$co;wPjSBPV!X;3j~+%3 z#~nOJd2Oithwaj#N)0=qEwQJr$IORcFGxtZg=0v;(IaaKNP?ElY)d;j6bP^I_CS6> zjeuhTE=$xaB15)YRrlEvsBN8F0NnWK8$`v`Eu4K!d}b8yf9()oMrY)jLqi*4t_VcJ z)|foLJMx1J9vc?z4yk*CYVQIih8EqNPF|zGx5sDBbvoPQ18>N=(e9nJvFrRguY&bx zX}VQfTIgm_sLUmGH-ut;I$4wBnf^2GPA^zHK=`o0ze3b&9Ji^Ml|^dhniQCv(U#@r z?)*7QW?DD;VJSDMSE6a4>v!T=&*FHQzP9G9|T-#4HN;*k5;M4)N z4;j=7S~&6e2yI*>p-ElI#Fn$aRy0^>EpN{|SkS8Ov_?p>riaty^zus`YTv z8NZg%Z|Cv~IVB8^sz}MCo{m#u^}l!f_7<<0w_{2lnfFzyORsuIM|eE|9-yNkSdf$8 z6oI9DmBk(7mShzW;IRDeLURLv5X2;S@8-=_#10Huvi8G=E9gMc=kU7!F|!tKuMIgw zSZ&Zo5oo)ycd$S!MLxU^zY9`NDERdUAd_)M3zp}9!em=*C2+#|mln*>&z?OC+ReYw z8(PAuRjd310xsbQ-uM zU9?gN>d4wduaO^qf-X*REv+D<%*CXzu$0xm>pD5mVG8Z-?A9CYYspS5oYzIV)@*-% zzBQGTT}s+%uQ!AisDCx+ccGraZoB%BtZm zp-M|nuMz*(R;1NXg@xDom$%q8HXfy@qFO7BqUx_+r6SkQR@@%Re%_?WUfH8|=-!jT zW_wa$B`HWEhd_VfP(>KO+=%0VbEoMjDHC~ql>XYxkzZdk)&9Dtd+QoCVV}W#ggeXPMWqlPR?q6=)7|CU^?kvAPn^Lw{Nb9KG zyDuBrp}o zm)B~e+gjhe)>%8<;00PR#b?6U{~m1{%LcZ%4rAlDcXni5Kbfu_FW?;Bz}K0qvZH-z!9mhKMbHPQN&E8aJ{Z4xy-0w_9ah z3Dl{Z8)R@gJoU=jsP~l9>($wj*Drz~FHT;=3GHCC$0RMrr!eobL%fYm~W#=a%5N~%m&qx=e zT51^^*x+d)zGqSe(UP<}I_q*v80e)=*RUE@ZR9t*<(C#;x-g?IzdM`zHf?#>i$V%O zco10Bwl>X+Ca==dgOItBM@rh* z^jM}ogQP##VCqITAgVXu;*VT>738(_(|`=TfLZ#-c>7YzA0iz5Edyv^thx%eRrsp? zx@hy-7n#oJg|83YFK4HNos-=8DJh?x-__yg_YjggTVHug(*KE_`dV7Fq5FbGiG>^e zI%RQ4V&xgiXcw41GAc%j2~tLLp_3(ok%C}Hxh8f$i`Su(Lk6Qq=$(p#uGAaWZqM6f zgh8be79)%NAcW%tf<`x$Gp^3JTNcDIFQ7lr4GUl1ZFY{#DRwEDEI^| z7>B-o{R(T9$|iacG$x1iy+t%G*9$vsMi+KEt;Zo7aQ%8T(Z~qBj9Zf&q69qY_|VUNkHk zT+mwIbDcWIGxc8UF8+<;f2FF;*R#K{(Nw3X>|6^w3?_R}PmwfrURl+`k9`LP5`8S( z^`j3nok|s=pi#1+YofqmyHnaudwC@_Xfrr~#g`(Ums>cT?i<9*@JF2>=l4Y_1p*MU z{18h+ZEYKgZ+AYch}yd?cW#)xPa{eH`C^*v79VN-IkWRW)n^H=pe^w_y+#OG!A z9Q_(g_5R7)ireRUX(d}|+N$6Bm)2V3O@0vU$uh3puE5RWl*EyBEnmbW-atagW0&~c zsXd!r$BMU$-lEMr8^v)0#1W|4)9&tt@>O*owi+O(RlFP^m9tm<{3d>uUauP*hl3L~V_Ylyr)N#!)S{vNP*d@>}j~ z_lJue;0SI7@BwML!4J3d%X%yxOGrpAP7z;F(3k@~sfWUfpa5bRpPE{zSBpqUN=sWT zo{bhUZH;m%KeIJu$DWPsQhFMPR>{6D-7Ojr*h;tTJgPdBTsS7~EzPG=Wv1gqn93=DiXM!|O_G2Cdm(%pgK8NPC!Y(0KiDIg9e0$F%J(S%HZ8U6=vn!?`gWptKvjaom#v zQEy;POujU{&@0*{Xu}K|9(`6#Ypq6X+fUNl9y#)hCs+p0YiG_qR^5qd4$RULEe}=? zkPDCy21bl|YKI*^|M#KSpcw_Zvmbs|7__yEyg=w+4dC$f2chxb?><_+K*m|n2mHt5 z1hs@&+~YB9KJZ)~p_0PJ8DWJWgAvvc37L!z0TmNdaFmGCKdyp?h6eR>29F#E=p_9| z2AX6XF&4CrhWQ_n13zmjj0==5~6*2S66olWFHLRA6skn1$fAav0we_cgW!oq}f1pA*T`v6pjSl zsB~J%^$ZSwW&eOnge>zO@{6s5!x@#GznqKGLg@b4>#b~9ut79f-vPFviQf+ouYsju zWW*T!eZk}U)v_3xA}R+y7QF_1dzi^d{?A`)CNO-4A%-~NFuH>|qKA(kyB>I$QEABA z@}FfF^(IS%A%OKc?F!1uv~Y6OR8&-8BjM#EzBg(@g4YsKtDi|n0qMST^R6hG=mMj=i&Y!#_@2x7|Kef#vHejU)x_`Lg^=6ZIEc&_ZdMpjnouO9D=UArBj+QuDD zO$%c%;h^Da4aA7#l`B_>V*+AtW9zw1VBgvC5D3_po=ff+mkNlB<=6;8?uDWTjA4O@ zG`RlketkJcxLFCW5{>Iu@;hI{O^!0|tloqjdqD{Yuoo1BP6?J2)|kzhvP=#<8S%kH z^8nW^NLpU7EA6$m1+-eTzMX$eI8N?uDGrdiF}X-X?+jgqOvLBC0OD z+Ev4jlhCxtRGH?%f8NQ~oI)5-6kIZrh*>1iH&9JafY@-nlKt<)tRqYM38Xj*f6x+g zica-lw`=BeM%ybaM{qR7o%;PP@^m5~`6H+s-F-HoPGDHXOo~ zG{|YasN8C(Uf@d~gopcmFe$n;jO=LreUg%G@&U%ZFK@vm9NT>tXL_VHZD_=ptMTWw zs_%hYw5{(3sVa?++hGva4nCPe5l-xf<|n!cg$eMnmodWv4H_}*3jHzjhxF2vr@3BysyTJ!nM35g5dULLoD9NP=Xb-|nu18--{cuHPd}-(eVR*wG%& zE&c1$>Y9h}_T^Q&ET_OurB0VO4LcGaIk@lt{^qlPG~DcHv5C0{1P9VJ?3NW60;oq* zs~3iF_2;U*a)6+mTH|s<-rnE8Uz|^MopAd1V6MFntc5xRDTEq>Uu+N=ywCX2*vS*>QOI;HL|KSqwP?5C}sv#E8R1 zvVz^(0zPjtSd2rCO+1U~ODd;`i`r4jIJ?)mW9rCg(XWm?`J!Ts0K+=)8KC51#sf5ex&QpSNYB&jQYKMS>rc?tzPzwa_-}b^8|>a|DetabV(xqdTZ0PV2-rJ%--h)+_|b!u)iVsQpdt&0%b!Z6+yQid z7tiWbN){*O&5aRB7X8^27?rBw>IEle0{a8JA5<_FLotW1Y0xX`L7O43*#UZ}1ke&F z2#F$NCjVOFe$06md@F$g6t*_+4wiV1x*iWxz0fAoet3w??OJ`| zg+Vm;)h@)TR|6gA4KkJvYd$g^e1=eBbe)g*bDdl8Lj_|ESGr=4>ae^t=7n~l=RP15 z%q?$$rgWpM)`D^K-NcY>)qY&zU^CtMi>Ogt;o+wsvDJH1t(L|87ski8F*7STJHJW` z$#`qV*Hr4|g%C*CC=V!b2gwbtF%qBT8^Vk75<`pN<_D2yKMgysS+k~hXy{NY^l+8) z$W-`^G+qnh_7b)h7Qfp75=A1~_#WKfCl99+8W)9%1fS+1CvAW?m}n6^cLz`7!I%)5 zSkB{c>L3U(nua_={He;y_tQc?Lkgqk(TB!tiOI8WI(brVPv9?*!yxXG!DtK+0a2g| zW|~omwhQ_nc&t|U->2Js3W*DnHM^+jQ`qt>e#W)!9KJ#7L`~w|9}-J{cAyxQ_1W?| zd{-dXs6=$F?7s}RLEJpD7y0%$R8L^id;~A?gRro{x^LX|eYUokoxv!;^3a7zoSJ3k za1A5Qfbv5z9+G5QB*%0snXM-`W-y-k9-v{$86XM4A052rk@E=VQQh6AhzkRpv^RP~ z5s}?sUAt{+>g(&nYBetL?H?LzEWZT>uvw* z>%dEnaFDGbIzOD*q~C|oI(43r z#_l*-n^dK!jsFz*;D4PXd;jkr{=a_(w(p(jKZ{KK6*?KP{Rke>&R!Ezd*Q#I@$_Nj ze_K%zfyfNVet-p%=uiO=F;;=bgg=T7o6Y~vqMn!le3?#B`{x0s|NmF~{6B90`G5S% z;yeYT<(ST2oz(nqvnTTGbGmE+ASMxCF_w$b+p!RLU?K5zJWlCvaGd~uk%CUj`N!Q5>K$3;)t$`QLEL;jehTqA^G;x4K z+U^CxgwehAnEQ_7fV9JcazMo7_3J^nz*u~E6jPzCZ;Nm$I)*|1K*J$MJcwewwn7xG zT(fP6p-Z5R7a>j%>lqo!=Tv)cMuj8^`+YUM)z$b&nA0li>o-ySDuB_baCt&`x#Whu zlDcQmyGS>3A9dc8IHT&6lXCG+#+tN>0R5zzSV6;2jF1L)ImsXz)Th`w-lI`q z>(ovO!^6Ru))^m&VZs(yzY=PSK}Tn06ZV%yFa z`j52aIbMb-Tkur<&RuQziHUb4XxFsNsNvS$3r{-|={>kNo?P!t`eYYSN|)EZg;74J)xt^TMU~gUg{MMvhiIy9G`sapmRpBPJT*^sF>9+I z%X~BxCNZ?v>&^APk1NY_gDeX?nOt6_&VKIRM|-RkndpnwrZoqAFiM+yT=AU6drzr^ ziJexK@XG9zmEuKTHrt77nxQKbj2vNOMRTv5m$r}1mhQ=-lRll$w=u6#3zOH@OJ3^(21|%H(o&xt86z0z?} zzy7(Ut+ss)&z81@2L3LxHMi3`%p8>a!KP{?SEFPluBP6=(jhf+hWd@rmc;(Vis4UR zy?k@3SM1$Vd@lLc2Q~!pOfiq1D6Dj`>ysN?Sgx5`ZgYrIoHkVVd}R5Fsl_Mu>#at^ zN_^)=!xox*GR5xQ34-b+Z^n0Tji-hj{rJzpuFVYkYRjTN8{!qk&a@3X{%~^t^P@GD zF^Z;mdA4(~mEV1d)#fL6VMg;(N==XmzX6><2sO*?o~v!ssWBb>2upltIxY>`UAtuA zw8n^!Ap|zmSz;!FF+k@am8YukvVqq%Np`$(WRd{++dVuME1{!}l8?Mrx zS0{gsP_-DGo))|4*p}AT9b_|d-91ES z*5i(corz$uy z=#|b*1_#S`7Zu3qs*|R1;zxY2M&Sx%`lZf=J^U6s0o%SfeJbsPwsLD5s zM|l#XRn)!`UqAo+qvP|mQF+2!#q)b|l+o^>$9KO6R84F$eRQxmrToT1|NPfUpFgZy zJ34MGmQUsREK5^+jmA2$XNpA8h|x8$)&C5wkMXh_=x4neZm=?NLv6jvf*ziv^_TO4 zfqO|(ZHSA_b!x0uUwTn_`)pOQ(4Vj(noVeg)eo)mkK-W2HX0f;;rdB!!y9HdxTw59 z+uz}=epku`Lk`s#q#!rB91KbMpXx+B(Qu%{zP+r=p{vOcWh(mcnVRa_GVk z79Cclnp}c{`69=zhNJ)Nvu&9lk@h*gXPZH%k|F$qcpSw==kBg9@atjU>57=)zr-vO z=oRjd?P0(PvKZmie&c!!mw7EU8@Qjh6=KGuBgUONbzG|LkD=h}>N2ArfFDG^wWqcR zmx{=qJ6C3t4xvj&^xMMl2CbT!w%i2Ib3Ho zt0b&P7n2MQz*Y?K%xmB=A${JoY7nY#H42$5I#x>&F79bK3Di_oC-ajAUw0%XBoO`+ zN2K`4$AEgVxn3WlLC`&VRB&5;SRqf5FV4Ucc|<1u<>#2P8#)_PG7ba>hAG|F>f{Wt zuWdbL8DBWbx^y*RjXj;c5Hq=;4MVLh^FANZun@l#${~P5xEyF0=o5kQts20MWT4Y| z)M90?JXqU!m_PCoO-;jS`2K-qvUHEIk6cNL)8&OagWtbrgGk53h+FRsYV>a?KHji} z8|CRRf&j&kKY!GR(hPKbWE2W++$MO2VGa&bOd5b+m&gh*YeLcXDJr^l-gNpZc3}^g z4qS!c2mHJp25Br0CX@FGcG<25a!4CKqLKFIjVQUV=sx=y^itdE!+A`hfIxm);W^sx z%-@Mu!^SL?)J$g9i2D}bmD~=7&I)&X#XZk)tva{i+hJu4V%Hj9!iYKytE`oH{GC44PxO;L44xzEVj|of-R;db2i9j zm(@L5pa_bV#8O*4pE5kdb_AzS&gY6S?~K-@@Tc?UJ=KAIoJ_$ z6Pk9ZrxZ+HMQ?wsfO=!X0QJ2uT5adCSI365)8Z1Np2Xxxm^3i1Q+IuNy>q5bpt zaG4PzJC1{N=XsWABL%F9H5_z4hBulp0`TOcNgiQKh=UZ9wit2T0MQs)0U>#yZ6v{@ zMNXs(h)!_Y>o;uZ!^tE!tmIj?>6~!2N0fqeB6n7}&-}Urmmda@k?9(tS6CM3M{M4| zlQg2o?}I+94Evup(&^y`lM3ACx!@@;FOM^t>Ci1K-MybmO7{e4QSB_l8v=^Ppe0~G zDUn;y$u`~)10~hTBp4{2+~9=~pBN;bjmcu!pq1IEq+8^+pQ_{^fYVyxG4Bn+T_`6t zfHB`MCZ@;a0{1-`V*ndS9v0ur0XvToTV%v|fecJA6Js_Wo7~%X^e$$tVB*W@4hR1U z10t|e8sCAlU>7m&)6}G&Wk`kPx_m3@R4Yjkl=W6Eetq~D&%d_yusCE)l(9Mdn0yX+b|Q2Nl{Z28-mfU91g^@J6!d+t^#sD;Mu|qv<#UGH6qyYtRX(W6QmVw4$p`kdv z&=oLy7|NjUN>!}ifUVbld1)<9Q5@1CTI*YcW5HL$gwz@Ie_Gfl;(7c(g`C|>(@_}5 z1#3hEz1WbAUqxyW;AJElq&)M&s=XuWeO*jhcWolV%HXp9=#Il|?A)1+l zE5y`Fv5EuhwE#MV1M@}J>AR29h&NOUwqd;=N7+3n=r`#66iFaabOJ;$qUZmJ@GYHD z$BI9pH`UjSL^dKGJTg?jiC5gNzKTIFrOTXBKcz!X0ID{k*VMYHS9VPMlpkZtKn6`C z!*;3YL!e4Iibam-7byfNaCBy&S@Sk8VtjWwn?-!$Oz@f%F7Gsxx*z8TM#x?k6 zbehFKllPdrfQ)yB+(y+u+n&wY)fQ(nfY=K|lU~@jQ{!u+Z?BIe^y;J~D~XQEvllP~ z=t#EsvfU7Lh2?jsL!Msd!7EAxEN&TTepfq_0@Z%h<`c%- za%s@-I_EAd-XI3f;vXyPIeDA37BmSOU^rpr%kmlTusu1L8sK`{2$uaiKm7Uq^DeF* z7@L#l8YJncuMpG9J{-$i_8iaoy~c7iuipY~D9b;#bM9~utplK$vK*;NH@WGMmJFKc z3U76HPY~Af64)F|izW#ny;du3V|#AyS-2AbNI~x45Ck7%V=hAfo}77PV}QVAaRvj2 zXMBq9w7ovLN|X>uD^kSKBe}z#L?dMzPj4qoc6%sv(C6C<8JHn%n*+mrbHfMV`SyZ` z=%_-V*5Tll_&%_1M~Ta|B-6AavdyUT_xcZ - Python Bindings for ONNX Runtime — ONNX Runtime 1.11.0 documentation + Python Bindings for ONNX Runtime — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -38,13 +39,13 @@
          -

          Python Bindings for ONNX Runtime

          +

          Python Bindings for ONNX Runtime

          ONNX Runtime is a performance-focused scoring engine for Open Neural Network Exchange (ONNX) models. For more information on ONNX Runtime, please see aka.ms/onnxruntime or the Github project.

          @@ -72,7 +73,7 @@

          ONNX Runtime

          Navigation

          @@ -93,7 +94,7 @@

          Quick search

          - + @@ -110,7 +111,7 @@

          Quick search

          ©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 | diff --git a/docs/api/python/modules/index.html b/docs/api/python/modules/index.html index 95672aba918e6..ddac275fbf785 100644 --- a/docs/api/python/modules/index.html +++ b/docs/api/python/modules/index.html @@ -5,7 +5,7 @@ - Overview: module code — ONNX Runtime 1.11.0 documentation + Overview: module code — ONNX Runtime 1.13.0 documentation @@ -16,6 +16,7 @@ + @@ -38,7 +39,6 @@

          All modules for which code is available

          @@ -62,7 +62,7 @@

          ONNX Runtime

          Navigation

          @@ -82,7 +82,7 @@

          Quick search

          - + @@ -99,7 +99,7 @@

          Quick search

          ©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12 diff --git a/docs/api/python/modules/onnxruntime/capi/onnxruntime_inference_collection.html b/docs/api/python/modules/onnxruntime/capi/onnxruntime_inference_collection.html index 62ba39e85ba4b..2fed76086f235 100644 --- a/docs/api/python/modules/onnxruntime/capi/onnxruntime_inference_collection.html +++ b/docs/api/python/modules/onnxruntime/capi/onnxruntime_inference_collection.html @@ -5,7 +5,7 @@ - onnxruntime.capi.onnxruntime_inference_collection — ONNX Runtime 1.11.0 documentation + onnxruntime.capi.onnxruntime_inference_collection — ONNX Runtime 1.13.0 documentation @@ -16,6 +16,7 @@ + @@ -48,16 +49,15 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          from onnxruntime.capi import _pybind_state as C -def get_ort_device_type(device): - device_type = device if type(device) is str else device.type.lower() - if device_type == 'cuda': +def get_ort_device_type(device_type, device_index): + if device_type == "cuda": return C.OrtDevice.cuda() - elif device_type == 'cpu': + elif device_type == "cpu": return C.OrtDevice.cpu() - elif device_type == 'ort': - return C.get_ort_device(device.index).device_type() + elif device_type == "ort": + return C.get_ort_device(device_index).device_type() else: - raise Exception('Unsupported device type: ' + device_type) + raise Exception("Unsupported device type: " + device_type) def check_and_normalize_provider_args(providers, provider_options, available_provider_names): @@ -90,8 +90,10 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          def set_provider_options(name, options): if name not in available_provider_names: - warnings.warn("Specified provider '{}' is not in available provider names." - "Available providers: '{}'".format(name, ", ".join(available_provider_names))) + warnings.warn( + "Specified provider '{}' is not in available provider names." + "Available providers: '{}'".format(name, ", ".join(available_provider_names)) + ) if name in provider_name_to_options: warnings.warn("Duplicate provider '{}' encountered, ignoring.".format(name)) @@ -123,8 +125,12 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          for provider in providers: if isinstance(provider, str): set_provider_options(provider, dict()) - elif isinstance(provider, tuple) and len(provider) == 2 and \ - isinstance(provider[0], str) and isinstance(provider[1], dict): + elif ( + isinstance(provider, tuple) + and len(provider) == 2 + and isinstance(provider[0], str) + and isinstance(provider[1], dict) + ): set_provider_options(provider[0], provider[1]) else: raise ValueError("'providers' values must be either strings or (string, dict) tuples.") @@ -136,6 +142,7 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          """ This is the main class used to run a model. """ + def __init__(self): # self._sess is managed by the derived class and relies on bindings from C.InferenceSession @@ -214,6 +221,8 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          :param output_names: name of the outputs :param input_feed: dictionary ``{ input_name: input_value }`` :param run_options: See :class:`onnxruntime.RunOptions`. + :return: list of results, every result is either a numpy array, + a sparse tensor, a list or a dictionary. :: @@ -244,7 +253,7 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          Compute the predictions. :param output_names: name of the outputs - :param input_feed: dictionary ``{ input_name: input_ort_value }`` + :param input_dict_ort_values: dictionary ``{ input_name: input_ort_value }`` See ``OrtValue`` class how to create `OrtValue` from numpy array or `SparseTensor` :param run_options: See :class:`onnxruntime.RunOptions`. @@ -254,11 +263,14 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          sess.run([output_name], {input_name: x}) """ + def invoke(sess, output_names, input_dict_ort_values, run_options): input_dict = {} for n, v in input_dict_ort_values.items(): input_dict[n] = v._get_c_value() result = sess.run_with_ort_values(input_dict, output_names, run_options) + if not isinstance(result, C.OrtValueVector): + raise TypeError("run_with_ort_values() must return a instance of type 'OrtValueVector'.") ort_values = [OrtValue(v) for v in result] return ort_values @@ -306,10 +318,10 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          def run_with_iobinding(self, iobinding, run_options=None): """ - Compute the predictions. + Compute the predictions. - :param iobinding: the iobinding object that has graph inputs/outputs bind. - :param run_options: See :class:`onnxruntime.RunOptions`. + :param iobinding: the iobinding object that has graph inputs/outputs bind. + :param run_options: See :class:`onnxruntime.RunOptions`. """ self._sess.run_with_iobinding(iobinding._iobinding, run_options) @@ -318,6 +330,7 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          """ This is the main class used to run a model. """ + def __init__(self, path_or_bytes, sess_options=None, providers=None, provider_options=None, **kwargs): """ :param path_or_bytes: filename or serialized ONNX or ORT format model in a byte string @@ -364,10 +377,10 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          self._sess_options = sess_options self._sess_options_initial = sess_options self._enable_fallback = True - self._read_config_from_model = os.environ.get('ORT_LOAD_CONFIG_FROM_MODEL') == '1' + self._read_config_from_model = os.environ.get("ORT_LOAD_CONFIG_FROM_MODEL") == "1" # internal parameters that we don't expect to be used in general so aren't documented - disabled_optimizers = kwargs['disabled_optimizers'] if 'disabled_optimizers' in kwargs else None + disabled_optimizers = kwargs["disabled_optimizers"] if "disabled_optimizers" in kwargs else None try: self._create_inference_session(providers, provider_options, disabled_optimizers) @@ -385,21 +398,25 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          available_providers = C.get_available_providers() # Tensorrt can fall back to CUDA. All others fall back to CPU. - if 'TensorrtExecutionProvider' in available_providers: - self._fallback_providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] + if "TensorrtExecutionProvider" in available_providers: + self._fallback_providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] + elif "MIGraphXExecutionProvider" in available_providers: + self._fallback_providers = ["ROCMExecutionProvider", "CPUExecutionProvider"] else: - self._fallback_providers = ['CPUExecutionProvider'] + self._fallback_providers = ["CPUExecutionProvider"] # validate providers and provider_options before other initialization - providers, provider_options = check_and_normalize_provider_args(providers, - provider_options, - available_providers) + providers, provider_options = check_and_normalize_provider_args( + providers, provider_options, available_providers + ) if providers == [] and len(available_providers) > 1: self.disable_fallback() - raise ValueError("This ORT build has {} enabled. ".format(available_providers) + - "Since ORT 1.9, you are required to explicitly set " + - "the providers parameter when instantiating InferenceSession. For example, " - "onnxruntime.InferenceSession(..., providers={}, ...)".format(available_providers)) + raise ValueError( + "This ORT build has {} enabled. ".format(available_providers) + + "Since ORT 1.9, you are required to explicitly set " + + "the providers parameter when instantiating InferenceSession. For example, " + "onnxruntime.InferenceSession(..., providers={}, ...)".format(available_providers) + ) session_options = self._sess_options if self._sess_options else C.get_default_session_options() if self._model_path: @@ -446,19 +463,20 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          [docs]class IOBinding: - ''' + """ This class provides API to bind input/output to a specified device, e.g. GPU. - ''' + """ + def __init__(self, session): self._iobinding = C.SessionIOBinding(session._sess) self._numpy_obj_references = {}
          [docs] def bind_cpu_input(self, name, arr_on_cpu): - ''' + """ bind an input to array on CPU :param name: input name :param arr_on_cpu: input values as a python array on CPU - ''' + """ # Hold a reference to the numpy object as the bound OrtValue is backed # directly by the data buffer of the numpy object and so the numpy object # must be around until this IOBinding instance is around @@ -466,38 +484,53 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          self._iobinding.bind_input(name, arr_on_cpu)
          [docs] def bind_input(self, name, device_type, device_id, element_type, shape, buffer_ptr): - ''' + """ :param name: input name :param device_type: e.g. cpu, cuda :param device_id: device id, e.g. 0 :param element_type: input element type :param shape: input shape :param buffer_ptr: memory pointer to input data - ''' - self._iobinding.bind_input(name, - C.OrtDevice(get_ort_device_type(device_type), C.OrtDevice.default_memory(), - device_id), - element_type, shape, buffer_ptr)
          + """ + self._iobinding.bind_input( + name, + C.OrtDevice( + get_ort_device_type(device_type, device_id), + C.OrtDevice.default_memory(), + device_id, + ), + element_type, + shape, + buffer_ptr, + )
          [docs] def bind_ortvalue_input(self, name, ortvalue): - ''' + """ :param name: input name :param ortvalue: OrtValue instance to bind - ''' + """ self._iobinding.bind_ortvalue_input(name, ortvalue._ortvalue)
          def synchronize_inputs(self): self._iobinding.synchronize_inputs() -
          [docs] def bind_output(self, name, device_type='cpu', device_id=0, element_type=None, shape=None, buffer_ptr=None): - ''' +
          [docs] def bind_output( + self, + name, + device_type="cpu", + device_id=0, + element_type=None, + shape=None, + buffer_ptr=None, + ): + """ :param name: output name :param device_type: e.g. cpu, cuda, cpu by default :param device_id: device id, e.g. 0 :param element_type: output element type :param shape: output shape :param buffer_ptr: memory pointer to output data - ''' + """ # Follow the `if` path when the user has not provided any pre-allocated buffer but still # would like to bind an output to a specific device (e.g. cuda). @@ -506,41 +539,51 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          # in which case ORT will allocate the memory for the user # (2) The output has a dynamic shape and hence the size of the buffer may not be fixed across runs if buffer_ptr is None: - self._iobinding.bind_output(name, - C.OrtDevice(get_ort_device_type(device_type), C.OrtDevice.default_memory(), - device_id)) + self._iobinding.bind_output( + name, + C.OrtDevice( + get_ort_device_type(device_type, device_id), + C.OrtDevice.default_memory(), + device_id, + ), + ) else: if element_type is None or shape is None: raise ValueError("`element_type` and `shape` are to be provided if pre-allocated memory is provided") - self._iobinding.bind_output(name, - C.OrtDevice(get_ort_device_type(device_type), C.OrtDevice.default_memory(), - device_id), - element_type, shape, buffer_ptr)
          + self._iobinding.bind_output( + name, + C.OrtDevice( + get_ort_device_type(device_type, device_id), + C.OrtDevice.default_memory(), + device_id, + ), + element_type, + shape, + buffer_ptr, + )
          [docs] def bind_ortvalue_output(self, name, ortvalue): - ''' + """ :param name: output name :param ortvalue: OrtValue instance to bind - ''' + """ self._iobinding.bind_ortvalue_output(name, ortvalue._ortvalue)
          def synchronize_outputs(self): self._iobinding.synchronize_outputs()
          [docs] def get_outputs(self): - ''' + """ Returns the output OrtValues from the Run() that preceded the call. The data buffer of the obtained OrtValues may not reside on CPU memory - ''' - returned_ortvalues = [] - - for ortvalue in self._iobinding.get_outputs(): - returned_ortvalues.append(OrtValue(ortvalue)) - - return returned_ortvalues
          + """ + outputs = self._iobinding.get_outputs() + if not isinstance(outputs, C.OrtValueVector): + raise TypeError("get_outputs() must return an instance of type 'OrtValueVector'.") + return [OrtValue(ortvalue) for ortvalue in outputs]
          [docs] def copy_outputs_to_cpu(self): - '''Copy output contents to CPU (if on another device). No-op if already on the CPU.''' + """Copy output contents to CPU (if on another device). No-op if already on the CPU.""" return self._iobinding.copy_outputs_to_cpu()
          def clear_binding_inputs(self): @@ -551,11 +594,12 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          [docs]class OrtValue: - ''' + """ A data structure that supports all ONNX data formats (tensors and non-tensors) that allows users to place the data backing these on a device, for example, on a CUDA supported device. This class provides APIs to construct and deal with OrtValues. - ''' + """ + def __init__(self, ortvalue, numpy_obj=None): if isinstance(ortvalue, C.OrtValue): self._ortvalue = ortvalue @@ -564,140 +608,183 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          self._numpy_obj = numpy_obj else: # An end user won't hit this error - raise ValueError("`Provided ortvalue` needs to be of type " + - "`onnxruntime.capi.onnxruntime_pybind11_state.OrtValue`") + raise ValueError( + "`Provided ortvalue` needs to be of type " + "`onnxruntime.capi.onnxruntime_pybind11_state.OrtValue`" + ) def _get_c_value(self): return self._ortvalue
          [docs] @staticmethod - def ortvalue_from_numpy(numpy_obj, device_type='cpu', device_id=0): - ''' + def ortvalue_from_numpy(numpy_obj, device_type="cpu", device_id=0): + """ Factory method to construct an OrtValue (which holds a Tensor) from a given Numpy object A copy of the data in the Numpy object is held by the OrtValue only if the device is NOT cpu :param numpy_obj: The Numpy object to construct the OrtValue from :param device_type: e.g. cpu, cuda, cpu by default :param device_id: device id, e.g. 0 - ''' + """ # Hold a reference to the numpy object (if device_type is 'cpu') as the OrtValue # is backed directly by the data buffer of the numpy object and so the numpy object # must be around until this OrtValue instance is around - return OrtValue(C.OrtValue.ortvalue_from_numpy(numpy_obj, C.OrtDevice(get_ort_device_type(device_type), - C.OrtDevice.default_memory(), device_id)), numpy_obj if device_type.lower() == 'cpu' else None)
          + return OrtValue( + C.OrtValue.ortvalue_from_numpy( + numpy_obj, + C.OrtDevice( + get_ort_device_type(device_type, device_id), + C.OrtDevice.default_memory(), + device_id, + ), + ), + numpy_obj if device_type.lower() == "cpu" else None, + )
          [docs] @staticmethod - def ortvalue_from_shape_and_type(shape=None, element_type=None, device_type='cpu', device_id=0): - ''' + def ortvalue_from_shape_and_type(shape=None, element_type=None, device_type="cpu", device_id=0): + """ Factory method to construct an OrtValue (which holds a Tensor) from given shape and element_type :param shape: List of integers indicating the shape of the OrtValue :param element_type: The data type of the elements in the OrtValue (numpy type) :param device_type: e.g. cpu, cuda, cpu by default :param device_id: device id, e.g. 0 - ''' + """ if shape is None or element_type is None: raise ValueError("`element_type` and `shape` are to be provided if pre-allocated memory is provided") - return OrtValue(C.OrtValue.ortvalue_from_shape_and_type(shape, element_type, - C.OrtDevice(get_ort_device_type(device_type), C.OrtDevice.default_memory(), device_id)))
          + return OrtValue( + C.OrtValue.ortvalue_from_shape_and_type( + shape, + element_type, + C.OrtDevice( + get_ort_device_type(device_type, device_id), + C.OrtDevice.default_memory(), + device_id, + ), + ) + )
          [docs] @staticmethod def ort_value_from_sparse_tensor(sparse_tensor): - ''' + """ The function will construct an OrtValue instance from a valid SparseTensor The new instance of OrtValue will assume the ownership of sparse_tensor - ''' + """ return OrtValue(C.OrtValue.ort_value_from_sparse_tensor(sparse_tensor._get_c_tensor()))
          [docs] def as_sparse_tensor(self): - ''' + """ The function will return SparseTensor contained in this OrtValue - ''' + """ return SparseTensor(self._ortvalue.as_sparse_tensor())
          [docs] def data_ptr(self): - ''' + """ Returns the address of the first element in the OrtValue's data buffer - ''' + """ return self._ortvalue.data_ptr()
          [docs] def device_name(self): - ''' + """ Returns the name of the device where the OrtValue's data buffer resides e.g. cpu, cuda - ''' + """ return self._ortvalue.device_name().lower()
          [docs] def shape(self): - ''' + """ Returns the shape of the data in the OrtValue - ''' + """ return self._ortvalue.shape()
          [docs] def data_type(self): - ''' + """ Returns the data type of the data in the OrtValue - ''' + """ return self._ortvalue.data_type()
          +
          [docs] def element_type(self): + """ + Returns the proto type of the data in the OrtValue + if the OrtValue is a tensor. + """ + return self._ortvalue.element_type()
          +
          [docs] def has_value(self): - ''' + """ Returns True if the OrtValue corresponding to an optional type contains data, else returns False - ''' + """ return self._ortvalue.has_value()
          [docs] def is_tensor(self): - ''' + """ Returns True if the OrtValue contains a Tensor, else returns False - ''' + """ return self._ortvalue.is_tensor()
          [docs] def is_sparse_tensor(self): - ''' + """ Returns True if the OrtValue contains a SparseTensor, else returns False - ''' + """ return self._ortvalue.is_sparse_tensor()
          [docs] def is_tensor_sequence(self): - ''' + """ Returns True if the OrtValue contains a Tensor Sequence, else returns False - ''' + """ return self._ortvalue.is_tensor_sequence()
          [docs] def numpy(self): - ''' + """ Returns a Numpy object from the OrtValue. Valid only for OrtValues holding Tensors. Throws for OrtValues holding non-Tensors. Use accessors to gain a reference to non-Tensor objects such as SparseTensor - ''' - return self._ortvalue.numpy()
          + """ + return self._ortvalue.numpy()
          + +
          [docs] def update_inplace(self, np_arr): + """ + Update the OrtValue in place with a new Numpy array. The numpy contents + are copied over to the device memory backing the OrtValue. It can be used + to update the input valuess for an InferenceSession with CUDA graph + enabled or other scenarios where the OrtValue needs to be updated while + the memory address can not be changed. + """ + self._ortvalue.update_inplace(np_arr)
          [docs]class OrtDevice: - ''' + """ A data structure that exposes the underlying C++ OrtDevice - ''' + """ + def __init__(self, c_ort_device): - ''' + """ Internal constructor - ''' + """ if isinstance(c_ort_device, C.OrtDevice): self._ort_device = c_ort_device else: - raise ValueError("`Provided object` needs to be of type " + - "`onnxruntime.capi.onnxruntime_pybind11_state.OrtDevice`") + raise ValueError( + "`Provided object` needs to be of type " + "`onnxruntime.capi.onnxruntime_pybind11_state.OrtDevice`" + ) def _get_c_device(self): - ''' + """ Internal accessor to underlying object - ''' + """ return self._ort_device @staticmethod def make(ort_device_name, device_id): - return OrtDevice(C.OrtDevice(get_ort_device_type(ort_device_name), - C.OrtDevice.default_memory(), device_id)) + return OrtDevice( + C.OrtDevice( + get_ort_device_type(ort_device_name, device_id), + C.OrtDevice.default_memory(), + device_id, + ) + ) def device_id(self): return self._ort_device.device_id() @@ -707,29 +794,31 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          [docs]class SparseTensor: - ''' + """ A data structure that project the C++ SparseTensor object The class provides API to work with the object. Depending on the format, the class will hold more than one buffer depending on the format - ''' + """ + def __init__(self, sparse_tensor): - ''' + """ Internal constructor - ''' + """ if isinstance(sparse_tensor, C.SparseTensor): self._tensor = sparse_tensor else: # An end user won't hit this error - raise ValueError("`Provided object` needs to be of type " + - "`onnxruntime.capi.onnxruntime_pybind11_state.SparseTensor`") + raise ValueError( + "`Provided object` needs to be of type " + "`onnxruntime.capi.onnxruntime_pybind11_state.SparseTensor`" + ) def _get_c_tensor(self): return self._tensor
          [docs] @staticmethod def sparse_coo_from_numpy(dense_shape, values, coo_indices, ort_device): - ''' + """ Factory method to construct a SparseTensor in COO format from given arguments :param dense_shape: 1-D numpy array(int64) or a python list that contains a dense_shape of the sparse tensor @@ -748,13 +837,14 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          on GC. The buffers may reside in any storage either CPU or GPU. For strings and objects, it will create a copy of the arrays in CPU memory as ORT does not support those on other devices and their memory can not be mapped. - ''' - return SparseTensor(C.SparseTensor.sparse_coo_from_numpy(dense_shape, values, coo_indices, - ort_device._get_c_device()))
          + """ + return SparseTensor( + C.SparseTensor.sparse_coo_from_numpy(dense_shape, values, coo_indices, ort_device._get_c_device()) + )
          [docs] @staticmethod def sparse_csr_from_numpy(dense_shape, values, inner_indices, outer_indices, ort_device): - ''' + """ Factory method to construct a SparseTensor in CSR format from given arguments :param dense_shape: 1-D numpy array(int64) or a python list that contains a dense_shape of the @@ -773,20 +863,27 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          The buffers may reside in any storage either CPU or GPU. For strings and objects, it will create a copy of the arrays in CPU memory as ORT does not support those on other devices and their memory can not be mapped. - ''' - return SparseTensor(C.SparseTensor.sparse_csr_from_numpy(dense_shape, values, inner_indices, outer_indices, - ort_device._get_c_device()))
          + """ + return SparseTensor( + C.SparseTensor.sparse_csr_from_numpy( + dense_shape, + values, + inner_indices, + outer_indices, + ort_device._get_c_device(), + ) + )
          [docs] def values(self): - ''' + """ The method returns a numpy array that is backed by the native memory if the data type is numeric. Otherwise, the returned numpy array that contains copies of the strings. - ''' + """ return self._tensor.values()
          [docs] def as_coo_view(self): - ''' + """ The method will return coo representation of the sparse tensor which will enable querying COO indices. If the instance did not contain COO format, it would throw. You can query coo indices as: @@ -796,11 +893,11 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          coo_indices = sparse_tensor.as_coo_view().indices() which will return a numpy array that is backed by the native memory. - ''' + """ return self._tensor.get_coo_data()
          [docs] def as_csrc_view(self): - ''' + """ The method will return CSR(C) representation of the sparse tensor which will enable querying CRS(C) indices. If the instance dit not contain CSR(C) format, it would throw. You can query indices as: @@ -811,11 +908,11 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          outer_ndices = sparse_tensor.as_csrc_view().outer() returning numpy arrays backed by the native memory. - ''' + """ return self._tensor.get_csrc_data()
          [docs] def as_blocksparse_view(self): - ''' + """ The method will return coo representation of the sparse tensor which will enable querying BlockSparse indices. If the instance did not contain BlockSparse format, it would throw. You can query coo indices as: @@ -825,11 +922,11 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          block_sparse_indices = sparse_tensor.as_blocksparse_view().indices() which will return a numpy array that is backed by the native memory - ''' + """ return self._tensor.get_blocksparse_data()
          [docs] def to_cuda(self, ort_device): - ''' + """ Returns a copy of this instance on the specified cuda device :param ort_device: with name 'cuda' and valid gpu device id @@ -840,31 +937,31 @@

          Source code for onnxruntime.capi.onnxruntime_inference_collection

          - this instance is already on GPU. Cross GPU copy is not supported - CUDA is not present in this build - if the specified device is not valid - ''' + """ return SparseTensor(self._tensor.to_cuda(ort_device._get_c_device()))
          [docs] def format(self): - ''' + """ Returns a OrtSparseFormat enumeration - ''' + """ return self._tensor.format
          [docs] def dense_shape(self): - ''' + """ Returns a numpy array(int64) containing a dense shape of a sparse tensor - ''' + """ return self._tensor.dense_shape()
          [docs] def data_type(self): - ''' + """ Returns a string data type of the data in the OrtValue - ''' + """ return self._tensor.data_type()
          [docs] def device_name(self): - ''' + """ Returns the name of the device where the SparseTensor data buffers reside e.g. cpu, cuda - ''' + """ return self._tensor.device_name().lower()
          @@ -889,7 +986,7 @@

          ONNX Runtime

          Navigation

          @@ -911,7 +1008,7 @@

          Quick search

          - + @@ -928,7 +1025,7 @@

          Quick search

          ©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12
          diff --git a/docs/api/python/modules/onnxruntime/datasets.html b/docs/api/python/modules/onnxruntime/datasets.html deleted file mode 100644 index b4e759a2d8dd6..0000000000000 --- a/docs/api/python/modules/onnxruntime/datasets.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - onnxruntime.datasets — ONNX Runtime 1.11.0 documentation - - - - - - - - - - - - - - - - - - - - - - -
          -
          -
          - - -
          - -

          Source code for onnxruntime.datasets

          -# Copyright (c) Microsoft Corporation. All rights reserved.
          -# Licensed under the MIT License.
          -"""
          -Short examples used in the documentation.
          -"""
          -import os
          -
          -
          -
          [docs]def get_example(name): - """ - Retrieves the absolute file name of an example. - """ - this = os.path.abspath(os.path.dirname(__file__)) - full = os.path.join(this, name) - if not os.path.exists(full): - raise FileNotFoundError("Unable to find example '{0}'".format(name)) - return full
          -
          - -
          - -
          -
          - -
          -
          - - - - - - - \ No newline at end of file diff --git a/docs/api/python/objects.inv b/docs/api/python/objects.inv index 138759759d8a3a4d1d43b0db97c272cdbd3234ec..e87c37d6a1e5c85c7d98fbda8eaf707276e95a92 100644 GIT binary patch delta 1827 zcmV+;2i*9J50np(Ljg09L`Q$L%gV)Uvr8JF2+(8(NlH3__VRW)+D^B`Ool6-1E_qW0L=7a)1Bw)J5xX73}q!|D^3-e6O2$383bk(_BpHf?_uP=DJ1_X6#)Mp|N} z2{MFhp|(YKPt(MsG(qt0$b9h4vGp$M!9W-(2{$1kPH>jz?n`*!X`D|1G;#1yZvU-p z3GgK1RViyvY+trep&;eQIG28KX&3{=4Yk=cfiQH(0lw4c8V_tGA$*$Aj^V8z>ubfI zug%oz^l^plah`u8+ihfm7xaiAhE(mVp=t7>kud=cGJ&E)O^q1*!L}yk8#16e2px%y z<^g!YS&hhrWEFgPiJ{Mf`L`e@JGnm3lhzPbQV!0vm7{GEeOze_ZQO}mKnTYyU~ZaV zEfgUrhnL*V5N9go;#}#GxBqjD*lNF>ODJz14_DCRFbHC4g->fJgHfH>KElzN9~! z2=vRXH?)+S<`Tn}d1OwC;9Q4ODjb(Gyg*G51{SG%#_fgbhNJzuBzHG;2m*!JniWXv zLXI?a5PyH9pqD^KMUGTk$7wGbgw%-9gTjGM4p|0Dj4Q5SfMyUsrK~*4Y|{pR@4Mjj zMRowRBj16E>_^*FpDB6WxV;;;Oo$jPT4kX$o^#}w1O6e%qanXx@tjCUEQL@dHUR|f zH@08MckG$u(<%<1{n@6 zPh7$+*}XzM4c^?}t+3}1KIW!t$dbtsYQe0m?Qa-QPxjX-^YHe6$>JEc&E(yU@shC) zu+4wW)aA*Nr2%G}u}35J;+Gra(%oQnqD}rT7ugg^^8V%14p)$%$px2^5&b*JA(s*6 z{?)NZhuls2B$l1kV6k{kfeW-z(fcQ7DS#<&BVTB{vpzd`K~bKza{Ou z1jE*$`s6e-PTBBqrlc`}^X8_qL(S{CUG7Bu1yAQqH*axrwjQ9VB}|&me@asKW8Q+4 zZkdzNrG+WN?(h}}yJe2>qr$JCxO+Is+fVol#N9f_{NkpR#GFXd&*L^O@Z!-J`?Y_s zPO<8fO=5zbM<3DkF2TN^38eeAeIUWe<1X2n$GZ-K%25UwJbs)^j)Y&c5yJ-hw|TYYOo21C3%h@V)u~d4`V|i{j7Lj7>I}TyD5D@uu8|piX6&o3KAF~_iR$AeGmog`#??YC|81*c(GJ0PcCnsu!n3Hx_Dpm{ppUT3#_}Tifaw~6; z{pUnam4TH?Bc$~?WyAcwQc;8qKc{Gz>eniYk>zJK4b%NfQE!^j=foF2Ozr8en+=BJ R<7i$;zPJC|{RdHtsP1Zzm}>w4 delta 1818 zcmV+#2j%#b4~q|wLjf_7L`Q$5%gV)Uvr8JF7$C_EGC|QDK}***5s6eu$}`H>_fpi; zmZ=AsuErzroO}4VFG_I!CQGha4*SQakBp~`pQ56ApJY_2=pmv7BdW}EDy#ij=h?g8 zqIf5!Q2PV^B}q{d#*0!Lk{t9|q#IcL8HCgqnw1ceN|f50%ZnlrMb&>$D58Z~?5$KM z&@IzS3Vs9$Jb@QbiV42%uv~%nDO2>20XfnvJJ95ZpO!uFuxu$Qq&TvyaS9JEv)=Vl zQ~`)`kwS(XGyqqSLtvRMASFxd9blYkMl<#kWC-eR7l_hSYGOtb9*FtEQjkOx8lQ!v z48f)B??CF9AcsE0dk}x&3x5Xk%Ji8q5loUL#BfdOc4t_j{Ov?mA zf0Pkj-y*ll~*J`-5}0ftnj zE0W=lY;Cx?B13$jkFqM&N$Vp<8o61 zZP~CfbWhV1&m90s@g=vltnCwk94buyTxiot5=ba)N)*(s*;VWql&}k(~%| zEh{h5rtvkmFFE9dVj)ZYHoc`Zba*21DDiNF5=sSO=th4Hx({9LeP&ZkcO8sO$kd(} z54K?=80^H@YT5LaIr~|A;I=4uMa#IZn`x7=h(1f8sq&|kG%TfmDw!bkOeeRD>r=`V zN3*+-+8ZN+jshmTc+y&zgPIQg50323lTpHnDRXd|hF27dWb7cR=OM=^gDJ+QK{UV; z^q;&aHza?=x}y8u6?Dtf;Q(k_k3%MsA5DFDVeqsfl8Pr5m-{ay5 z^2zTz+YH|Qv@>h>8o9;%#AVQ&-5#>h;MG0S0(%y*#oTlbnKL;;&6q7JbC>?`V7`** zySLDD7RRu4CU0&o=Zv+0b!Mh66Xq-pFzbxnYldfcZj2inHEXLt+u|PHXkM(3g9f@h z01ba0MoOpeQ;|$fA^PzA7`@mBJ6d9zXw<1ca8clGguQ)jIsT$}>d}rkM(yh>t|Akf zG~x6<<#3c`e){_LpXi%ifaqg`$7EfZoTjNx)@b0%P6=yivz-h_=laUE)AZQO<`v@{c}dQ;=W?6NaH&S+!l zf$ojj$8o9X31;n0#vC;35p}XS6DNNOr&iEdgDy>orCDp}MMDuiytnRxd^JZ@DzjLX zC}nh{7X)aCjuKnUS0R7waLmMMEULJD(S$9LmT2Cd%fZ_jSaV88Xa!Uz=P}SevzQnA z{u!5ir;76%Ic1WJmfN)xz43Pj93wb3BjOG`<&)EP$jBv%YMu8?n~%-F&Lw}5)9qp| zVPij9AaBC)Tq1`~t&G$eA9ZWJUmq+|?k+E8=23&=7996rGpkj}#Wlwp|6ee%>6qb~ zjX}iJoE?iWQ}Bo|t_gLO%YuoFsvPG8+L1_|3UcachZ;dkGnGr|bUlByK=l1W%sGJ?);n8&Izu?voigsuH0~5~_v9;+Uz_2v zCBH5CI$^1J<<@O~L9S@YXOc#|Ois`Y;gWWfDi#a;pVER`yfZ&6oXRhV{w~o|X<(t! z0AbywY#84cDhd$cU5bXGeyO4mQQoO(815H}`lS)wCH8J;k9TbkGHec0M}0~3z4>qV IA25q`CpHOp6aWAK diff --git a/docs/api/python/search.html b/docs/api/python/search.html index 75827edb1896e..5347ffb91beac 100644 --- a/docs/api/python/search.html +++ b/docs/api/python/search.html @@ -5,7 +5,7 @@ - Search — ONNX Runtime 1.11.0 documentation + Search — ONNX Runtime 1.13.0 documentation @@ -17,6 +17,7 @@ + @@ -93,7 +94,7 @@

          ONNX Runtime

          Navigation

          @@ -120,7 +121,7 @@

          Related Topics

          ©2018-2021, Microsoft. | - Powered by Sphinx 4.3.2 + Powered by Sphinx 5.1.1 & Alabaster 0.7.12
          diff --git a/docs/api/python/searchindex.js b/docs/api/python/searchindex.js index 33823485fffc9..429ff14e448f1 100644 --- a/docs/api/python/searchindex.js +++ b/docs/api/python/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["api_summary","auto_examples/index","auto_examples/plot_backend","auto_examples/plot_common_errors","auto_examples/plot_convert_pipeline_vectorizer","auto_examples/plot_load_and_predict","auto_examples/plot_metadata","auto_examples/plot_pipeline","auto_examples/plot_profiling","auto_examples/plot_train_convert_predict","auto_examples/sg_execution_times","examples_md","index","tutorial"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["api_summary.rst","auto_examples/index.rst","auto_examples/plot_backend.rst","auto_examples/plot_common_errors.rst","auto_examples/plot_convert_pipeline_vectorizer.rst","auto_examples/plot_load_and_predict.rst","auto_examples/plot_metadata.rst","auto_examples/plot_pipeline.rst","auto_examples/plot_profiling.rst","auto_examples/plot_train_convert_predict.rst","auto_examples/sg_execution_times.rst","examples_md.rst","index.rst","tutorial.rst"],objects:{"onnxruntime.IOBinding":[[0,1,1,"","bind_cpu_input"],[0,1,1,"","bind_input"],[0,1,1,"","bind_ortvalue_input"],[0,1,1,"","bind_ortvalue_output"],[0,1,1,"","bind_output"],[0,1,1,"","copy_outputs_to_cpu"],[0,1,1,"","get_outputs"]],"onnxruntime.InferenceSession":[[0,1,1,"","disable_fallback"],[0,1,1,"","enable_fallback"],[0,1,1,"","end_profiling"],[0,1,1,"","get_inputs"],[0,1,1,"","get_modelmeta"],[0,1,1,"","get_outputs"],[0,1,1,"","get_overridable_initializers"],[0,1,1,"","get_profiling_start_time_ns"],[0,1,1,"","get_provider_options"],[0,1,1,"","get_providers"],[0,1,1,"","get_session_options"],[0,1,1,"","io_binding"],[0,1,1,"","run"],[0,1,1,"","run_with_iobinding"],[0,1,1,"","run_with_ort_values"],[0,1,1,"","set_providers"]],"onnxruntime.ModelMetadata":[[0,2,1,"","custom_metadata_map"],[0,2,1,"","description"],[0,2,1,"","domain"],[0,2,1,"","graph_description"],[0,2,1,"","graph_name"],[0,2,1,"","producer_name"],[0,2,1,"","version"]],"onnxruntime.NodeArg":[[0,2,1,"","name"],[0,2,1,"","shape"],[0,2,1,"","type"]],"onnxruntime.OrtValue":[[0,1,1,"","as_sparse_tensor"],[0,1,1,"","data_ptr"],[0,1,1,"","data_type"],[0,1,1,"","device_name"],[0,1,1,"","has_value"],[0,1,1,"","is_sparse_tensor"],[0,1,1,"","is_tensor"],[0,1,1,"","is_tensor_sequence"],[0,1,1,"","numpy"],[0,1,1,"","ort_value_from_sparse_tensor"],[0,1,1,"","ortvalue_from_numpy"],[0,1,1,"","ortvalue_from_shape_and_type"],[0,1,1,"","shape"]],"onnxruntime.RunOptions":[[0,2,1,"","log_severity_level"],[0,2,1,"","log_verbosity_level"],[0,2,1,"","logid"],[0,2,1,"","only_execute_path_to_fetches"],[0,2,1,"","terminate"]],"onnxruntime.SessionOptions":[[0,1,1,"","add_free_dimension_override_by_denotation"],[0,1,1,"","add_free_dimension_override_by_name"],[0,1,1,"","add_initializer"],[0,1,1,"","add_session_config_entry"],[0,2,1,"","enable_cpu_mem_arena"],[0,2,1,"","enable_mem_pattern"],[0,2,1,"","enable_mem_reuse"],[0,2,1,"","enable_profiling"],[0,2,1,"","execution_mode"],[0,2,1,"","execution_order"],[0,1,1,"","get_session_config_entry"],[0,2,1,"","graph_optimization_level"],[0,2,1,"","inter_op_num_threads"],[0,2,1,"","intra_op_num_threads"],[0,2,1,"","log_severity_level"],[0,2,1,"","log_verbosity_level"],[0,2,1,"","logid"],[0,2,1,"","optimized_model_filepath"],[0,2,1,"","profile_file_prefix"],[0,1,1,"","register_custom_ops_library"],[0,2,1,"","use_deterministic_compute"]],"onnxruntime.SparseTensor":[[0,1,1,"","as_blocksparse_view"],[0,1,1,"","as_coo_view"],[0,1,1,"","as_csrc_view"],[0,1,1,"","data_type"],[0,1,1,"","dense_shape"],[0,1,1,"","device_name"],[0,1,1,"","format"],[0,1,1,"","sparse_coo_from_numpy"],[0,1,1,"","sparse_csr_from_numpy"],[0,1,1,"","to_cuda"],[0,1,1,"","values"]],"onnxruntime.backend":[[0,3,1,"","is_compatible"],[0,3,1,"","prepare"],[0,3,1,"","run"],[0,3,1,"","supports_device"]],"onnxruntime.datasets":[[0,3,1,"","get_example"]],onnxruntime:[[0,0,1,"","IOBinding"],[0,0,1,"","InferenceSession"],[0,0,1,"","ModelMetadata"],[0,0,1,"","NodeArg"],[0,0,1,"","OrtDevice"],[0,0,1,"","OrtValue"],[0,0,1,"","RunOptions"],[0,0,1,"","SessionOptions"],[0,0,1,"","SparseTensor"],[0,3,1,"","get_device"]]},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","property","Python property"],"3":["py","function","Python function"]},objtypes:{"0":"py:class","1":"py:method","2":"py:property","3":"py:function"},terms:{"0":[0,2,3,4,5,6,7,8,9,10,13],"00":10,"0002686927327886224":3,"000857":9,"000869":9,"000873":9,"000874":9,"000876":9,"000881":9,"0008813192099997735":9,"000883":9,"0008830492349999729":9,"000884":9,"000885":9,"000895":9,"000899":9,"000907":9,"00091":9,"000912":9,"000913":9,"000914":9,"000915":9,"000916":9,"000921":9,"000922":9,"000928":9,"000934":9,"00094":9,"000941":9,"000948":9,"000966":9,"000967":9,"000972":9,"000977":9,"000983":9,"000992":9,"00101":9,"00107":9,"00108":9,"0010817126199989956":9,"00111":9,"0024466365575790405":3,"00402":9,"00404":9,"00409":9,"005":[6,10],"00597":9,"00599":9,"00606":9,"007":[8,10],"009":[3,10],"01":[8,9],"0116":6,"013":[5,10],"013000461272895336":9,"014":[2,10],"02":9,"021566055715084076":3,"027834143489599228":3,"03":10,"03678159e":9,"03936365991830826":9,"04_17":8,"05":[3,9],"05698008090257645":9,"0636":9,"0637":9,"0639":9,"07":3,"07e":9,"09":8,"098":9,"0982":9,"0987":9,"0x7feaf2025c10":9,"0x7feafe274ac0":7,"1":[0,2,3,4,6,7,8,9],"10":9,"100":9,"100n":0,"11":8,"13":9,"133":9,"14":9,"15":9,"159":[9,10],"16":8,"167":9,"168":9,"1833212822675705":9,"196":[7,10],"2":[0,2,3,4,6,7,8,9],"20":9,"201":9,"202":9,"203":9,"22":[4,9,10],"23":10,"236":9,"237":9,"240":8,"25":[8,9],"25e":9,"271":9,"3":[0,2,3,5,6,7,8,9],"30":9,"30004554e":9,"305":9,"3089":8,"339":9,"34":9,"35":9,"36":8,"370":10,"374":9,"375":9,"38e":9,"3c59201b940f410fa29dc71ea9d5767d":6,"3g":9,"4":[0,3,5,7,8,9,13],"40":9,"42990368e":9,"45":9,"46e":9,"5":[0,3,5,7,8,9],"50":9,"5047166":5,"5055595":5,"50677085":5,"5097179":5,"51":9,"5178277":5,"5184905":5,"52279866":5,"5249817":5,"525905":5,"5320551":5,"53635114":5,"5369593":5,"5392329":5,"5398089":5,"54673976":5,"548968":5,"55":8,"550723":5,"5522731":5,"55390376":5,"5549751":5,"56":8,"5622808":5,"5627599":5,"56360227":5,"5688669":5,"56964463":5,"5735331":5,"5743989":5,"5819309":5,"5826889":5,"5833795":5,"5842683":5,"58536506":5,"59407187":5,"59544575":5,"6":[3,7,8,9],"60552883":5,"60617851e":9,"60848683":5,"6108959":5,"62443805":5,"6270167988259345e":3,"6312441":5,"6324704":5,"63349843":5,"63380575":5,"6382853":5,"63900065":5,"63964766":5,"6423601":5,"64378905":5,"65169865":5,"65232253":5,"6620137":5,"6746977":5,"68858314":5,"69634616":5,"69650024":5,"69800366e":9,"7":[7,8],"708999":5,"71":8,"71247685":5,"715":9,"7161434":5,"717":9,"72":9,"7210646":5,"7223234":5,"7300966":5,"787709464906584e":3,"8":[4,9],"8036782741546631":9,"83321386e":9,"8492364688427188e":9,"84923705e":9,"87":4,"9":[8,9],"9209977605173356":4,"92e":9,"93636566e":9,"9429903030395508":9,"9505997896194458":3,"95951945e":9,"9595235901069827e":9,"9606178402900696":9,"966":[4,10],"9671264999914226e":9,"97e":9,"9974970817565918":3,"9997311234474182":3,"9999999999999366":4,"boolean":0,"byte":[0,3],"case":[0,4,9],"class":3,"default":0,"do":[4,6,9],"float":[0,3,4,5],"function":[0,4],"import":[2,3,4,5,6,7,8,9,13],"int":[0,4],"new":0,"public":0,"return":[0,3,8,9],"static":0,"switch":2,"throw":0,"true":[0,4,8,9],"try":[2,3,4],"while":0,A:0,And:9,At:13,But:4,By:0,For:[0,12],If:0,In:[0,4,13],It:[0,3,5,6,13],Its:0,NOT:0,No:0,On:0,That:7,The:[0,2,3,4,5,8,9,13],Then:[7,9],There:[7,13],These:0,To:0,With:6,about:[0,4],absolut:0,access:0,accessor:0,across:0,actual:[0,3,4],add_free_dimension_override_by_denot:0,add_free_dimension_override_by_nam:0,add_initi:0,add_session_config_entri:0,addit:0,address:0,after:0,aka:12,all:[0,1,3],alloc:0,allow:0,alreadi:0,also:[0,2,5],altern:4,alwai:0,am:4,among:3,an:[0,3,4,5,7,9,13],ani:[0,3],anoth:0,api:[2,12],appear:9,append:[0,9],appli:0,applic:13,ar:[0,8,9,13],arena:0,arg0:0,arg1:0,arg:[0,8],argument:0,arr_on_cpu:0,arrai:[0,2,3,5,8,9],array_equ:0,as_blocksparse_view:0,as_coo_view:0,as_csrc_view:0,as_fram:4,as_sparse_tensor:0,associ:0,assum:0,astyp:[5,9,13],auto_exampl:10,auto_examples_jupyt:1,auto_examples_python:1,av:9,avail:[0,5],averag:9,ax:9,axesimag:7,back:0,backend:[1,10],bad:3,basic:0,batch:[9,13],becaus:[0,4],befor:[7,8],being:0,below:0,better:9,between:[0,2,9],bind:0,bind_cpu_input:0,bind_input:0,bind_ortvalue_input:0,bind_ortvalue_output:0,bind_output:0,block_sparse_indic:0,blockspars:0,blue:9,boston:4,both:0,bound:0,briefli:13,buffer:0,buffer_ptr:0,build:0,c:[0,9],c_ort_devic:0,california:4,call:[0,4],can:[0,2,3,4,8,13],cannot:[0,3],capabl:0,capi:[0,2,3,4],cat:8,categori:4,chang:[0,13],change_ir_vers:8,check:0,chenta:7,choos:0,chosen:0,click:[2,3,4,5,6,7,8,9],clr:[9,13],cmu:4,code:[0,1,2,3,4,5,6,7,8,9,13],col:0,common:[1,4,9,10,13],commonli:13,compar:[0,4,9],comparison:[0,9],compat:0,compil:[0,2],compos:13,comput:[0,2,4,5,8,9,13],config:0,configur:0,conform:0,confus:[4,9],confusion_matrix:9,consist:[4,9],construct:0,constructor:0,consum:0,contain:[0,6,8],content:[0,7],contigu:0,convert:[1,6,7,10],convert_sklearn:[4,9,13],coo:0,coo_indic:0,coordin:0,copi:0,copy_outputs_to_cpu:0,correspond:0,could:4,count:0,cpu:[0,2,13],cpuexecutionprovid:0,cr:0,creat:[0,4,13],creation:0,cross:0,csr:0,cuda:0,cudaexecutionprovid:0,current:0,curv:9,custom:0,custom_metadata_map:[0,6],d:[0,9],data:[3,4,9,13],data_ptr:0,data_typ:[0,4,7,9,13],data_url:4,datafram:[4,9],dataset:[2,3,4,5,6,7,8,9,13],datset:[4,9],deal:0,debug:0,decreas:0,decrement:0,def:[8,9],defin:[0,13],definit:[0,5],demonstr:[4,5,7,9],denot:0,dens:0,dense_shap:0,depend:[0,2,13],deploi:6,deprec:4,describ:[0,13],descript:[0,6],detail:[4,13],determinist:0,devic:2,device_id:0,device_nam:0,device_typ:0,df:9,dict:0,dictionari:[0,4],dictionarytyp:4,dictvector:4,did:0,differ:[7,9],dim:7,dim_valu:7,dimens:[0,2,3],directli:[0,2],disabl:0,disable_fallback:0,discourag:4,discrep:4,discuss:0,displai:7,dit:0,doc_str:6,docstr:7,document:[0,4],doe:[0,3,8],domain:[0,6,7],don:0,dot:7,doubl:[3,4],download:[0,1,2,3,4,5,6,7,8,9],draw:[1,10],dtype:[2,3,5,8],due:[0,3],dur:8,dynam:0,e:[0,2,3,4],each:0,easi:13,easier:2,edu:4,educ:4,either:[0,2,3],elem_typ:7,element:0,element_typ:0,els:0,enabl:[0,8],enable_cpu_mem_arena:0,enable_fallback:0,enable_mem_pattern:0,enable_mem_reus:0,enable_profil:[0,8],end:[0,4,9],end_profil:[0,8],engin:12,ensembl:[4,9],entri:0,enumer:0,equal:0,error:[0,1,10],etc:0,ethic:4,everi:9,ex:0,exactli:0,exampl:[2,3,4,5,6,7,8,9,12],example1:[5,7,8],example2:3,except:[2,3,4],exchang:12,execut:[0,1,9,10],execution_mod:0,execution_ord:0,exit:0,expect:[2,3,4],experi:9,explain:4,explicitli:0,expos:0,extend:2,extens:0,f:[4,8,9,13],facilit:0,factori:0,fail:[0,3,4],failur:0,fall:0,fallback:0,fals:[0,4],famou:13,fatal:0,favorit:3,fct:9,featur:0,feature_extract:4,feed:[0,3],fetch:[0,4],fetch_california_h:4,fetch_openml:4,few:0,fid:7,file:[0,8,10],filenam:[0,8],first:[0,3,4,9,13],fit:[4,9,13],fix:[2,3],float32:[0,2,3,5,8,9,13],float64:3,float_data:7,float_input:[2,3,4,9,13],floattensortyp:[4,9,13],focus:12,follow:[0,2,3,4],forest:9,format:[0,2,3,6,8],framework:[2,3],free:0,from:[0,2,3,4,5,6,7,8,9,13],full:[2,3,4,5,6,7,8,9],func:4,further:4,futur:0,futurewarn:4,g:0,gain:0,galleri:[2,3,4,5,6,7,8,9,12],gc:0,gced:0,gener:[0,1,2,3,4,5,6,7,8,9],get:[0,9,13],get_available_provid:[3,4,5,6,8,9,13],get_devic:[0,2],get_exampl:[0,2,3,5,6,7,8],get_input:[0,3,4,5,8,9,13],get_modelmeta:[0,6],get_output:[0,3,4,5,9,13],get_overridable_initi:0,get_profiling_start_time_n:0,get_provid:0,get_provider_opt:0,get_session_config_entri:0,get_session_opt:0,getopnodeproduc:7,getpydotgraph:7,github:[5,12],given:0,global:9,goe:3,got:[2,3],gpu:[0,2,13],gracefulli:0,gradientboostingregressor:4,graph:[0,7],graph_descript:0,graph_nam:[0,6],graph_optimization_level:0,green:9,ha:[0,4,9],handl:3,has_valu:0,have:0,header:4,held:0,here:[0,2,3,4,5,6,7,8,9,13],high:13,higher:3,hold:0,home:4,homogen:0,host:0,hous:4,house_pric:4,how:[0,2,5,6,7,8,9],hstack:4,http:4,i:[4,9],id:0,ident:9,identifi:0,im:9,imag:7,implement:[0,2],imread:7,imshow:7,includ:[0,4,7],increment:0,index:[0,2,3],indic:[0,2,3],individu:0,infer:0,inferenc:0,inferencesess:[0,3,4,5,6,8,9,13],info:0,inform:[0,12],initi:[0,7],initial_typ:[4,9,13],inner:0,inner_indic:0,inner_ndic:0,inp:4,input:[0,2,3,4,5,7,9],input_dict_ort_valu:0,input_fe:0,input_nam:[0,3,5,8,9,13],input_ort_valu:0,input_shap:5,input_typ:5,input_valu:0,insensit:0,inst:9,instal:0,instanc:[0,6],instanti:0,instead:[3,4],int64:[0,3,4],int64tensortyp:4,integ:0,inter_op_num_thread:0,interest:0,interpret:8,intra_op_num_thread:0,introduc:0,invalid:[2,3],invalid_argu:[2,3,4],invalidargu:[2,3,4],invoc:0,io:0,io_bind:0,ipynb:[2,3,4,5,6,7,8,9],ir_vers:[6,7,8],iri:[3,9,13],is_compat:0,is_sparse_tensor:0,is_tensor:0,is_tensor_sequ:0,issu:[0,4],its:[0,4,5,7,9,13],json:8,jupyt:[1,2,3,4,5,6,7,8,9],keep:6,kei:0,kernel:0,kind:3,kwarg:0,label:[2,3,9],label_nam:[9,13],learn:[4,5,6,9,13],legend:9,len:9,length:0,let:[0,2,5,6,8,9],level:[0,13],lib:4,libari:0,librari:0,linear:0,linear_model:[9,13],list:[0,13],ll:13,load:[1,2,3,4,6,7,8,9,10],load_boston:4,load_iri:[9,13],load_model_format:0,local:4,log:0,log_severity_level:0,log_verbosity_level:0,logger:0,logi:9,logid:0,logist:[2,3,6],logisticregress:[9,13],logreg_iri:[2,3,6,9,13],look:[3,4,7,9],loop:9,lr:7,ma:9,machin:[4,5,9,13],maco:0,mai:0,maintain:4,make:2,make_pipelin:4,map:[0,4],math:0,matplotlib:[7,9],matrix:[4,9],max:9,mb:10,mean:0,measur:9,mechan:0,memori:0,messag:7,meta:6,metadata:[0,1,10],metadata_prop:6,method:0,metric:[4,9],mi:9,min:9,minut:[2,3,4,5,6,7,8,9],misspel:3,mkl:0,mode:0,model:[1,2,3,4,6,9,10,12],model_loading_arrai:8,model_select:[4,9,13],model_vers:6,modelproto:[0,7],modul:[4,9],monotonic_n:0,more:[0,12,13],most:7,ms:12,msg:4,mul:7,mul_1:[7,8],multipl:[2,3],must:0,n:9,n_estim:9,n_tree:9,name:[0,2,3,4,5,7,8,9,13],nanosecond:0,nativ:0,necessarili:3,need:[0,8,9],net_draw:7,network:12,neural:12,nfor:9,nnz:0,node:[0,7],node_produc:7,non:0,none:[0,3,4,8,9,13],notebook:[1,2,3,4,5,6,7,8,9],np:[0,2,4],nrow:9,number:[0,3,9],numer:0,nummpi:0,numpi:[0,2,3,4,5,8,9,13],numpy_obj:0,o:7,object:[0,7,9],observ:4,obtain:0,one:[0,4,7,9,13],ones:4,onli:[0,3],only_execute_path_to_fetch:0,onnx:[0,1,3,6,8,10],onnx_model:8,onnx_model_str:8,onnxml:6,onnxmltool:[6,13],onnxruntim:[0,1,2,4,5,6,7,8,9,10,12,13],onnxruntime_profile__2022:8,onnxruntime_pybind11_st:[0,2,3,4],onnxruntimeerror:[2,3,4],onx:[4,9,13],op:0,op_typ:7,open:[4,7,8,9,12,13],oper:13,oppos:9,opset:8,opset_import:[7,8],optim:[0,13],optimized_model_filepath:0,option:[3,8],order:0,origin:4,ort:0,ort_devic:0,ort_output:0,ort_value_from_sparse_tensor:0,ortsparseformat:0,ortvalue_from_numpi:0,ortvalue_from_shape_and_typ:0,os:7,other:[0,2,3,7,9,13],otherwis:0,out:[2,3,4,5,6,7,8,9],outer:0,outer_indic:0,outer_ndic:0,output:[0,3,4,5,7,9,13],output_label:9,output_nam:[0,3,5],output_shap:5,output_typ:5,over:0,own:0,ownership:0,packag:[0,2,4,7],pair:0,panda:[4,9],parallel:0,param:0,paramet:0,parsefromstr:7,part:0,particular:0,particularli:0,path:0,path_or_byt:0,pattern:0,pd:4,perfectli:9,perform:[0,12,13],ph:8,pid:8,pipe:4,pipelin:[1,10,13],pipeline_vector:4,place:0,platform:0,pleas:[2,3,12],plot:9,plot_backend:[2,10],plot_common_error:[3,10],plot_convert_pipeline_vector:[4,10],plot_load_and_predict:[5,10],plot_metadata:[6,10],plot_pipelin:[7,10],plot_profil:[8,10],plot_train_convert_predict:[9,10],plt:7,png:7,pointer:0,pprint:[8,9],pre:0,preced:0,precis:0,pred:[4,9],pred_onx:[4,9,13],predict:[0,1,2,3,8,10,13],predict_proba:9,prefix:0,prepar:[0,2],present:0,price:4,primit:0,print:[2,3,4,5,6,7,8,9,13],prob_nam:9,prob_rt:9,prob_sklearn:9,proba:2,probabili:9,probabl:[2,3],problem:4,produc:[0,3,6],producer_nam:[0,6,7],producer_vers:6,product:6,prof_fil:8,profil:[0,1,10],profile_file_prefix:0,project:[0,12],properti:0,protobuf:7,provid:[0,3,4,5,6,8,9,13],provider_opt:0,purpos:4,put:0,py:[2,3,4,5,6,7,8,9,10],pydot_graph:7,pyplot:7,python3:4,python:[0,1,2,3,4,5,6,7,8,9],queri:0,r2_score:4,r:[3,8],rais:3,random:[5,9],randomforestclassifi:9,rang:9,rank:3,rankdir:7,rather:13,raw:9,raw_df:4,rb:[7,8],re:[0,3,5,8],read:[0,7],read_csv:4,readi:0,refer:[0,4],regist:0,register_custom_ops_librari:0,regress:[2,3,6],regular:[0,4],relat:6,relev:9,remov:4,rep:2,repeat:9,replac:3,represent:0,request:0,requir:0,reset:0,resid:0,result:[0,8],retriev:[0,4,5,9],reus:0,rf:9,rf_iri:9,rf_iris_:9,roc:9,row:[0,4],rt:[3,4,5,6,8,9,13],run:[2,3,4,5,6,7,8,9],run_log_severity_level:0,run_opt:0,run_with_iobind:0,run_with_ort_valu:0,runner:4,runtim:[0,1,6,8,10],runtimeerror:[2,3,4],s:[0,2,4,5,6,7,8,9],same:[2,3,9],save:[0,9],save_model_format:0,scenario:[0,4,9,13],scienc:4,scikit:[4,6,9,13],score:12,script:[2,3,4,5,6,7,8,9],se:0,second:[2,3,4,5,6,7,8,9],see:[0,5,6,8,9,12,13],self:0,sep:4,seq:4,sequenc:0,sequencetyp:4,sequenti:0,serial:0,serializetostr:[4,8,9,13],servic:13,sess:[0,3,4,5,6,8,9,13],sess_opt:0,sess_predict:9,sess_predict_proba:9,sess_predict_proba_loop:9,sess_predict_proba_rf:9,sess_profil:8,sess_tim:8,session:[0,8],session_initi:8,session_log_severity_level:0,sessionopt:8,set:[0,4,9,13],set_provid:0,set_titl:9,set_xlabel:9,set_ylabel:9,sever:[0,3],shape:[0,3,4,5,7,9],share:0,should:0,show:[0,4,5,8,9],sigmoid:5,similar:[4,9],simpl:[1,2,6,7,10],singl:[0,3],site:[4,13],situat:3,size:0,skiprow:4,skl2onnx:[4,9,13],sklearn:[4,6,9,13],small:4,snippet:0,so:0,some:[0,8],sourc:[0,1,2,3,4,5,6,7,8,9],spars:[0,4],sparse_coo_from_numpi:0,sparse_csr_from_numpi:0,sparse_tensor:0,special:4,specif:[0,6,13],specifi:[0,13],speed:9,sphinx:[1,2,3,4,5,6,7,8,9],start:[0,3,4,9],stat:4,statu:0,step:[3,4,9],storag:0,store:[0,7,8],str:0,string:0,strongli:4,structur:0,studi:4,suit:0,sum:9,summari:12,suppli:0,suppor:0,support:[0,8],supports_devic:0,system:7,t:[0,4],take:[3,4],target:[4,9,13],tensor:[0,3,4,5],tensor_typ:7,termin:0,test:[0,4,7,9],test_sigmoid:5,than:[0,3,7,13],thei:0,them:[0,4,9],therefor:4,thi:[0,2,3,4,5,7,8,9,13],those:0,thread:0,three:3,thu:0,tid:8,time:[0,2,3,4,5,6,7,8,9],timeit:9,timer:[0,9],to_cuda:0,to_dict:4,tool:[7,13],topolog:0,total:[2,3,4,5,6,7,8,9,10],tpng:7,track:6,train:[1,3,6,10],train_test_split:[4,9,13],tree:9,trt:9,ts:8,tsk:9,tupl:0,tutori:12,twice:0,type:[0,3,4,5,7],un:8,underli:0,unexpect:[3,4],unless:[0,4],unus:0,us:[0,2,3,4,6,7,9],usabl:0,usag:0,use_deterministic_comput:0,user:0,usual:[0,13],util:4,valid:0,valu:[0,4],variabl:4,vector:[3,4,5],verbos:0,veri:[1,4,8,10],verif:0,version:[0,6,7,8],vlog:0,w:7,wa:[2,6],wai:[7,13],want:0,warn:[0,3,4],wb:[4,9,13],we:[4,7,8,9,13],webservic:9,what:[8,9],when:[0,6],where:0,whether:0,which:[0,3,4,6,7,13],window:0,within:0,without:[2,13],work:0,would:0,wrap:0,write:[4,9,13],write_dot:7,x:[0,2,3,4,5,7,8,9,13],x_ortvalu:0,x_test:[4,9,13],x_test_dict:4,x_train:[4,9,13],x_train_dict:4,y:[0,4,5,7,9,13],y_ortvalu:0,y_test:[4,9,13],y_train:[4,9,13],you:[0,4,13],your:3,zero:0,zip:1},titles:["API Summary","Gallery of examples","ONNX Runtime Backend for ONNX","Common errors with onnxruntime","Train, convert and predict with ONNX Runtime","Load and predict with ONNX Runtime and a very simple model","Metadata","Draw a pipeline","Profile the execution of a simple model","Train, convert and predict with ONNX Runtime","Computation times","Gallery of examples","Python Bindings for ONNX Runtime","Tutorial"],titleterms:{"1":13,"2":13,"3":13,"class":0,"export":13,api:0,backend:[0,2],benchmark:9,bind:12,common:3,comput:10,convers:[4,9],convert:[4,9,13],data:0,dataset:0,devic:0,draw:7,error:3,exampl:[0,1],execut:8,favorit:13,format:[4,7,9,13],framework:13,galleri:1,intern:0,iobind:0,json:7,load:[0,5,13],logist:9,main:0,metadata:6,model:[0,5,7,8,13],modelmetadata:0,nodearg:0,onnx:[2,4,5,7,9,12,13],onnxruntim:3,option:0,ortdevic:0,ortvalu:0,pipelin:[4,7],predict:[4,5,9],probabl:9,profil:8,python:12,randomforest:9,regress:9,retriev:7,run:[0,13],runopt:0,runtim:[2,4,5,9,12,13],sessionopt:0,simpl:[5,8],sparsetensor:0,step:13,summari:0,time:10,train:[4,9,13],tutori:13,us:13,veri:5,your:13}}) \ No newline at end of file +Search.setIndex({"docnames": ["api_summary", "auto_examples/index", "auto_examples/plot_backend", "auto_examples/plot_common_errors", "auto_examples/plot_convert_pipeline_vectorizer", "auto_examples/plot_load_and_predict", "auto_examples/plot_metadata", "auto_examples/plot_pipeline", "auto_examples/plot_profiling", "auto_examples/plot_train_convert_predict", "auto_examples/sg_execution_times", "examples_md", "index", "tutorial"], "filenames": ["api_summary.rst", "auto_examples/index.rst", "auto_examples/plot_backend.rst", "auto_examples/plot_common_errors.rst", "auto_examples/plot_convert_pipeline_vectorizer.rst", "auto_examples/plot_load_and_predict.rst", "auto_examples/plot_metadata.rst", "auto_examples/plot_pipeline.rst", "auto_examples/plot_profiling.rst", "auto_examples/plot_train_convert_predict.rst", "auto_examples/sg_execution_times.rst", "examples_md.rst", "index.rst", "tutorial.rst"], "titles": ["API", "Gallery of examples", "ONNX Runtime Backend for ONNX", "Common errors with onnxruntime", "Train, convert and predict with ONNX Runtime", "Load and predict with ONNX Runtime and a very simple model", "Metadata", "Draw a pipeline", "Profile the execution of a simple model", "Train, convert and predict with ONNX Runtime", "Computation times", "Gallery of examples", "Python Bindings for ONNX Runtime", "Tutorial"], "terms": {"onnx": [0, 1, 3, 6, 8, 10], "runtim": [0, 1, 6, 8, 10], "infer": 0, "graph": [0, 7], "format": [0, 2, 3, 6, 8], "ort": 0, "memori": 0, "disk": 0, "constrain": 0, "environ": [0, 4, 9], "The": [0, 2, 3, 4, 5, 8, 9, 13], "consum": 0, "produc": [0, 3, 6], "can": [0, 2, 3, 4, 8, 13], "specifi": [0, 13], "access": 0, "wai": [0, 7, 13], "best": 0, "match": 0, "your": [0, 3], "scenario": [0, 4, 9, 13], "i": [0, 2, 3, 4, 5, 6, 7, 9, 12, 13], "main": 0, "It": [0, 3, 5, 6, 13], "us": [0, 2, 3, 4, 6, 7, 9], "an": [0, 3, 4, 5, 7, 9, 13], "well": 0, "applic": [0, 13], "configur": 0, "session": [0, 8], "onnxruntim": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13], "name": [0, 2, 3, 4, 5, 7, 8, 9, 13], "consist": [0, 4, 9], "comput": [0, 2, 4, 5, 8, 9, 13], "oper": [0, 13], "implement": [0, 2], "optim": [0, 13], "kernel": 0, "differ": [0, 7, 9], "hardwar": 0, "target": [0, 4, 9, 13], "orchestr": 0, "execut": [0, 1, 9, 10], "via": 0, "provid": [0, 3, 4, 5, 6, 8, 9, 13], "contain": [0, 6, 8], "set": [0, 4, 9, 13], "specif": [0, 6, 13], "gpu": [0, 2, 13], "iot": 0, "etc": 0, "ar": [0, 8, 9, 13], "paramet": 0, "from": [0, 2, 3, 4, 5, 6, 7, 8, 9, 13], "chosen": 0, "prioriti": 0, "order": 0, "given": 0, "list": [0, 13], "In": [0, 4, 9, 13], "exampl": [0, 2, 3, 4, 5, 6, 7, 8, 9, 12], "below": 0, "cuda": 0, "If": 0, "cudaexecutionprovid": 0, "cpuexecutionprovid": 0, "avail": [0, 5], "found": 0, "here": [0, 2, 3, 4, 5, 6, 7, 8, 9, 13], "sinc": 0, "1": [0, 2, 3, 4, 6, 7, 8, 9], "10": [0, 9], "you": [0, 4, 13], "must": 0, "explicitli": 0, "onli": [0, 3], "time": [0, 2, 3, 4, 5, 6, 7, 8, 9], "allow": 0, "explicit": 0, "follow": [0, 2, 3, 4], "assum": 0, "nvidia": 0, "replac": [0, 3], "suppli": 0, "other": [0, 2, 3, 7, 9, 13], "For": [0, 12], "enabl": [0, 8], "profil": [0, 1, 10], "enable_profil": [0, 8], "true": [0, 4, 8, 9], "sess_opt": 0, "its": [0, 4, 5, 7, 9, 13], "On": [0, 4, 9], "default": 0, "map": [0, 4], "nativ": 0, "python": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "structur": 0, "numpi": [0, 2, 3, 4, 5, 8, 9, 13], "arrai": [0, 2, 3, 5, 8, 9], "dictionari": [0, 4], "x": [0, 2, 3, 4, 5, 7, 8, 9, 13], "ortvalue_from_numpi": 0, "device_nam": 0, "shape": [0, 3, 4, 5, 7, 9], "data_typ": [0, 4, 7, 9, 13], "tensor": [0, 3, 4, 5], "float": [0, 3, 4, 5], "is_tensor": 0, "np": [0, 2, 4], "array_equ": 0, "part": 0, "feed": [0, 3], "result": [0, 8], "y": [0, 4, 5, 7, 9, 13], "By": 0, "alwai": 0, "place": 0, "": [0, 2, 4, 5, 6, 7, 8, 9], "have": 0, "mai": 0, "than": [0, 3, 7, 13], "becaus": [0, 4], "introduc": 0, "copi": 0, "between": [0, 2, 9], "support": [0, 8], "custom": 0, "all": [0, 1, 3], "user": 0, "back": 0, "thi": [0, 2, 3, 4, 5, 7, 8, 9, 13], "call": [0, 4], "To": 0, "featur": 0, "run_with_iobind": 0, "A": 0, "instanc": [0, 6], "onto": 0, "io_bind": 0, "over": 0, "node": [0, 7], "bind_cpu_input": 0, "bind_output": 0, "copy_outputs_to_cpu": 0, "0": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13], "directli": [0, 2], "x_ortvalu": 0, "bind_input": 0, "device_typ": 0, "device_id": 0, "element_typ": 0, "float32": [0, 2, 3, 5, 8, 9, 13], "buffer_ptr": 0, "data_ptr": 0, "both": 0, "also": [0, 2, 5], "y_ortvalu": 0, "ortvalue_from_shape_and_typ": 0, "3": [0, 2, 3, 5, 6, 7, 8, 9], "2": [0, 2, 3, 4, 6, 7, 8, 9], "chang": [0, 13], "actual": [0, 3, 4], "being": 0, "bound": 0, "request": 0, "alloc": 0, "particularli": 0, "dynam": 0, "get_output": [0, 3, 4, 5, 9, 13], "get": [0, 9, 13], "correspond": 0, "thu": 0, "bind": 0, "return": [0, 3, 8, 9], "which": [0, 3, 4, 6, 7, 13], "ha": [0, 4, 9], "ort_output": 0, "addit": 0, "work": 0, "while": 0, "inferenc": 0, "bind_ortvalue_input": 0, "bind_ortvalue_output": 0, "pytorch": 0, "x_tensor": 0, "contigu": 0, "tupl": 0, "y_shape": 0, "need": [0, 8, 9], "y_tensor": 0, "torch": 0, "empti": 0, "dtype": [0, 2, 3, 5, 8], "path_or_byt": 0, "none": [0, 3, 4, 8, 9, 13], "provider_opt": 0, "kwarg": 0, "sourc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "filenam": [0, 8], "serial": 0, "byte": [0, 3], "string": 0, "sequenc": 0, "decreas": 0, "preced": 0, "valu": [0, 4], "either": [0, 2, 3], "dict": 0, "type": [0, 3, 4, 5, 7], "unless": [0, 4], "so": 0, "add_session_config_entri": 0, "load_model_format": 0, "file": [0, 8, 10], "extens": 0, "when": [0, 6], "ani": [0, 3], "should": 0, "mean": 0, "capabl": 0, "otherwis": 0, "disable_fallback": 0, "disabl": 0, "fallback": 0, "mechan": 0, "enable_fallback": 0, "fail": [0, 3, 4], "due": [0, 3], "failur": 0, "reset": 0, "fall": 0, "end_profil": [0, 8], "end": [0, 4, 9], "store": [0, 7, 8], "get_input": [0, 3, 4, 5, 8, 9, 13], "metadata": [0, 1, 10], "get_modelmeta": [0, 6], "see": [0, 5, 6, 8, 9, 12, 13], "get_overridable_initi": 0, "includ": [0, 4, 7], "initi": [0, 7], "get_profiling_start_time_n": 0, "nanosecond": 0, "start": [0, 3, 4, 9], "compar": [0, 4, 9], "monotonic_n": 0, "after": 0, "some": [0, 8], "platform": 0, "timer": [0, 9], "precis": 0, "window": 0, "maco": 0, "100n": 0, "get_provider_opt": 0, "regist": 0, "get_provid": 0, "get_session_opt": 0, "object": [0, 7, 9], "output_nam": [0, 3, 5], "input_fe": 0, "run_opt": 0, "predict": [0, 1, 2, 3, 8, 10, 13], "input_nam": [0, 3, 5, 8, 9, 13], "input_valu": 0, "everi": [0, 9], "spars": [0, 4], "sess": [0, 3, 4, 5, 6, 8, 9, 13], "run_with_ort_valu": 0, "input_dict_ort_valu": 0, "input_ort_valu": 0, "how": [0, 2, 5, 6, 7, 8, 9], "creat": [0, 4, 13], "set_provid": 0, "underli": 0, "re": [0, 3, 5, 8], "self": 0, "capi": [0, 2, 3, 4], "onnxruntime_pybind11_st": [0, 2, 3, 4], "inform": [0, 12], "singl": [0, 3], "add_run_config_entri": 0, "arg0": 0, "str": 0, "arg1": 0, "entri": 0, "pair": 0, "get_run_config_entri": 0, "kei": 0, "properti": 0, "log_severity_level": 0, "log": 0, "sever": [0, 3], "level": [0, 13], "particular": 0, "invoc": 0, "verbos": 0, "info": 0, "warn": [0, 3, 4], "error": [0, 1, 10], "4": [0, 3, 5, 7, 8, 9, 13], "fatal": 0, "log_verbosity_level": 0, "vlog": 0, "debug": 0, "build": 0, "run_log_severity_level": 0, "appli": 0, "logid": 0, "identifi": 0, "gener": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "only_execute_path_to_fetch": 0, "fetch": [0, 4], "termin": 0, "current": 0, "individu": 0, "exit": 0, "gracefulli": 0, "statu": 0, "add_external_initi": 0, "add_free_dimension_override_by_denot": 0, "int": [0, 4], "dimens": [0, 2, 3], "size": 0, "each": 0, "denot": 0, "associ": 0, "free": 0, "add_free_dimension_override_by_nam": 0, "within": 0, "add_initi": 0, "enable_cpu_mem_arena": 0, "arena": 0, "pre": 0, "futur": 0, "usag": 0, "fals": [0, 4], "don": 0, "t": [0, 4, 8], "want": 0, "enable_mem_pattern": 0, "pattern": 0, "enable_mem_reus": 0, "reus": 0, "execution_mod": 0, "mode": 0, "sequenti": 0, "execution_ord": 0, "basic": 0, "topolog": 0, "get_session_config_entri": 0, "graph_optimization_level": 0, "inter_op_num_thread": 0, "number": [0, 3, 9], "thread": 0, "parallel": 0, "across": 0, "let": [0, 2, 5, 6, 8, 9], "choos": 0, "intra_op_num_thread": 0, "session_log_severity_level": 0, "logger": 0, "id": 0, "optimized_model_filepath": 0, "path": 0, "save_model_format": 0, "config": 0, "case": [0, 4, 9], "insensit": 0, "profile_file_prefix": 0, "prefix": 0, "append": [0, 9], "register_custom_ops_librari": 0, "share": 0, "librari": 0, "op": 0, "requir": 0, "use_deterministic_comput": 0, "whether": 0, "determinist": 0, "numpy_obj": 0, "non": 0, "construct": 0, "deal": 0, "as_sparse_tensor": 0, "function": [0, 4], "address": 0, "first": [0, 3, 4, 9, 13], "element": 0, "buffer": 0, "where": 0, "resid": 0, "e": [0, 2, 3, 4], "g": 0, "proto": 0, "has_valu": 0, "els": 0, "is_sparse_tensor": 0, "is_tensor_sequ": 0, "valid": 0, "hold": 0, "throw": 0, "accessor": 0, "gain": 0, "refer": [0, 4], "static": 0, "ort_value_from_sparse_tensor": 0, "sparse_tensor": 0, "new": 0, "ownership": 0, "factori": 0, "method": 0, "held": 0, "NOT": 0, "integ": 0, "indic": [0, 2, 3], "update_inplac": 0, "np_arr": 0, "updat": 0, "content": [0, 7], "valuess": 0, "project": [0, 12], "c": [0, 9], "depend": [0, 2, 13], "more": [0, 12, 13], "one": [0, 4, 7, 9, 13], "constructor": 0, "as_blocksparse_view": 0, "coo": 0, "represent": [0, 4, 9], "queri": 0, "blockspars": 0, "did": 0, "would": 0, "block_sparse_indic": 0, "as_coo_view": 0, "coo_indic": 0, "as_csrc_view": 0, "csr": 0, "cr": 0, "dit": 0, "inner_ndic": 0, "inner": 0, "outer_ndic": 0, "outer": 0, "dense_shap": 0, "int64": [0, 3, 4], "dens": 0, "ortsparseformat": 0, "enumer": 0, "sparse_coo_from_numpi": 0, "ort_devic": 0, "argument": 0, "d": [0, 9], "homogen": 0, "zero": 0, "linear": 0, "index": [0, 2, 3], "length": 0, "equal": 0, "coordin": 0, "nnz": 0, "exactli": 0, "twice": 0, "describ": [0, 13], "own": 0, "nummpi": 0, "suppor": 0, "numer": 0, "primit": 0, "them": [0, 4, 9], "storag": 0, "increment": 0, "count": 0, "decrement": 0, "gc": 0, "doe": [0, 3, 8], "those": 0, "sparse_csr_from_numpi": 0, "inner_indic": 0, "outer_indic": 0, "row": [0, 4], "col": 0, "Its": 0, "gced": 0, "to_cuda": 0, "alreadi": 0, "cross": 0, "present": 0, "arr_on_cpu": 0, "param": 0, "pointer": 0, "anoth": 0, "No": 0, "obtain": 0, "c_ort_devic": 0, "expos": 0, "These": 0, "cannot": [0, 3], "instanti": 0, "thei": 0, "libari": 0, "defin": [0, 13], "about": [0, 4], "usual": [0, 13], "facilit": 0, "comparison": [0, 9], "custom_metadata_map": [0, 6], "descript": [0, 6], "domain": [0, 6, 7], "graph_descript": 0, "host": 0, "graph_nam": [0, 6], "producer_nam": [0, 6, 7], "version": [0, 6, 7, 8], "definit": [0, 5], "arg": [0, 8], "regular": [0, 4], "perform": [0, 12, 13], "usabl": 0, "verif": 0, "conform": 0, "is_compat": 0, "compat": 0, "unus": 0, "ex": 0, "boolean": 0, "prepar": [0, 2], "readi": 0, "modelproto": [0, 7], "compil": [0, 2], "supports_devic": 0, "check": 0, "test": [0, 4, 7, 9], "suit": 0, "draw": [1, 10], "pipelin": [1, 10, 13], "load": [1, 2, 3, 4, 6, 7, 8, 9, 10], "veri": [1, 4, 8, 10], "simpl": [1, 2, 6, 7, 10], "model": [1, 2, 3, 4, 6, 9, 10, 12], "backend": [1, 10], "train": [1, 3, 6, 10], "convert": [1, 6, 7, 10], "common": [1, 4, 9, 10, 13], "download": [1, 2, 3, 4, 5, 6, 7, 8, 9], "code": [1, 2, 3, 4, 5, 6, 7, 8, 9, 13], "auto_examples_python": 1, "zip": 1, "jupyt": [1, 2, 3, 4, 5, 6, 7, 8, 9], "notebook": [1, 2, 3, 4, 5, 6, 7, 8, 9], "auto_examples_jupyt": 1, "sphinx": [1, 2, 3, 4, 5, 6, 7, 8, 9], "click": [2, 3, 4, 5, 6, 7, 8, 9], "full": [2, 3, 4, 5, 6, 7, 8, 9], "extend": 2, "api": [2, 12], "run": [2, 3, 4, 5, 6, 7, 8, 9], "logist": [2, 3, 6], "regress": [2, 3, 6], "import": [2, 3, 4, 5, 6, 7, 8, 9, 13], "devic": 2, "packag": [2, 4, 7], "wa": [2, 6], "cpu": [2, 13], "dataset": [2, 3, 4, 5, 6, 7, 8, 9, 13], "get_devic": 2, "invalidargu": [2, 3, 4], "get_exampl": [2, 3, 5, 6, 7, 8], "logreg_iri": [2, 3, 6, 9, 13], "rep": 2, "try": [2, 3, 4, 9], "label": [2, 3, 9], "proba": 2, "print": [2, 3, 4, 5, 6, 7, 8, 9, 13], "probabl": [2, 3], "except": [2, 3, 4], "runtimeerror": [2, 3, 4], "onnxruntimeerror": [2, 3, 4], "invalid_argu": [2, 3, 4], "got": [2, 3], "invalid": [2, 3], "input": [2, 3, 4, 5, 7, 9], "float_input": [2, 3, 4, 9, 13], "expect": [2, 3, 4], "pleas": [2, 3, 4, 9, 12], "fix": [2, 3], "without": [2, 13], "framework": [2, 3], "make": 2, "easier": 2, "switch": 2, "multipl": [2, 3], "same": [2, 3, 9], "total": [2, 3, 4, 5, 6, 7, 8, 9, 10], "script": [2, 3, 4, 5, 6, 7, 8, 9], "minut": [2, 3, 4, 5, 6, 7, 8, 9], "014": [2, 10], "second": [2, 3, 4, 5, 6, 7, 8, 9], "plot_backend": [2, 10], "py": [2, 3, 4, 5, 6, 7, 8, 9, 10], "ipynb": [2, 3, 4, 5, 6, 7, 8, 9], "galleri": [2, 3, 4, 5, 6, 7, 8, 9, 12], "look": [3, 4, 7, 9], "situat": 3, "rais": 3, "instead": [3, 4], "step": [3, 4, 9], "favorit": 3, "iri": [3, 9, 13], "take": [3, 4], "vector": [3, 4, 5], "class": 3, "among": 3, "three": 3, "rt": [3, 4, 5, 6, 8, 9, 13], "example2": 3, "inferencesess": [3, 4, 5, 6, 8, 9, 13], "get_available_provid": [3, 4, 5, 6, 8, 9, 13], "bad": 3, "handl": 3, "kind": 3, "5": [3, 5, 7, 8, 9], "6": [3, 7, 8, 9], "float64": 3, "unexpect": [3, 4], "data": [3, 4, 9, 13], "doubl": [3, 4], "output": [3, 4, 5, 7, 9, 13], "misspel": 3, "option": [3, 8], "9505997896194458": 3, "027834143489599228": 3, "021566055715084076": 3, "9974970817565918": 3, "6270167988259345e": 3, "05": [3, 9], "0024466365575790405": 3, "9997311234474182": 3, "787709464906584e": 3, "07": 3, "0002686927327886224": 3, "goe": 3, "necessarili": 3, "r": [3, 8], "rank": 3, "higher": 3, "009": [3, 10], "plot_common_error": [3, 10], "demonstr": [4, 5, 7, 9], "scikit": [4, 6, 9, 13], "learn": [4, 5, 6, 9, 13], "dictvector": 4, "retriev": [4, 5, 9], "boston": 4, "datset": [4, 9], "panda": [4, 9], "sklearn": [4, 6, 9, 13], "load_boston": 4, "model_select": [4, 9, 13], "train_test_split": [4, 9, 13], "x_train": [4, 9, 13], "x_test": [4, 9, 13], "y_train": [4, 9, 13], "y_test": [4, 9, 13], "x_train_dict": 4, "datafram": [4, 9], "to_dict": 4, "x_test_dict": 4, "home": 4, "runner": 4, "local": 4, "lib": 4, "python3": 4, "8": [4, 9], "site": [4, 13], "util": 4, "deprec": 4, "87": 4, "futurewarn": 4, "remov": 4, "hous": 4, "price": 4, "ethic": 4, "problem": 4, "document": 4, "further": 4, "detail": [4, 13], "maintain": 4, "therefor": 4, "strongli": 4, "discourag": 4, "purpos": 4, "studi": 4, "educ": 4, "issu": 4, "scienc": 4, "machin": [4, 5, 9, 13], "special": 4, "origin": 4, "pd": 4, "data_url": 4, "http": 4, "stat": 4, "cmu": 4, "edu": 4, "raw_df": 4, "read_csv": 4, "sep": 4, "skiprow": 4, "22": [4, 10], "header": 4, "hstack": 4, "altern": 4, "california": 4, "func": 4, "fetch_california_h": 4, "am": 4, "fetch_openml": 4, "house_pric": 4, "as_fram": 4, "msg": 4, "categori": 4, "we": [4, 7, 8, 9, 13], "ensembl": [4, 9], "gradientboostingregressor": 4, "feature_extract": 4, "make_pipelin": 4, "pipe": 4, "fit": [4, 9, 13], "x27": 4, "rerun": [4, 9], "cell": [4, 9], "show": [4, 5, 8, 9], "html": [4, 9], "trust": [4, 9], "github": [4, 5, 9, 12], "unabl": [4, 9], "render": [4, 9], "page": [4, 9], "nbviewer": [4, 9], "org": [4, 9], "pipelinepipelin": 4, "dictvectorizerdictvector": 4, "gradientboostingregressorgradientboostingregressor": 4, "confus": [4, 9], "matrix": [4, 9], "metric": [4, 9], "r2_score": 4, "pred": [4, 9], "8843586896936388": 4, "modul": [4, 9], "skl2onnx": [4, 9, 13], "convert_sklearn": [4, 9, 13], "dictionarytyp": 4, "floattensortyp": [4, 9, 13], "int64tensortyp": 4, "sequencetyp": 4, "initial_typ": [4, 9, 13], "onx": [4, 9, 13], "open": [4, 7, 8, 9, 12, 13], "pipeline_vector": 4, "wb": [4, 9, 13], "f": [4, 8, 9, 13], "write": [4, 9, 13], "serializetostr": [4, 8, 9, 13], "inp": 4, "out": 4, "variabl": 4, "could": 4, "do": [4, 6, 9], "pred_onx": [4, 9, 13], "seq": 4, "But": 4, "observ": 4, "ones": 4, "9999999999999561": 4, "similar": [4, 9], "explain": 4, "small": 4, "discrep": 4, "956": [4, 10], "plot_convert_pipeline_vector": [4, 10], "test_sigmoid": 5, "example1": [5, 7, 8], "sigmoid": 5, "input_shap": 5, "input_typ": 5, "output_shap": 5, "output_typ": 5, "random": [5, 9], "astyp": [5, 9, 13], "6362598": 5, "69637424": 5, "66820115": 5, "66656613": 5, "66833836": 5, "6735109": 5, "7306087": 5, "5827978": 5, "5790133": 5, "5281905": 5, "5875758": 5, "5256195": 5, "5485236": 5, "6221244": 5, "6873636": 5, "6726905": 5, "6112579": 5, "52476424": 5, "54415625": 5, "67545795": 5, "5092699": 5, "69676566": 5, "70407355": 5, "64738125": 5, "59030807": 5, "5806675": 5, "56875795": 5, "5390076": 5, "54938734": 5, "7169268": 5, "6765016": 5, "6001371": 5, "7239268": 5, "50898796": 5, "7079662": 5, "6985444": 5, "5496287": 5, "6313638": 5, "51122195": 5, "65290225": 5, "5237154": 5, "671646": 5, "57126474": 5, "6550032": 5, "554477": 5, "5734256": 5, "53975654": 5, "69029194": 5, "6799297": 5, "5502332": 5, "5855049": 5, "68936455": 5, "5244481": 5, "6527785": 5, "50686556": 5, "512562": 5, "6157843": 5, "6511187": 5, "7200693": 5, "62636346": 5, "007": [5, 10], "plot_load_and_predict": [5, 10], "relat": 6, "deploi": 6, "product": 6, "keep": 6, "track": 6, "doc_str": 6, "ir_vers": [6, 7, 8], "metadata_prop": 6, "model_vers": 6, "producer_vers": 6, "onnxml": 6, "onnxmltool": [6, 13], "0116": 6, "With": 6, "meta": 6, "3c59201b940f410fa29dc71ea9d5767d": 6, "003": [6, 10], "plot_metadata": [6, 10], "There": [7, 13], "That": 7, "most": 7, "mul_1": [7, 8], "protobuf": 7, "messag": 7, "chenta": 7, "w": 7, "op_typ": 7, "mul": 7, "dim": 7, "float_data": 7, "tensor_typ": 7, "elem_typ": 7, "dim_valu": 7, "opset_import": [7, 8], "7": [7, 8], "net_draw": 7, "befor": [7, 8], "rb": [7, 8], "fid": 7, "read": 7, "parsefromstr": 7, "tool": [7, 13], "getopnodeproduc": 7, "getpydotgraph": 7, "pydot_graph": 7, "rankdir": 7, "lr": 7, "node_produc": 7, "docstr": 7, "write_dot": 7, "dot": 7, "Then": [7, 9], "imag": 7, "o": 7, "system": 7, "tpng": 7, "displai": 7, "matplotlib": [7, 9], "pyplot": 7, "plt": 7, "imread": 7, "png": 7, "imshow": 7, "axesimag": 7, "0x7ff7301cd3a0": 7, "218": [7, 10], "plot_pipelin": [7, 10], "interpret": 8, "def": [8, 9], "change_ir_vers": 8, "opset": 8, "11": [8, 9], "onnx_model": 8, "onnx_model_str": 8, "9": [8, 9], "16": 8, "25": [8, 9], "36": 8, "sessionopt": 8, "sess_profil": 8, "prof_fil": 8, "onnxruntime_profile__2022": 8, "08": 8, "16_04": 8, "44": 8, "json": 8, "un": 8, "what": [8, 9], "sess_tim": 8, "pprint": [8, 9], "cat": 8, "dur": 8, "67": 8, "model_loading_arrai": 8, "ph": 8, "pid": 8, "3111": 8, "tid": 8, "236": 8, "session_initi": 8, "85": 8, "005": [8, 10], "plot_profil": [8, 10], "load_iri": [9, 13], "linear_model": [9, 13], "logisticregress": [9, 13], "clr": [9, 13], "logisticregressionlogisticregress": 9, "confusion_matrix": 9, "17": 9, "output_label": 9, "label_nam": [9, 13], "perfectli": 9, "ident": 9, "relev": 9, "roc": 9, "curv": 9, "prob_sklearn": 9, "predict_proba": 9, "82164782e": 9, "01": 9, "13598178e": 9, "23703980e": 9, "03": [9, 10], "12021102e": 9, "04": 9, "37134524e": 9, "62053455e": 9, "20249493e": 9, "06": 9, "74038501e": 9, "02": 9, "82594947e": 9, "And": 9, "probabili": 9, "appear": 9, "prob_nam": 9, "prob_rt": 9, "18216472864151": 9, "8135982751846313": 9, "0042370399460196495": 9, "0008120210259221494": 9, "3371346592903137": 9, "6620532870292664": 9, "2024959232803667e": 9, "01740385964512825": 9, "9825949668884277": 9, "timeit": 9, "speed": 9, "inst": 9, "repeat": 9, "20": 9, "global": 9, "raw": 9, "av": 9, "sum": 9, "len": 9, "mi": 9, "ma": 9, "min": 9, "max": 9, "averag": 9, "3g": 9, "46e": 9, "3e": 9, "6e": 9, "84e": 9, "78e": 9, "5e": 9, "838059500016698e": 9, "webservic": 9, "experi": 9, "oppos": 9, "batch": [9, 13], "loop": 9, "fct": 9, "n": 9, "nrow": 9, "rang": 9, "im": 9, "100": 9, "sess_predict": 9, "0042": 9, "00418": 9, "00428": 9, "000862": 9, "000856": 9, "000878": 9, "0008617829299998903": 9, "sess_predict_proba": 9, "00617": 9, "00615": 9, "0062": 9, "000887": 9, "00088": 9, "000915": 9, "0008867338849996997": 9, "better": 9, "save": 9, "randomforestclassifi": 9, "rf": 9, "rf_iri": 9, "sess_predict_proba_rf": 9, "723": 9, "721": 9, "729": 9, "00103": 9, "00102": 9, "00106": 9, "0010315913400006592": 9, "tree": 9, "measur": 9, "n_tree": 9, "51": 9, "n_estim": 9, "rf_iris_": 9, "sess_predict_proba_loop": 9, "tsk": 9, "trt": 9, "df": 9, "ax": 9, "plot": 9, "blue": 9, "logi": 9, "green": 9, "set_xlabel": 9, "set_ylabel": 9, "set_titl": 9, "nfor": 9, "forest": 9, "legend": 9, "0519": 9, "0521": 9, "000867": 9, "000898": 9, "0872": 9, "0871": 9, "0875": 9, "000881": 9, "000877": 9, "000893": 9, "15": 9, "123": 9, "122": 9, "000908": 9, "000896": 9, "000938": 9, "158": 9, "000902": 9, "000918": 9, "193": 9, "000929": 9, "000914": 9, "000961": 9, "30": 9, "228": 9, "229": 9, "000927": 9, "000948": 9, "35": 9, "263": 9, "264": 9, "000946": 9, "000935": 9, "000978": 9, "40": 9, "298": 9, "299": 9, "000952": 9, "000943": 9, "000972": 9, "45": 9, "334": 9, "333": 9, "335": 9, "000953": 9, "000985": 9, "50": 9, "369": 9, "371": 9, "000981": 9, "000973": 9, "00101": 9, "0x7ff71efab280": 9, "21": [9, 10], "167": [9, 10], "plot_train_convert_predict": [9, 10], "379": 10, "auto_exampl": 10, "mb": 10, "00": 10, "focus": 12, "score": 12, "engin": 12, "neural": 12, "network": 12, "exchang": 12, "aka": 12, "m": 12, "tutori": 12, "easi": 13, "high": 13, "rather": 13, "servic": 13, "At": 13, "briefli": 13, "ll": 13, "famou": 13, "commonli": 13, "compos": 13}, "objects": {"onnxruntime": [[0, 0, 1, "", "IOBinding"], [0, 0, 1, "", "InferenceSession"], [0, 0, 1, "", "ModelMetadata"], [0, 0, 1, "", "NodeArg"], [0, 0, 1, "", "OrtDevice"], [0, 0, 1, "", "OrtValue"], [0, 0, 1, "", "RunOptions"], [0, 0, 1, "", "SessionOptions"], [0, 0, 1, "", "SparseTensor"]], "onnxruntime.IOBinding": [[0, 1, 1, "", "bind_cpu_input"], [0, 1, 1, "", "bind_input"], [0, 1, 1, "", "bind_ortvalue_input"], [0, 1, 1, "", "bind_ortvalue_output"], [0, 1, 1, "", "bind_output"], [0, 1, 1, "", "copy_outputs_to_cpu"], [0, 1, 1, "", "get_outputs"]], "onnxruntime.InferenceSession": [[0, 1, 1, "", "disable_fallback"], [0, 1, 1, "", "enable_fallback"], [0, 1, 1, "", "end_profiling"], [0, 1, 1, "", "get_inputs"], [0, 1, 1, "", "get_modelmeta"], [0, 1, 1, "", "get_outputs"], [0, 1, 1, "", "get_overridable_initializers"], [0, 1, 1, "", "get_profiling_start_time_ns"], [0, 1, 1, "", "get_provider_options"], [0, 1, 1, "", "get_providers"], [0, 1, 1, "", "get_session_options"], [0, 1, 1, "", "io_binding"], [0, 1, 1, "", "run"], [0, 1, 1, "", "run_with_iobinding"], [0, 1, 1, "", "run_with_ort_values"], [0, 1, 1, "", "set_providers"]], "onnxruntime.ModelMetadata": [[0, 2, 1, "", "custom_metadata_map"], [0, 2, 1, "", "description"], [0, 2, 1, "", "domain"], [0, 2, 1, "", "graph_description"], [0, 2, 1, "", "graph_name"], [0, 2, 1, "", "producer_name"], [0, 2, 1, "", "version"]], "onnxruntime.NodeArg": [[0, 2, 1, "", "name"], [0, 2, 1, "", "shape"], [0, 2, 1, "", "type"]], "onnxruntime.OrtValue": [[0, 1, 1, "", "as_sparse_tensor"], [0, 1, 1, "", "data_ptr"], [0, 1, 1, "", "data_type"], [0, 1, 1, "", "device_name"], [0, 1, 1, "", "element_type"], [0, 1, 1, "", "has_value"], [0, 1, 1, "", "is_sparse_tensor"], [0, 1, 1, "", "is_tensor"], [0, 1, 1, "", "is_tensor_sequence"], [0, 1, 1, "", "numpy"], [0, 1, 1, "", "ort_value_from_sparse_tensor"], [0, 1, 1, "", "ortvalue_from_numpy"], [0, 1, 1, "", "ortvalue_from_shape_and_type"], [0, 1, 1, "", "shape"], [0, 1, 1, "", "update_inplace"]], "onnxruntime.RunOptions": [[0, 1, 1, "", "add_run_config_entry"], [0, 1, 1, "", "get_run_config_entry"], [0, 2, 1, "", "log_severity_level"], [0, 2, 1, "", "log_verbosity_level"], [0, 2, 1, "", "logid"], [0, 2, 1, "", "only_execute_path_to_fetches"], [0, 2, 1, "", "terminate"]], "onnxruntime.SessionOptions": [[0, 1, 1, "", "add_external_initializers"], [0, 1, 1, "", "add_free_dimension_override_by_denotation"], [0, 1, 1, "", "add_free_dimension_override_by_name"], [0, 1, 1, "", "add_initializer"], [0, 1, 1, "", "add_session_config_entry"], [0, 2, 1, "", "enable_cpu_mem_arena"], [0, 2, 1, "", "enable_mem_pattern"], [0, 2, 1, "", "enable_mem_reuse"], [0, 2, 1, "", "enable_profiling"], [0, 2, 1, "", "execution_mode"], [0, 2, 1, "", "execution_order"], [0, 1, 1, "", "get_session_config_entry"], [0, 2, 1, "", "graph_optimization_level"], [0, 2, 1, "", "inter_op_num_threads"], [0, 2, 1, "", "intra_op_num_threads"], [0, 2, 1, "", "log_severity_level"], [0, 2, 1, "", "log_verbosity_level"], [0, 2, 1, "", "logid"], [0, 2, 1, "", "optimized_model_filepath"], [0, 2, 1, "", "profile_file_prefix"], [0, 1, 1, "", "register_custom_ops_library"], [0, 2, 1, "", "use_deterministic_compute"]], "onnxruntime.SparseTensor": [[0, 1, 1, "", "as_blocksparse_view"], [0, 1, 1, "", "as_coo_view"], [0, 1, 1, "", "as_csrc_view"], [0, 1, 1, "", "data_type"], [0, 1, 1, "", "dense_shape"], [0, 1, 1, "", "device_name"], [0, 1, 1, "", "format"], [0, 1, 1, "", "sparse_coo_from_numpy"], [0, 1, 1, "", "sparse_csr_from_numpy"], [0, 1, 1, "", "to_cuda"], [0, 1, 1, "", "values"]], "onnxruntime.backend": [[0, 3, 1, "", "is_compatible"], [0, 3, 1, "", "prepare"], [0, 3, 1, "", "run"], [0, 3, 1, "", "supports_device"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:property", "3": "py:function"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "property", "Python property"], "3": ["py", "function", "Python function"]}, "titleterms": {"api": 0, "overview": 0, "load": [0, 5, 13], "run": [0, 13], "model": [0, 5, 7, 8, 13], "data": 0, "input": 0, "output": 0, "cpu": 0, "devic": 0, "detail": 0, "inferencesess": 0, "option": 0, "runopt": 0, "sessionopt": 0, "ortvalu": 0, "sparsetensor": 0, "iobind": 0, "ortdevic": 0, "intern": 0, "class": 0, "modelmetadata": 0, "nodearg": 0, "backend": [0, 2], "galleri": 1, "exampl": 1, "onnx": [2, 4, 5, 7, 9, 12, 13], "runtim": [2, 4, 5, 9, 12, 13], "common": 3, "error": 3, "onnxruntim": 3, "train": [4, 9, 13], "convert": [4, 9, 13], "predict": [4, 5, 9], "pipelin": [4, 7], "convers": [4, 9], "format": [4, 7, 9, 13], "veri": 5, "simpl": [5, 8], "metadata": 6, "draw": 7, "retriev": 7, "json": 7, "profil": 8, "execut": 8, "logist": 9, "regress": 9, "probabl": 9, "benchmark": 9, "randomforest": 9, "comput": 10, "time": 10, "python": 12, "bind": 12, "tutori": 13, "step": 13, "1": 13, "us": 13, "your": 13, "favorit": 13, "framework": 13, "2": 13, "export": 13, "3": 13}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.viewcode": 1, "sphinx": 56}}) \ No newline at end of file diff --git a/docs/api/python/sources/api_summary.rst.txt b/docs/api/python/sources/api_summary.rst.txt index 0325cdd47fa97..12d17bafd3ee9 100644 --- a/docs/api/python/sources/api_summary.rst.txt +++ b/docs/api/python/sources/api_summary.rst.txt @@ -1,65 +1,107 @@ -=========== -API Summary -=========== - -Summary of public functions and classes exposed -in *ONNX Runtime*. +=== +API +=== .. contents:: :local: -OrtValue -========= +API Overview +============ -*ONNX Runtime* works with native Python data structures which are mapped into ONNX data formats : -Numpy arrays (tensors), dictionaries (maps), and a list of Numpy arrays (sequences). -The data backing these are on CPU. +*ONNX Runtime* loads and runs inference on a model in ONNX graph format, or ORT format (for memory and disk constrained environments). -*ONNX Runtime* supports a custom data structure that supports all ONNX data formats that allows users -to place the data backing these on a device, for example, on a CUDA supported device. This allows for -interesting *IOBinding* scenarios (discussed below). In addition, *ONNX Runtime* supports directly -working with *OrtValue* (s) while inferencing a model if provided as part of the input feed. +The data consumed and produced by the model can be specified and accessed in the way that best matches your scenario. + +Load and run a model +-------------------- -Below is an example showing creation of an *OrtValue* from a Numpy array while placing its backing memory -on a CUDA device: +InferenceSession is the main class of ONNX Runtime. It is used to load and run an ONNX model, +as well as specify environment and application configuration options. .. code-block:: python - # X is numpy array on cpu, create an OrtValue and place it on cuda device id = 0 - ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0) - ortvalue.device_name() # 'cuda' - ortvalue.shape() # shape of the numpy array X - ortvalue.data_type() # 'tensor(float)' - ortvalue.is_tensor() # 'True' + session = onnxruntime.InferenceSession('model.onnx') + + outputs = session.run([output names], inputs) + +ONNX and ORT format models consist of a graph of computations, modeled as operators, +and implemented as optimized operator kernels for different hardware targets. +ONNX Runtime orchestrates the execution of operator kernels via `execution providers`. +An execution provider contains the set of kernels for a specific execution target (CPU, GPU, IoT etc). +Execution provides are configured using the `providers` parameter. Kernels from different execution +providers are chosen in the priority order given in the list of providers. In the example below +if there is a kernel in the CUDA execution provider ONNX Runtime executes that on GPU. If not +the kernel is executed on CPU. + +.. code-block:: python + + session = onnxruntime.InferenceSession(model, + providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) + +The list of available execution providers can be found here: `Execution Providers `_. + +Since ONNX Runtime 1.10, you must explicitly specify the execution provider for your target. +Running on CPU is the only time the API allows no explicit setting of the `provider` parameter. +In the examples that follow, the `CUDAExecutionProvider` and `CPUExecutionProvider` are used, assuming the application is running on NVIDIA GPUs. +Replace these with the execution provider specific to your environment. + +You can supply other session configurations via the `session options` parameter. For example, to enable +profiling on the session: + +.. code-block:: python + + options = onnxruntime.SessionOptions() + options.enable_profiling=True + session = onnxruntime.InferenceSession('model.onnx', sess_options=options, providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) + + +Data inputs and outputs +----------------------- + +The ONNX Runtime Inference Session consumes and produces data using its OrtValue class. + +Data on CPU +^^^^^^^^^^^ + +On CPU (the default), OrtValues can be mapped to and from native Python data structures: numpy arrays, dictionaries and lists of +numpy arrays. + +.. code-block:: python + + # X is numpy array on cpu + ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X) + ortvalue.device_name() # 'cpu' + ortvalue.shape() # shape of the numpy array X + ortvalue.data_type() # 'tensor(float)' + ortvalue.is_tensor() # 'True' np.array_equal(ortvalue.numpy(), X) # 'True' # ortvalue can be provided as part of the input feed to a model - ses = onnxruntime.InferenceSession('model.onnx') - res = sess.run(["Y"], {"X": ortvalue}) + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) + results = session.run(["Y"], {"X": ortvalue}) -IOBinding -========= +By default, *ONNX Runtime* always places input(s) and output(s) on CPU. Having the data on CPU +may not optimal if the input or output is consumed and produced on a device +other than CPU because it introduces data copy between CPU and the device. -By default, *ONNX Runtime* always places input(s) and output(s) on CPU, which -is not optimal if the input or output is consumed and produced on a device -other than CPU because it introduces data copy between CPU and the device. -*ONNX Runtime* provides a feature, *IO Binding*, which addresses this issue by -enabling users to specify which device to place input(s) and output(s) on. -Here are scenarios to use this feature. -(In the following code snippets, *model.onnx* is the model to execute, -*X* is the input data to feed, and *Y* is the output data.) +Data on device +^^^^^^^^^^^^^^ + +*ONNX Runtime* supports a custom data structure that supports all ONNX data formats that allows users +to place the data backing these on a device, for example, on a CUDA supported device. In ONNX Runtime, +this called `IOBinding`. -Scenario 1: +To use the `IOBinding` feature, replace `InferenceSession.run()` with `InferenceSession.run_with_iobinding()`. A graph is executed on a device other than CPU, for instance CUDA. Users can -use IOBinding to put input on CUDA as the follows. +use IOBinding to copy the data onto the GPU. .. code-block:: python # X is numpy array on cpu - session = onnxruntime.InferenceSession('model.onnx') + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) io_binding = session.io_binding() # OnnxRuntime will copy the data over to the CUDA device if 'input' is consumed by nodes on the CUDA device io_binding.bind_cpu_input('input', X) @@ -67,37 +109,32 @@ use IOBinding to put input on CUDA as the follows. session.run_with_iobinding(io_binding) Y = io_binding.copy_outputs_to_cpu()[0] -Scenario 2: - The input data is on a device, users directly use the input. The output data is on CPU. .. code-block:: python # X is numpy array on cpu X_ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0) - session = onnxruntime.InferenceSession('model.onnx') + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) io_binding = session.io_binding() io_binding.bind_input(name='input', device_type=X_ortvalue.device_name(), device_id=0, element_type=np.float32, shape=X_ortvalue.shape(), buffer_ptr=X_ortvalue.data_ptr()) io_binding.bind_output('output') session.run_with_iobinding(io_binding) Y = io_binding.copy_outputs_to_cpu()[0] -Scenario 3: - -The input data and output data are both on a device, users directly use the input and also place output on the device. +The input data and output data are both on a device, users directly use the input and also place output on the device. .. code-block:: python #X is numpy array on cpu X_ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0) Y_ortvalue = onnxruntime.OrtValue.ortvalue_from_shape_and_type([3, 2], np.float32, 'cuda', 0) # Change the shape to the actual shape of the output being bound - session = onnxruntime.InferenceSession('model.onnx') + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) io_binding = session.io_binding() io_binding.bind_input(name='input', device_type=X_ortvalue.device_name(), device_id=0, element_type=np.float32, shape=X_ortvalue.shape(), buffer_ptr=X_ortvalue.data_ptr()) io_binding.bind_output(name='output', device_type=Y_ortvalue.device_name(), device_id=0, element_type=np.float32, shape=Y_ortvalue.shape(), buffer_ptr=Y_ortvalue.data_ptr()) session.run_with_iobinding(io_binding) -Scenario 4: Users can request *ONNX Runtime* to allocate an output on a device. This is particularly useful for dynamic shaped outputs. Users can use the *get_outputs()* API to get access to the *OrtValue* (s) corresponding to the allocated output(s). @@ -107,7 +144,7 @@ Users can thus consume the *ONNX Runtime* allocated memory for the output as an #X is numpy array on cpu X_ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0) - session = onnxruntime.InferenceSession('model.onnx') + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) io_binding = session.io_binding() io_binding.bind_input(name='input', device_type=X_ortvalue.device_name(), device_id=0, element_type=np.float32, shape=X_ortvalue.shape(), buffer_ptr=X_ortvalue.data_ptr()) #Request ONNX Runtime to bind and allocate memory on CUDA for 'output' @@ -117,7 +154,7 @@ Users can thus consume the *ONNX Runtime* allocated memory for the output as an ort_output = io_binding.get_outputs()[0] -Scenario 5: +In addition, *ONNX Runtime* supports directly working with *OrtValue* (s) while inferencing a model if provided as part of the input feed. Users can bind *OrtValue* (s) directly. @@ -127,39 +164,52 @@ Users can bind *OrtValue* (s) directly. #X is numpy array on cpu X_ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(X, 'cuda', 0) Y_ortvalue = onnxruntime.OrtValue.ortvalue_from_shape_and_type([3, 2], np.float32, 'cuda', 0) # Change the shape to the actual shape of the output being bound - session = onnxruntime.InferenceSession('model.onnx') + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) io_binding = session.io_binding() io_binding.bind_ortvalue_input('input', X_ortvalue) io_binding.bind_ortvalue_output('output', Y_ortvalue) session.run_with_iobinding(io_binding) -Device -====== - -The package is compiled for a specific device, GPU or CPU. -The CPU implementation includes optimizations -such as MKL (Math Kernel Libary). The following function -indicates the chosen option: -.. autofunction:: onnxruntime.get_device +You can also bind inputs and outputs directly to a PyTorch tensor. -Examples and datasets -===================== - -The package contains a few models stored in ONNX format -used in the documentation. These don't need to be downloaded -as they are installed with the package. - -.. autofunction:: onnxruntime.datasets.get_example +.. code-block:: python -Load and run a model -==================== + # X is a PyTorch tensor on device + session = onnxruntime.InferenceSession('model.onnx', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])) + binding = session.io_binding() + + X_tensor = X.contiguous() + + binding.bind_input( + name='X', + device_type='cuda', + device_id=0, + element_type=np.float32, + shape=tuple(x_tensor.shape), + buffer_ptr=x_tensor.data_ptr(), + ) + + ## Allocate the PyTorch tensor for the model output + Y_shape = ... # You need to specify the output PyTorch tensor shape + Y_tensor = torch.empty(Y_shape, dtype=torch.float32, device='cuda:0').contiguous() + binding.bind_output( + name='Y', + device_type='cuda', + device_id=0, + element_type=np.float32, + shape=tuple(Y_tensor.shape), + buffer_ptr=Y_tensor.data_ptr(), + ) + + session.run_with_iobinding(binding) + + +API Details +=========== -*ONNX Runtime* reads a model saved in ONNX format. -The main class *InferenceSession* wraps these functionalities -in a single place. -Main class +InferenceSession ---------- .. autoclass:: onnxruntime.InferenceSession diff --git a/docs/api/python/sources/auto_examples/index.rst.txt b/docs/api/python/sources/auto_examples/index.rst.txt index 30fa6cc39cbc1..7a082c95e7201 100644 --- a/docs/api/python/sources/auto_examples/index.rst.txt +++ b/docs/api/python/sources/auto_examples/index.rst.txt @@ -1,9 +1,5 @@ :orphan: - - -.. _sphx_glr_auto_examples: - Gallery of examples =================== @@ -12,194 +8,176 @@ Gallery of examples +.. raw:: html + +
          + + .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_pipeline_thumb.png - :alt: Draw a pipeline + .. image:: /auto_examples/images/thumb/sphx_glr_plot_pipeline_thumb.png + :alt: Draw a pipeline - :ref:`sphx_glr_auto_examples_plot_pipeline.py` + :ref:`sphx_glr_auto_examples_plot_pipeline.py` .. raw:: html +
          Draw a pipeline
          -.. toctree:: - :hidden: - - /auto_examples/plot_pipeline - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_load_and_predict_thumb.png - :alt: Load and predict with ONNX Runtime and a very simple model + .. image:: /auto_examples/images/thumb/sphx_glr_plot_load_and_predict_thumb.png + :alt: Load and predict with ONNX Runtime and a very simple model - :ref:`sphx_glr_auto_examples_plot_load_and_predict.py` + :ref:`sphx_glr_auto_examples_plot_load_and_predict.py` .. raw:: html +
          Load and predict with ONNX Runtime and a very simple model
          -.. toctree:: - :hidden: - - /auto_examples/plot_load_and_predict - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_backend_thumb.png - :alt: ONNX Runtime Backend for ONNX + .. image:: /auto_examples/images/thumb/sphx_glr_plot_backend_thumb.png + :alt: ONNX Runtime Backend for ONNX - :ref:`sphx_glr_auto_examples_plot_backend.py` + :ref:`sphx_glr_auto_examples_plot_backend.py` .. raw:: html +
          ONNX Runtime Backend for ONNX
          -.. toctree:: - :hidden: - - /auto_examples/plot_backend - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_metadata_thumb.png - :alt: Metadata + .. image:: /auto_examples/images/thumb/sphx_glr_plot_metadata_thumb.png + :alt: Metadata - :ref:`sphx_glr_auto_examples_plot_metadata.py` + :ref:`sphx_glr_auto_examples_plot_metadata.py` .. raw:: html +
          Metadata
          -.. toctree:: - :hidden: - - /auto_examples/plot_metadata - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_profiling_thumb.png - :alt: Profile the execution of a simple model + .. image:: /auto_examples/images/thumb/sphx_glr_plot_profiling_thumb.png + :alt: Profile the execution of a simple model - :ref:`sphx_glr_auto_examples_plot_profiling.py` + :ref:`sphx_glr_auto_examples_plot_profiling.py` .. raw:: html +
          Profile the execution of a simple model
          -.. toctree:: - :hidden: - - /auto_examples/plot_profiling - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_convert_pipeline_vectorizer_thumb.png - :alt: Train, convert and predict with ONNX Runtime + .. image:: /auto_examples/images/thumb/sphx_glr_plot_convert_pipeline_vectorizer_thumb.png + :alt: Train, convert and predict with ONNX Runtime - :ref:`sphx_glr_auto_examples_plot_convert_pipeline_vectorizer.py` + :ref:`sphx_glr_auto_examples_plot_convert_pipeline_vectorizer.py` .. raw:: html +
          Train, convert and predict with ONNX Runtime
          -.. toctree:: - :hidden: - - /auto_examples/plot_convert_pipeline_vectorizer - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_common_errors_thumb.png - :alt: Common errors with onnxruntime + .. image:: /auto_examples/images/thumb/sphx_glr_plot_common_errors_thumb.png + :alt: Common errors with onnxruntime - :ref:`sphx_glr_auto_examples_plot_common_errors.py` + :ref:`sphx_glr_auto_examples_plot_common_errors.py` .. raw:: html +
          Common errors with onnxruntime
          -.. toctree:: - :hidden: - - /auto_examples/plot_common_errors - .. raw:: html
          .. only:: html - .. figure:: /auto_examples/images/thumb/sphx_glr_plot_train_convert_predict_thumb.png - :alt: Train, convert and predict with ONNX Runtime + .. image:: /auto_examples/images/thumb/sphx_glr_plot_train_convert_predict_thumb.png + :alt: Train, convert and predict with ONNX Runtime - :ref:`sphx_glr_auto_examples_plot_train_convert_predict.py` + :ref:`sphx_glr_auto_examples_plot_train_convert_predict.py` .. raw:: html +
          Train, convert and predict with ONNX Runtime
          -.. toctree:: - :hidden: - - /auto_examples/plot_train_convert_predict .. raw:: html -
          - +
          -.. only :: html +.. toctree:: + :hidden: - .. container:: sphx-glr-footer - :class: sphx-glr-footer-gallery + /auto_examples/plot_pipeline + /auto_examples/plot_load_and_predict + /auto_examples/plot_backend + /auto_examples/plot_metadata + /auto_examples/plot_profiling + /auto_examples/plot_convert_pipeline_vectorizer + /auto_examples/plot_common_errors + /auto_examples/plot_train_convert_predict - .. container:: sphx-glr-download sphx-glr-download-python +.. only:: html - :download:`Download all examples in Python source code: auto_examples_python.zip ` + .. container:: sphx-glr-footer sphx-glr-footer-gallery + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download all examples in Python source code: auto_examples_python.zip ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download all examples in Jupyter notebooks: auto_examples_jupyter.zip ` + :download:`Download all examples in Jupyter notebooks: auto_examples_jupyter.zip ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_backend.rst.txt b/docs/api/python/sources/auto_examples/plot_backend.rst.txt index b273b7902120b..59b3152211d70 100644 --- a/docs/api/python/sources/auto_examples/plot_backend.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_backend.rst.txt @@ -29,16 +29,15 @@ to run predictions using this runtime. Let's use the API to compute the prediction of a simple logistic regression model. -.. GENERATED FROM PYTHON SOURCE LINES 17-23 +.. GENERATED FROM PYTHON SOURCE LINES 17-22 .. code-block:: default import numpy as np - from onnxruntime import datasets - from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument - import onnxruntime.backend as backend from onnx import load + import onnxruntime.backend as backend + @@ -46,16 +45,18 @@ of a simple logistic regression model. -.. GENERATED FROM PYTHON SOURCE LINES 24-26 +.. GENERATED FROM PYTHON SOURCE LINES 23-25 The device depends on how the package was compiled, GPU or CPU. -.. GENERATED FROM PYTHON SOURCE LINES 26-41 +.. GENERATED FROM PYTHON SOURCE LINES 25-42 .. code-block:: default - from onnxruntime import get_device + from onnxruntime import datasets, get_device + from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument + device = get_device() name = datasets.get_example("logreg_iris.onnx") @@ -76,8 +77,6 @@ GPU or CPU. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: float_input for the following indices @@ -87,12 +86,12 @@ GPU or CPU. -.. GENERATED FROM PYTHON SOURCE LINES 42-44 +.. GENERATED FROM PYTHON SOURCE LINES 43-45 The backend can also directly load the model without using *onnx*. -.. GENERATED FROM PYTHON SOURCE LINES 44-54 +.. GENERATED FROM PYTHON SOURCE LINES 45-55 .. code-block:: default @@ -112,8 +111,6 @@ without using *onnx*. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: float_input for the following indices @@ -123,7 +120,7 @@ without using *onnx*. -.. GENERATED FROM PYTHON SOURCE LINES 55-58 +.. GENERATED FROM PYTHON SOURCE LINES 56-59 The backend API is implemented by other frameworks and makes it easier to switch between multiple runtimes @@ -137,23 +134,18 @@ with the same API. .. _sphx_glr_download_auto_examples_plot_backend.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_backend.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_backend.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_backend.ipynb ` + :download:`Download Jupyter notebook: plot_backend.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_common_errors.rst.txt b/docs/api/python/sources/auto_examples/plot_common_errors.rst.txt index 871563380fa54..c766c513d96ca 100644 --- a/docs/api/python/sources/auto_examples/plot_common_errors.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_common_errors.rst.txt @@ -31,13 +31,14 @@ It starts by loading the model trained in example trained on *Iris* datasets. The model takes a vector of dimension 2 and returns a class among three. -.. GENERATED FROM PYTHON SOURCE LINES 18-29 +.. GENERATED FROM PYTHON SOURCE LINES 18-30 .. code-block:: default + import numpy + import onnxruntime as rt from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument - import numpy from onnxruntime.datasets import get_example example2 = get_example("logreg_iris.onnx") @@ -53,13 +54,13 @@ a vector of dimension 2 and returns a class among three. -.. GENERATED FROM PYTHON SOURCE LINES 30-33 +.. GENERATED FROM PYTHON SOURCE LINES 31-34 The first example fails due to *bad types*. *onnxruntime* only expects single floats (4 bytes) and cannot handle any other kind of floats. -.. GENERATED FROM PYTHON SOURCE LINES 33-41 +.. GENERATED FROM PYTHON SOURCE LINES 34-42 .. code-block:: default @@ -70,14 +71,12 @@ and cannot handle any other kind of floats. except Exception as e: print("Unexpected type") print("{0}: {1}".format(type(e), e)) - -.. rst-class:: sphx-glr-script-out - Out: +.. rst-class:: sphx-glr-script-out .. code-block:: none @@ -87,12 +86,12 @@ and cannot handle any other kind of floats. -.. GENERATED FROM PYTHON SOURCE LINES 42-44 +.. GENERATED FROM PYTHON SOURCE LINES 43-45 The model fails to return an output if the name is misspelled. -.. GENERATED FROM PYTHON SOURCE LINES 44-52 +.. GENERATED FROM PYTHON SOURCE LINES 45-53 .. code-block:: default @@ -110,8 +109,6 @@ is misspelled. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none Misspelled output name @@ -120,12 +117,12 @@ is misspelled. -.. GENERATED FROM PYTHON SOURCE LINES 53-55 +.. GENERATED FROM PYTHON SOURCE LINES 54-56 The output name is optional, it can be replaced by *None* and *onnxruntime* will then return all the outputs. -.. GENERATED FROM PYTHON SOURCE LINES 55-64 +.. GENERATED FROM PYTHON SOURCE LINES 56-65 .. code-block:: default @@ -144,8 +141,6 @@ and *onnxruntime* will then return all the outputs. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none All outputs @@ -154,11 +149,11 @@ and *onnxruntime* will then return all the outputs. -.. GENERATED FROM PYTHON SOURCE LINES 65-66 +.. GENERATED FROM PYTHON SOURCE LINES 66-67 The same goes if the input name is misspelled. -.. GENERATED FROM PYTHON SOURCE LINES 66-74 +.. GENERATED FROM PYTHON SOURCE LINES 67-75 .. code-block:: default @@ -176,8 +171,6 @@ The same goes if the input name is misspelled. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none Misspelled input name @@ -186,23 +179,23 @@ The same goes if the input name is misspelled. -.. GENERATED FROM PYTHON SOURCE LINES 75-77 +.. GENERATED FROM PYTHON SOURCE LINES 76-78 *onnxruntime* does not necessarily fail if the input dimension is a multiple of the expected input dimension. -.. GENERATED FROM PYTHON SOURCE LINES 77-104 +.. GENERATED FROM PYTHON SOURCE LINES 78-105 .. code-block:: default for x in [ - numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), - numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), - numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), - ]: + numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), + numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), + numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), + ]: try: r = sess.run([output_name], {input_name: x}) print("Shape={0} and predicted labels={1}".format(x.shape, r)) @@ -210,12 +203,12 @@ dimension is a multiple of the expected input dimension. print("ERROR with Shape={0} - {1}".format(x.shape, e)) for x in [ - numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), - numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), - numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), - numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), - ]: + numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32), + numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32), + numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32), + numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32), + ]: try: r = sess.run(None, {input_name: x}) print("Shape={0} and predicted probabilities={1}".format(x.shape, r[1])) @@ -228,8 +221,6 @@ dimension is a multiple of the expected input dimension. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none ERROR with Shape=(4,) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: float_input Got: 1 Expected: 2 Please fix either the inputs or the model. @@ -262,21 +253,21 @@ dimension is a multiple of the expected input dimension. -.. GENERATED FROM PYTHON SOURCE LINES 105-107 +.. GENERATED FROM PYTHON SOURCE LINES 106-108 It does not fail either if the number of dimension is higher than expects but produces a warning. -.. GENERATED FROM PYTHON SOURCE LINES 107-118 +.. GENERATED FROM PYTHON SOURCE LINES 108-119 .. code-block:: default for x in [ - numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32), - numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32), - numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32), - ]: + numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32), + numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32), + numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32), + ]: try: r = sess.run([output_name], {input_name: x}) print("Shape={0} and predicted labels={1}".format(x.shape, r)) @@ -288,8 +279,6 @@ is higher than expects but produces a warning. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none ERROR with Shape=(1, 2, 2) - [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: float_input Got: 3 Expected: 2 Please fix either the inputs or the model. @@ -307,23 +296,18 @@ is higher than expects but produces a warning. .. _sphx_glr_download_auto_examples_plot_common_errors.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_common_errors.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_common_errors.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_common_errors.ipynb ` + :download:`Download Jupyter notebook: plot_common_errors.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_convert_pipeline_vectorizer.rst.txt b/docs/api/python/sources/auto_examples/plot_convert_pipeline_vectorizer.rst.txt index 8aaf14206515b..41ce8b2ad4b7a 100644 --- a/docs/api/python/sources/auto_examples/plot_convert_pipeline_vectorizer.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_convert_pipeline_vectorizer.rst.txt @@ -35,19 +35,21 @@ Train a pipeline The first step consists in retrieving the boston datset. -.. GENERATED FROM PYTHON SOURCE LINES 22-32 +.. GENERATED FROM PYTHON SOURCE LINES 22-34 .. code-block:: default import pandas from sklearn.datasets import load_boston + boston = load_boston() X, y = boston.data, boston.target from sklearn.model_selection import train_test_split + X_train, X_test, y_train, y_test = train_test_split(X, y) - X_train_dict = pandas.DataFrame(X_train[:,1:]).T.to_dict().values() - X_test_dict = pandas.DataFrame(X_test[:,1:]).T.to_dict().values() + X_train_dict = pandas.DataFrame(X_train[:, 1:]).T.to_dict().values() + X_test_dict = pandas.DataFrame(X_test[:, 1:]).T.to_dict().values() @@ -55,8 +57,6 @@ The first step consists in retrieving the boston datset. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none /home/runner/.local/lib/python3.8/site-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function load_boston is deprecated; `load_boston` is deprecated in 1.0 and will be removed in 1.2. @@ -74,7 +74,6 @@ The first step consists in retrieving the boston datset. import pandas as pd import numpy as np - data_url = "http://lib.stat.cmu.edu/datasets/boston" raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None) data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]]) @@ -93,52 +92,49 @@ The first step consists in retrieving the boston datset. housing = fetch_openml(name="house_prices", as_frame=True) for the Ames housing dataset. - warnings.warn(msg, category=FutureWarning) -.. GENERATED FROM PYTHON SOURCE LINES 33-34 +.. GENERATED FROM PYTHON SOURCE LINES 35-36 We create a pipeline. -.. GENERATED FROM PYTHON SOURCE LINES 34-44 +.. GENERATED FROM PYTHON SOURCE LINES 36-45 .. code-block:: default - from sklearn.pipeline import make_pipeline from sklearn.ensemble import GradientBoostingRegressor from sklearn.feature_extraction import DictVectorizer - pipe = make_pipeline( - DictVectorizer(sparse=False), - GradientBoostingRegressor()) - - pipe.fit(X_train_dict, y_train) - - + from sklearn.pipeline import make_pipeline + pipe = make_pipeline(DictVectorizer(sparse=False), GradientBoostingRegressor()) + pipe.fit(X_train_dict, y_train) -.. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - Pipeline(steps=[('dictvectorizer', DictVectorizer(sparse=False)), - ('gradientboostingregressor', GradientBoostingRegressor())]) +.. raw:: html +
          +
          Pipeline(steps=[('dictvectorizer', DictVectorizer(sparse=False)),
          +                    ('gradientboostingregressor', GradientBoostingRegressor())])
          In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
          On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
          +
          +
          +
          -.. GENERATED FROM PYTHON SOURCE LINES 45-47 +.. GENERATED FROM PYTHON SOURCE LINES 46-48 We compute the prediction on the test set and we show the confusion matrix. -.. GENERATED FROM PYTHON SOURCE LINES 47-52 +.. GENERATED FROM PYTHON SOURCE LINES 48-53 .. code-block:: default @@ -153,34 +149,32 @@ and we show the confusion matrix. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - 0.9209977605173356 + 0.8843586896936388 -.. GENERATED FROM PYTHON SOURCE LINES 53-59 +.. GENERATED FROM PYTHON SOURCE LINES 54-60 Conversion to ONNX format +++++++++++++++++++++++++ -We use module +We use module `sklearn-onnx `_ to convert the model into ONNX format. -.. GENERATED FROM PYTHON SOURCE LINES 59-69 +.. GENERATED FROM PYTHON SOURCE LINES 60-70 .. code-block:: default from skl2onnx import convert_sklearn - from skl2onnx.common.data_types import FloatTensorType, Int64TensorType, DictionaryType, SequenceType + from skl2onnx.common.data_types import DictionaryType, FloatTensorType, Int64TensorType, SequenceType # initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))] - initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))] + initial_type = [("float_input", DictionaryType(Int64TensorType([1]), FloatTensorType([])))] onx = convert_sklearn(pipe, initial_types=initial_type) with open("pipeline_vectorize.onnx", "wb") as f: f.write(onx.SerializeToString()) @@ -192,12 +186,12 @@ to convert the model into ONNX format. -.. GENERATED FROM PYTHON SOURCE LINES 70-72 +.. GENERATED FROM PYTHON SOURCE LINES 71-73 We load the model with ONNX Runtime and look at its input and output. -.. GENERATED FROM PYTHON SOURCE LINES 72-82 +.. GENERATED FROM PYTHON SOURCE LINES 73-84 .. code-block:: default @@ -207,6 +201,7 @@ its input and output. sess = rt.InferenceSession("pipeline_vectorize.onnx", providers=rt.get_available_providers()) import numpy + inp, out = sess.get_inputs()[0], sess.get_outputs()[0] print("input name='{}' and shape={} and type={}".format(inp.name, inp.shape, inp.type)) print("output name='{}' and shape={} and type={}".format(out.name, out.shape, out.type)) @@ -217,8 +212,6 @@ its input and output. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none input name='float_input' and shape=[] and type=map(int64,tensor(float)) @@ -227,12 +220,12 @@ its input and output. -.. GENERATED FROM PYTHON SOURCE LINES 83-85 +.. GENERATED FROM PYTHON SOURCE LINES 85-87 We compute the predictions. We could do that in one call: -.. GENERATED FROM PYTHON SOURCE LINES 85-91 +.. GENERATED FROM PYTHON SOURCE LINES 87-93 .. code-block:: default @@ -248,8 +241,6 @@ We could do that in one call: .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Unexpected input data type. Actual: ((seq(map(int64,tensor(float))))) , expected: ((map(int64,tensor(float)))) @@ -257,12 +248,12 @@ We could do that in one call: -.. GENERATED FROM PYTHON SOURCE LINES 92-94 +.. GENERATED FROM PYTHON SOURCE LINES 94-96 But it fails because, in case of a DictVectorizer, ONNX Runtime expects one observation at a time. -.. GENERATED FROM PYTHON SOURCE LINES 94-96 +.. GENERATED FROM PYTHON SOURCE LINES 96-98 .. code-block:: default @@ -275,11 +266,11 @@ ONNX Runtime expects one observation at a time. -.. GENERATED FROM PYTHON SOURCE LINES 97-98 +.. GENERATED FROM PYTHON SOURCE LINES 99-100 We compare them to the model's ones. -.. GENERATED FROM PYTHON SOURCE LINES 98-100 +.. GENERATED FROM PYTHON SOURCE LINES 100-102 .. code-block:: default @@ -291,16 +282,14 @@ We compare them to the model's ones. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - 0.9999999999999366 + 0.9999999999999561 -.. GENERATED FROM PYTHON SOURCE LINES 101-103 +.. GENERATED FROM PYTHON SOURCE LINES 103-105 Very similar. *ONNX Runtime* uses floats instead of doubles, that explains the small discrepencies. @@ -308,28 +297,23 @@ that explains the small discrepencies. .. rst-class:: sphx-glr-timing - **Total running time of the script:** ( 0 minutes 0.966 seconds) + **Total running time of the script:** ( 0 minutes 0.956 seconds) .. _sphx_glr_download_auto_examples_plot_convert_pipeline_vectorizer.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_convert_pipeline_vectorizer.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_convert_pipeline_vectorizer.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_convert_pipeline_vectorizer.ipynb ` + :download:`Download Jupyter notebook: plot_convert_pipeline_vectorizer.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_load_and_predict.rst.txt b/docs/api/python/sources/auto_examples/plot_load_and_predict.rst.txt index 880209ef5fb5b..801638534aaed 100644 --- a/docs/api/python/sources/auto_examples/plot_load_and_predict.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_load_and_predict.rst.txt @@ -27,13 +27,14 @@ This example demonstrates how to load a model and compute the output for an input vector. It also shows how to retrieve the definition of its inputs and outputs. -.. GENERATED FROM PYTHON SOURCE LINES 14-19 +.. GENERATED FROM PYTHON SOURCE LINES 14-20 .. code-block:: default - import onnxruntime as rt import numpy + + import onnxruntime as rt from onnxruntime.datasets import get_example @@ -43,12 +44,12 @@ retrieve the definition of its inputs and outputs. -.. GENERATED FROM PYTHON SOURCE LINES 20-22 +.. GENERATED FROM PYTHON SOURCE LINES 21-23 Let's load a very simple model. The model is available on github `onnx...test_sigmoid `_. -.. GENERATED FROM PYTHON SOURCE LINES 22-26 +.. GENERATED FROM PYTHON SOURCE LINES 23-27 .. code-block:: default @@ -63,11 +64,11 @@ The model is available on github `onnx...test_sigmoid ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_load_and_predict.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_load_and_predict.ipynb ` + :download:`Download Jupyter notebook: plot_load_and_predict.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_metadata.rst.txt b/docs/api/python/sources/auto_examples/plot_metadata.rst.txt index 8dd7067d02914..52e8201fc7122 100644 --- a/docs/api/python/sources/auto_examples/plot_metadata.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_metadata.rst.txt @@ -29,15 +29,17 @@ Let's see how to do that with a simple logistic regression model trained with *scikit-learn* and converted with *sklearn-onnx*. -.. GENERATED FROM PYTHON SOURCE LINES 16-31 +.. GENERATED FROM PYTHON SOURCE LINES 16-33 .. code-block:: default from onnxruntime.datasets import get_example + example = get_example("logreg_iris.onnx") import onnx + model = onnx.load(example) print("doc_string={}".format(model.doc_string)) @@ -54,8 +56,6 @@ logistic regression model trained with .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none doc_string= @@ -69,16 +69,17 @@ logistic regression model trained with -.. GENERATED FROM PYTHON SOURCE LINES 32-33 +.. GENERATED FROM PYTHON SOURCE LINES 34-35 With *ONNX Runtime*: -.. GENERATED FROM PYTHON SOURCE LINES 33-44 +.. GENERATED FROM PYTHON SOURCE LINES 35-47 .. code-block:: default import onnxruntime as rt + sess = rt.InferenceSession(example, providers=rt.get_available_providers()) meta = sess.get_modelmeta() @@ -94,8 +95,6 @@ With *ONNX Runtime*: .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none custom_metadata_map={} @@ -111,28 +110,23 @@ With *ONNX Runtime*: .. rst-class:: sphx-glr-timing - **Total running time of the script:** ( 0 minutes 0.005 seconds) + **Total running time of the script:** ( 0 minutes 0.003 seconds) .. _sphx_glr_download_auto_examples_plot_metadata.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_metadata.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_metadata.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_metadata.ipynb ` + :download:`Download Jupyter notebook: plot_metadata.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_pipeline.rst.txt b/docs/api/python/sources/auto_examples/plot_pipeline.rst.txt index c71429c4141c0..d0e0bb5627078 100644 --- a/docs/api/python/sources/auto_examples/plot_pipeline.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_pipeline.rst.txt @@ -35,18 +35,20 @@ Retrieve a model in JSON format That's the most simple way. -.. GENERATED FROM PYTHON SOURCE LINES 22-32 +.. GENERATED FROM PYTHON SOURCE LINES 22-34 .. code-block:: default from onnxruntime.datasets import get_example + example1 = get_example("mul_1.onnx") import onnx + model = onnx.load(example1) # model is a ModelProto protobuf message - print(model) + print(model) @@ -55,8 +57,6 @@ That's the most simple way. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none ir_version: 3 @@ -124,7 +124,7 @@ That's the most simple way. -.. GENERATED FROM PYTHON SOURCE LINES 33-39 +.. GENERATED FROM PYTHON SOURCE LINES 35-41 Draw a model with ONNX ++++++++++++++++++++++ @@ -133,15 +133,16 @@ included in *onnx* package. We use *onnx* to load the model in a different way than before. -.. GENERATED FROM PYTHON SOURCE LINES 39-47 +.. GENERATED FROM PYTHON SOURCE LINES 41-50 .. code-block:: default from onnx import ModelProto + model = ModelProto() - with open(example1, 'rb') as fid: + with open(example1, "rb") as fid: content = fid.read() model.ParseFromString(content) @@ -152,17 +153,19 @@ in a different way than before. -.. GENERATED FROM PYTHON SOURCE LINES 48-49 +.. GENERATED FROM PYTHON SOURCE LINES 51-52 We convert it into a graph. -.. GENERATED FROM PYTHON SOURCE LINES 49-54 +.. GENERATED FROM PYTHON SOURCE LINES 52-59 .. code-block:: default - from onnx.tools.net_drawer import GetPydotGraph, GetOpNodeProducer - pydot_graph = GetPydotGraph(model.graph, name=model.graph.name, rankdir="LR", - node_producer=GetOpNodeProducer("docstring")) + from onnx.tools.net_drawer import GetOpNodeProducer, GetPydotGraph + + pydot_graph = GetPydotGraph( + model.graph, name=model.graph.name, rankdir="LR", node_producer=GetOpNodeProducer("docstring") + ) pydot_graph.write_dot("graph.dot") @@ -172,24 +175,23 @@ We convert it into a graph. -.. GENERATED FROM PYTHON SOURCE LINES 55-56 +.. GENERATED FROM PYTHON SOURCE LINES 60-61 Then into an image -.. GENERATED FROM PYTHON SOURCE LINES 56-59 +.. GENERATED FROM PYTHON SOURCE LINES 61-65 .. code-block:: default import os - os.system('dot -O -Tpng graph.dot') + os.system("dot -O -Tpng graph.dot") -.. rst-class:: sphx-glr-script-out - Out: +.. rst-class:: sphx-glr-script-out .. code-block:: none @@ -198,26 +200,21 @@ Then into an image -.. GENERATED FROM PYTHON SOURCE LINES 60-61 +.. GENERATED FROM PYTHON SOURCE LINES 66-67 Which we display... -.. GENERATED FROM PYTHON SOURCE LINES 61-70 +.. GENERATED FROM PYTHON SOURCE LINES 67-71 .. code-block:: default import matplotlib.pyplot as plt + image = plt.imread("graph.dot.png") plt.imshow(image) - - - - - - .. image-sg:: /auto_examples/images/sphx_glr_plot_pipeline_001.png :alt: plot pipeline :srcset: /auto_examples/images/sphx_glr_plot_pipeline_001.png @@ -226,40 +223,33 @@ Which we display... .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - + .. rst-class:: sphx-glr-timing - **Total running time of the script:** ( 0 minutes 0.196 seconds) + **Total running time of the script:** ( 0 minutes 0.218 seconds) .. _sphx_glr_download_auto_examples_plot_pipeline.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_pipeline.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_pipeline.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_pipeline.ipynb ` + :download:`Download Jupyter notebook: plot_pipeline.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_profiling.rst.txt b/docs/api/python/sources/auto_examples/plot_profiling.rst.txt index b5042b610ddd2..5bfc305bd1a55 100644 --- a/docs/api/python/sources/auto_examples/plot_profiling.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_profiling.rst.txt @@ -26,13 +26,14 @@ Profile the execution of a simple model *ONNX Runtime* can profile the execution of the model. This example shows how to interpret the results. -.. GENERATED FROM PYTHON SOURCE LINES 14-32 +.. GENERATED FROM PYTHON SOURCE LINES 14-31 .. code-block:: default + import numpy import onnx + import onnxruntime as rt - import numpy from onnxruntime.datasets import get_example @@ -53,13 +54,11 @@ This example shows how to interpret the results. - - -.. GENERATED FROM PYTHON SOURCE LINES 33-34 +.. GENERATED FROM PYTHON SOURCE LINES 32-33 Let's load a very simple model and compute some prediction. -.. GENERATED FROM PYTHON SOURCE LINES 34-45 +.. GENERATED FROM PYTHON SOURCE LINES 33-44 .. code-block:: default @@ -80,8 +79,6 @@ Let's load a very simple model and compute some prediction. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none [array([[ 1., 4.], @@ -91,12 +88,12 @@ Let's load a very simple model and compute some prediction. -.. GENERATED FROM PYTHON SOURCE LINES 46-48 +.. GENERATED FROM PYTHON SOURCE LINES 45-47 We need to enable to profiling before running the predictions. -.. GENERATED FROM PYTHON SOURCE LINES 48-60 +.. GENERATED FROM PYTHON SOURCE LINES 47-59 .. code-block:: default @@ -118,58 +115,53 @@ before running the predictions. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - onnxruntime_profile__2022-01-04_17-09-55.json + onnxruntime_profile__2022-08-16_04-44-08.json -.. GENERATED FROM PYTHON SOURCE LINES 61-63 +.. GENERATED FROM PYTHON SOURCE LINES 60-62 The results are stored un a file in JSON format. Let's see what it contains. -.. GENERATED FROM PYTHON SOURCE LINES 63-71 +.. GENERATED FROM PYTHON SOURCE LINES 62-69 .. code-block:: default import json + with open(prof_file, "r") as f: sess_time = json.load(f) import pprint - pprint.pprint(sess_time) - - + pprint.pprint(sess_time) .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none [{'args': {}, 'cat': 'Session', - 'dur': 56, + 'dur': 67, 'name': 'model_loading_array', 'ph': 'X', - 'pid': 3089, - 'tid': 3089, + 'pid': 3111, + 'tid': 3111, 'ts': 1}, {'args': {}, 'cat': 'Session', - 'dur': 240, + 'dur': 236, 'name': 'session_initialization', 'ph': 'X', - 'pid': 3089, - 'tid': 3089, - 'ts': 71}] + 'pid': 3111, + 'tid': 3111, + 'ts': 85}] @@ -177,28 +169,23 @@ Let's see what it contains. .. rst-class:: sphx-glr-timing - **Total running time of the script:** ( 0 minutes 0.007 seconds) + **Total running time of the script:** ( 0 minutes 0.005 seconds) .. _sphx_glr_download_auto_examples_plot_profiling.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_profiling.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_profiling.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_profiling.ipynb ` + :download:`Download Jupyter notebook: plot_profiling.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/plot_train_convert_predict.rst.txt b/docs/api/python/sources/auto_examples/plot_train_convert_predict.rst.txt index 1eee02ac44ada..92eba06dd1d1d 100644 --- a/docs/api/python/sources/auto_examples/plot_train_convert_predict.rst.txt +++ b/docs/api/python/sources/auto_examples/plot_train_convert_predict.rst.txt @@ -35,16 +35,18 @@ Train a logistic regression The first step consists in retrieving the iris datset. -.. GENERATED FROM PYTHON SOURCE LINES 23-31 +.. GENERATED FROM PYTHON SOURCE LINES 23-33 .. code-block:: default from sklearn.datasets import load_iris + iris = load_iris() X, y = iris.data, iris.target from sklearn.model_selection import train_test_split + X_train, X_test, y_train, y_test = train_test_split(X, y) @@ -54,16 +56,17 @@ The first step consists in retrieving the iris datset. -.. GENERATED FROM PYTHON SOURCE LINES 32-33 +.. GENERATED FROM PYTHON SOURCE LINES 34-35 Then we fit a model. -.. GENERATED FROM PYTHON SOURCE LINES 33-38 +.. GENERATED FROM PYTHON SOURCE LINES 35-41 .. code-block:: default from sklearn.linear_model import LogisticRegression + clr = LogisticRegression() clr.fit(X_train, y_train) @@ -71,23 +74,21 @@ Then we fit a model. -.. rst-class:: sphx-glr-script-out - - Out: - .. code-block:: none +.. raw:: html +
          +
          LogisticRegression()
          In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
          On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
          +
          +
          +
          - LogisticRegression() - - - -.. GENERATED FROM PYTHON SOURCE LINES 39-41 +.. GENERATED FROM PYTHON SOURCE LINES 42-44 We compute the prediction on the test set and we show the confusion matrix. -.. GENERATED FROM PYTHON SOURCE LINES 41-46 +.. GENERATED FROM PYTHON SOURCE LINES 44-49 .. code-block:: default @@ -102,27 +103,25 @@ and we show the confusion matrix. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - [[13 0 0] + [[17 0 0] [ 0 10 1] - [ 0 0 14]] + [ 0 0 10]] -.. GENERATED FROM PYTHON SOURCE LINES 47-53 +.. GENERATED FROM PYTHON SOURCE LINES 50-56 Conversion to ONNX format +++++++++++++++++++++++++ -We use module +We use module `sklearn-onnx `_ to convert the model into ONNX format. -.. GENERATED FROM PYTHON SOURCE LINES 53-62 +.. GENERATED FROM PYTHON SOURCE LINES 56-65 .. code-block:: default @@ -130,7 +129,7 @@ to convert the model into ONNX format. from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType - initial_type = [('float_input', FloatTensorType([None, 4]))] + initial_type = [("float_input", FloatTensorType([None, 4]))] onx = convert_sklearn(clr, initial_types=initial_type) with open("logreg_iris.onnx", "wb") as f: f.write(onx.SerializeToString()) @@ -142,23 +141,22 @@ to convert the model into ONNX format. -.. GENERATED FROM PYTHON SOURCE LINES 63-65 +.. GENERATED FROM PYTHON SOURCE LINES 66-68 We load the model with ONNX Runtime and look at its input and output. -.. GENERATED FROM PYTHON SOURCE LINES 65-74 +.. GENERATED FROM PYTHON SOURCE LINES 68-76 .. code-block:: default import onnxruntime as rt + sess = rt.InferenceSession("logreg_iris.onnx", providers=rt.get_available_providers()) - print("input name='{}' and shape={}".format( - sess.get_inputs()[0].name, sess.get_inputs()[0].shape)) - print("output name='{}' and shape={}".format( - sess.get_outputs()[0].name, sess.get_outputs()[0].shape)) + print("input name='{}' and shape={}".format(sess.get_inputs()[0].name, sess.get_inputs()[0].shape)) + print("output name='{}' and shape={}".format(sess.get_outputs()[0].name, sess.get_outputs()[0].shape)) @@ -166,8 +164,6 @@ its input and output. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none input name='float_input' and shape=[None, 4] @@ -176,11 +172,11 @@ its input and output. -.. GENERATED FROM PYTHON SOURCE LINES 75-76 +.. GENERATED FROM PYTHON SOURCE LINES 77-78 We compute the predictions. -.. GENERATED FROM PYTHON SOURCE LINES 76-84 +.. GENERATED FROM PYTHON SOURCE LINES 78-87 .. code-block:: default @@ -189,6 +185,7 @@ We compute the predictions. label_name = sess.get_outputs()[0].name import numpy + pred_onx = sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0] print(confusion_matrix(pred, pred_onx)) @@ -198,18 +195,16 @@ We compute the predictions. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - [[13 0 0] + [[17 0 0] [ 0 10 0] - [ 0 0 15]] + [ 0 0 11]] -.. GENERATED FROM PYTHON SOURCE LINES 85-94 +.. GENERATED FROM PYTHON SOURCE LINES 88-97 The prediction are perfectly identical. @@ -221,7 +216,7 @@ relevant metrics such as the ROC Curve. Let's see how to get them first with scikit-learn. -.. GENERATED FROM PYTHON SOURCE LINES 94-98 +.. GENERATED FROM PYTHON SOURCE LINES 97-101 .. code-block:: default @@ -235,23 +230,21 @@ scikit-learn. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - [[2.95951945e-05 5.69800366e-02 9.42990368e-01] - [1.84923705e-05 3.93636566e-02 9.60617851e-01] - [1.30004554e-02 8.03678159e-01 1.83321386e-01]] + [[1.82164782e-01 8.13598178e-01 4.23703980e-03] + [8.12021102e-04 3.37134524e-01 6.62053455e-01] + [1.20249493e-06 1.74038501e-02 9.82594947e-01]] -.. GENERATED FROM PYTHON SOURCE LINES 99-101 +.. GENERATED FROM PYTHON SOURCE LINES 102-104 And then with ONNX Runtime. -The probabilies appear to be +The probabilies appear to be -.. GENERATED FROM PYTHON SOURCE LINES 101-108 +.. GENERATED FROM PYTHON SOURCE LINES 104-112 .. code-block:: default @@ -260,6 +253,7 @@ The probabilies appear to be prob_rt = sess.run([prob_name], {input_name: X_test.astype(numpy.float32)})[0] import pprint + pprint.pprint(prob_rt[0:3]) @@ -268,27 +262,26 @@ The probabilies appear to be .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none - [{0: 2.9595235901069827e-05, 1: 0.05698008090257645, 2: 0.9429903030395508}, - {0: 1.8492364688427188e-05, 1: 0.03936365991830826, 2: 0.9606178402900696}, - {0: 0.013000461272895336, 1: 0.8036782741546631, 2: 0.1833212822675705}] + [{0: 0.18216472864151, 1: 0.8135982751846313, 2: 0.0042370399460196495}, + {0: 0.0008120210259221494, 1: 0.3371346592903137, 2: 0.6620532870292664}, + {0: 1.2024959232803667e-06, 1: 0.01740385964512825, 2: 0.9825949668884277}] -.. GENERATED FROM PYTHON SOURCE LINES 109-110 +.. GENERATED FROM PYTHON SOURCE LINES 113-114 Let's benchmark. -.. GENERATED FROM PYTHON SOURCE LINES 110-126 +.. GENERATED FROM PYTHON SOURCE LINES 114-132 .. code-block:: default from timeit import Timer + def speed(inst, number=10, repeat=20): timer = Timer(inst, globals=globals()) raw = numpy.array(timer.repeat(repeat, number=number)) @@ -297,6 +290,7 @@ Let's benchmark. print("Average %1.3g min=%1.3g max=%1.3g" % (ave, mi, ma)) return ave + print("Execution time for clr.predict") speed("clr.predict(X_test)") @@ -309,44 +303,46 @@ Let's benchmark. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none Execution time for clr.predict - Average 4.38e-05 min=4.25e-05 max=6.07e-05 + Average 4.46e-05 min=4.3e-05 max=5.6e-05 Execution time for ONNX Runtime - Average 1.97e-05 min=1.92e-05 max=2.46e-05 + Average 1.84e-05 min=1.78e-05 max=2.5e-05 - 1.9671264999914226e-05 + 1.838059500016698e-05 -.. GENERATED FROM PYTHON SOURCE LINES 127-130 +.. GENERATED FROM PYTHON SOURCE LINES 133-136 Let's benchmark a scenario similar to what a webservice experiences: the model has to do one prediction at a time as opposed to a batch of prediction. -.. GENERATED FROM PYTHON SOURCE LINES 130-148 +.. GENERATED FROM PYTHON SOURCE LINES 136-158 .. code-block:: default + def loop(X_test, fct, n=None): nrow = X_test.shape[0] if n is None: n = nrow for i in range(0, n): im = i % nrow - fct(X_test[im: im+1]) + fct(X_test[im : im + 1]) + print("Execution time for clr.predict") speed("loop(X_test, clr.predict, 100)") + def sess_predict(x): return sess.run([label_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for sess_predict") speed("loop(X_test, sess_predict, 100)") @@ -356,24 +352,22 @@ as opposed to a batch of prediction. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none Execution time for clr.predict - Average 0.00404 min=0.00402 max=0.00409 + Average 0.0042 min=0.00418 max=0.00428 Execution time for sess_predict - Average 0.000881 min=0.000874 max=0.000912 + Average 0.000862 min=0.000856 max=0.000878 - 0.0008813192099997735 + 0.0008617829299998903 -.. GENERATED FROM PYTHON SOURCE LINES 149-150 +.. GENERATED FROM PYTHON SOURCE LINES 159-160 Let's do the same for the probabilities. -.. GENERATED FROM PYTHON SOURCE LINES 150-160 +.. GENERATED FROM PYTHON SOURCE LINES 160-172 .. code-block:: default @@ -381,9 +375,11 @@ Let's do the same for the probabilities. print("Execution time for predict_proba") speed("loop(X_test, clr.predict_proba, 100)") + def sess_predict_proba(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for sess_predict_proba") speed("loop(X_test, sess_predict_proba, 100)") @@ -393,42 +389,41 @@ Let's do the same for the probabilities. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none Execution time for predict_proba - Average 0.00599 min=0.00597 max=0.00606 + Average 0.00617 min=0.00615 max=0.0062 Execution time for sess_predict_proba - Average 0.000883 min=0.000876 max=0.000916 + Average 0.000887 min=0.00088 max=0.000915 - 0.0008830492349999729 + 0.0008867338849996997 -.. GENERATED FROM PYTHON SOURCE LINES 161-165 +.. GENERATED FROM PYTHON SOURCE LINES 173-177 -This second comparison is better as +This second comparison is better as ONNX Runtime, in this experience, computes the label and the probabilities in every case. -.. GENERATED FROM PYTHON SOURCE LINES 167-171 +.. GENERATED FROM PYTHON SOURCE LINES 179-183 Benchmark with RandomForest +++++++++++++++++++++++++++ We first train and save a model in ONNX format. -.. GENERATED FROM PYTHON SOURCE LINES 171-180 +.. GENERATED FROM PYTHON SOURCE LINES 183-193 .. code-block:: default from sklearn.ensemble import RandomForestClassifier + rf = RandomForestClassifier() rf.fit(X_train, y_train) - initial_type = [('float_input', FloatTensorType([1, 4]))] + initial_type = [("float_input", FloatTensorType([1, 4]))] onx = convert_sklearn(rf, initial_types=initial_type) with open("rf_iris.onnx", "wb") as f: f.write(onx.SerializeToString()) @@ -440,20 +435,22 @@ We first train and save a model in ONNX format. -.. GENERATED FROM PYTHON SOURCE LINES 181-182 +.. GENERATED FROM PYTHON SOURCE LINES 194-195 We compare. -.. GENERATED FROM PYTHON SOURCE LINES 182-194 +.. GENERATED FROM PYTHON SOURCE LINES 195-209 .. code-block:: default sess = rt.InferenceSession("rf_iris.onnx", providers=rt.get_available_providers()) + def sess_predict_proba_rf(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + print("Execution time for predict_proba") speed("loop(X_test, rf.predict_proba, 100)") @@ -466,50 +463,50 @@ We compare. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none Execution time for predict_proba - Average 0.717 min=0.715 max=0.72 + Average 0.723 min=0.721 max=0.729 Execution time for sess_predict_proba - Average 0.00108 min=0.00107 max=0.00111 + Average 0.00103 min=0.00102 max=0.00106 - 0.0010817126199989956 + 0.0010315913400006592 -.. GENERATED FROM PYTHON SOURCE LINES 195-196 +.. GENERATED FROM PYTHON SOURCE LINES 210-211 Let's see with different number of trees. -.. GENERATED FROM PYTHON SOURCE LINES 196-223 +.. GENERATED FROM PYTHON SOURCE LINES 211-240 .. code-block:: default measures = [] - for n_trees in range(5, 51, 5): + for n_trees in range(5, 51, 5): print(n_trees) rf = RandomForestClassifier(n_estimators=n_trees) rf.fit(X_train, y_train) - initial_type = [('float_input', FloatTensorType([1, 4]))] + initial_type = [("float_input", FloatTensorType([1, 4]))] onx = convert_sklearn(rf, initial_types=initial_type) with open("rf_iris_%d.onnx" % n_trees, "wb") as f: f.write(onx.SerializeToString()) sess = rt.InferenceSession("rf_iris_%d.onnx" % n_trees, providers=rt.get_available_providers()) + def sess_predict_proba_loop(x): return sess.run([prob_name], {input_name: x.astype(numpy.float32)})[0] + tsk = speed("loop(X_test, rf.predict_proba, 100)", number=5, repeat=5) trt = speed("loop(X_test, sess_predict_proba_loop, 100)", number=5, repeat=5) - measures.append({'n_trees': n_trees, 'sklearn': tsk, 'rt': trt}) + measures.append({"n_trees": n_trees, "sklearn": tsk, "rt": trt}) from pandas import DataFrame + df = DataFrame(measures) ax = df.plot(x="n_trees", y="sklearn", label="scikit-learn", c="blue", logy=True) - df.plot(x="n_trees", y="rt", label="onnxruntime", - ax=ax, c="green", logy=True) + df.plot(x="n_trees", y="rt", label="onnxruntime", ax=ax, c="green", logy=True) ax.set_xlabel("Number of trees") ax.set_ylabel("Prediction time (s)") ax.set_title("Speed comparison between scikit-learn and ONNX Runtime\nFor a random forest on Iris dataset") @@ -525,70 +522,63 @@ Let's see with different number of trees. .. rst-class:: sphx-glr-script-out - Out: - .. code-block:: none 5 - Average 0.0637 min=0.0636 max=0.0639 - Average 0.000869 min=0.000857 max=0.000899 + Average 0.0519 min=0.0519 max=0.0521 + Average 0.000867 min=0.000856 max=0.000898 10 - Average 0.0982 min=0.098 max=0.0987 - Average 0.000884 min=0.000873 max=0.00091 + Average 0.0872 min=0.0871 max=0.0875 + Average 0.000881 min=0.000877 max=0.000893 15 - Average 0.133 min=0.133 max=0.133 - Average 0.000895 min=0.000885 max=0.000921 + Average 0.123 min=0.122 max=0.123 + Average 0.000908 min=0.000896 max=0.000938 20 - Average 0.168 min=0.167 max=0.168 - Average 0.000915 min=0.000907 max=0.00094 + Average 0.158 min=0.158 max=0.158 + Average 0.000902 min=0.000896 max=0.000918 25 - Average 0.202 min=0.201 max=0.203 - Average 0.000921 min=0.000913 max=0.000948 + Average 0.193 min=0.193 max=0.193 + Average 0.000929 min=0.000914 max=0.000961 30 - Average 0.236 min=0.236 max=0.237 - Average 0.000922 min=0.000914 max=0.000948 + Average 0.228 min=0.228 max=0.229 + Average 0.000927 min=0.000915 max=0.000948 35 - Average 0.271 min=0.271 max=0.271 - Average 0.000941 min=0.000928 max=0.000967 + Average 0.263 min=0.263 max=0.264 + Average 0.000946 min=0.000935 max=0.000978 40 - Average 0.305 min=0.305 max=0.305 - Average 0.000948 min=0.000934 max=0.000977 + Average 0.298 min=0.298 max=0.299 + Average 0.000952 min=0.000943 max=0.000972 45 - Average 0.34 min=0.339 max=0.34 - Average 0.000983 min=0.000972 max=0.00101 + Average 0.334 min=0.333 max=0.335 + Average 0.000953 min=0.000943 max=0.000985 50 - Average 0.375 min=0.374 max=0.375 - Average 0.000972 min=0.000966 max=0.000992 + Average 0.369 min=0.369 max=0.371 + Average 0.000981 min=0.000973 max=0.00101 - + .. rst-class:: sphx-glr-timing - **Total running time of the script:** ( 3 minutes 22.159 seconds) + **Total running time of the script:** ( 3 minutes 21.167 seconds) .. _sphx_glr_download_auto_examples_plot_train_convert_predict.py: +.. only:: html -.. only :: html - - .. container:: sphx-glr-footer - :class: sphx-glr-footer-example - - - - .. container:: sphx-glr-download sphx-glr-download-python + .. container:: sphx-glr-footer sphx-glr-footer-example - :download:`Download Python source code: plot_train_convert_predict.py ` + .. container:: sphx-glr-download sphx-glr-download-python + :download:`Download Python source code: plot_train_convert_predict.py ` - .. container:: sphx-glr-download sphx-glr-download-jupyter + .. container:: sphx-glr-download sphx-glr-download-jupyter - :download:`Download Jupyter notebook: plot_train_convert_predict.ipynb ` + :download:`Download Jupyter notebook: plot_train_convert_predict.ipynb ` .. only:: html diff --git a/docs/api/python/sources/auto_examples/sg_execution_times.rst.txt b/docs/api/python/sources/auto_examples/sg_execution_times.rst.txt index 12734e94e72c0..05223095e6584 100644 --- a/docs/api/python/sources/auto_examples/sg_execution_times.rst.txt +++ b/docs/api/python/sources/auto_examples/sg_execution_times.rst.txt @@ -5,22 +5,22 @@ Computation times ================= -**03:23.370** total execution time for **auto_examples** files: +**03:22.379** total execution time for **auto_examples** files: +-------------------------------------------------------------------------------------------------------------+-----------+--------+ -| :ref:`sphx_glr_auto_examples_plot_train_convert_predict.py` (``plot_train_convert_predict.py``) | 03:22.159 | 0.0 MB | +| :ref:`sphx_glr_auto_examples_plot_train_convert_predict.py` (``plot_train_convert_predict.py``) | 03:21.167 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ -| :ref:`sphx_glr_auto_examples_plot_convert_pipeline_vectorizer.py` (``plot_convert_pipeline_vectorizer.py``) | 00:00.966 | 0.0 MB | +| :ref:`sphx_glr_auto_examples_plot_convert_pipeline_vectorizer.py` (``plot_convert_pipeline_vectorizer.py``) | 00:00.956 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ -| :ref:`sphx_glr_auto_examples_plot_pipeline.py` (``plot_pipeline.py``) | 00:00.196 | 0.0 MB | +| :ref:`sphx_glr_auto_examples_plot_pipeline.py` (``plot_pipeline.py``) | 00:00.218 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ | :ref:`sphx_glr_auto_examples_plot_backend.py` (``plot_backend.py``) | 00:00.014 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ -| :ref:`sphx_glr_auto_examples_plot_load_and_predict.py` (``plot_load_and_predict.py``) | 00:00.013 | 0.0 MB | -+-------------------------------------------------------------------------------------------------------------+-----------+--------+ | :ref:`sphx_glr_auto_examples_plot_common_errors.py` (``plot_common_errors.py``) | 00:00.009 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ -| :ref:`sphx_glr_auto_examples_plot_profiling.py` (``plot_profiling.py``) | 00:00.007 | 0.0 MB | +| :ref:`sphx_glr_auto_examples_plot_load_and_predict.py` (``plot_load_and_predict.py``) | 00:00.007 | 0.0 MB | ++-------------------------------------------------------------------------------------------------------------+-----------+--------+ +| :ref:`sphx_glr_auto_examples_plot_profiling.py` (``plot_profiling.py``) | 00:00.005 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ -| :ref:`sphx_glr_auto_examples_plot_metadata.py` (``plot_metadata.py``) | 00:00.005 | 0.0 MB | +| :ref:`sphx_glr_auto_examples_plot_metadata.py` (``plot_metadata.py``) | 00:00.003 | 0.0 MB | +-------------------------------------------------------------------------------------------------------------+-----------+--------+ diff --git a/docs/api/python/static/_sphinx_javascript_frameworks_compat.js b/docs/api/python/static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000000000..8549469dc29fa --- /dev/null +++ b/docs/api/python/static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,134 @@ +/* + * _sphinx_javascript_frameworks_compat.js + * ~~~~~~~~~~ + * + * Compatability shim for jQuery and underscores.js. + * + * WILL BE REMOVED IN Sphinx 6.0 + * xref RemovedInSphinx60Warning + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/api/python/static/basic.css b/docs/api/python/static/basic.css index 603f6a8798e7f..eeb0519a69bac 100644 --- a/docs/api/python/static/basic.css +++ b/docs/api/python/static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -222,7 +222,7 @@ table.modindextable td { /* -- general body styles --------------------------------------------------- */ div.body { - min-width: 450px; + min-width: 360px; max-width: 800px; } @@ -236,7 +236,6 @@ div.body p, div.body dd, div.body li, div.body blockquote { a.headerlink { visibility: hidden; } - a.brackets:before, span.brackets > a:before{ content: "["; @@ -247,6 +246,7 @@ span.brackets > a:after { content: "]"; } + h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -334,13 +334,11 @@ aside.sidebar { p.sidebar-title { font-weight: bold; } - div.admonition, div.topic, blockquote { clear: left; } /* -- topics ---------------------------------------------------------------- */ - div.topic { border: 1px solid #ccc; padding: 7px; @@ -428,10 +426,6 @@ table.docutils td, table.docutils th { border-bottom: 1px solid #aaa; } -table.footnote td, table.footnote th { - border: 0 !important; -} - th { text-align: left; padding-right: 5px; @@ -614,7 +608,6 @@ ol.simple p, ul.simple p { margin-bottom: 0; } - dl.footnote > dt, dl.citation > dt { float: left; @@ -643,11 +636,11 @@ dl.field-list > dt { padding-left: 0.5em; padding-right: 5px; } - dl.field-list > dt:after { content: ":"; } + dl.field-list > dd { padding-left: 0.5em; margin-top: 0em; @@ -757,6 +750,7 @@ span.pre { -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; + white-space: nowrap; } div[class*="highlight-"] { diff --git a/docs/api/python/static/doctools.js b/docs/api/python/static/doctools.js index 8cbf1b161a652..c3db08d1c3896 100644 --- a/docs/api/python/static/doctools.js +++ b/docs/api/python/static/doctools.js @@ -2,322 +2,263 @@ * doctools.js * ~~~~~~~~~~~ * - * Sphinx JavaScript utilities for all documentation. + * Base JavaScript utilities for all Sphinx HTML documentation. * - * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ +"use strict"; -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - * - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL - */ -jQuery.urldecode = function(x) { - if (!x) { - return x +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); } - return decodeURIComponent(x.replace(/\+/g, ' ')); }; /** - * small helper function to urlencode strings + * highlight a given string on a node by wrapping it in + * span elements with the given class name. */ -jQuery.urlencode = encodeURIComponent; +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && - !jQuery(node.parentNode).hasClass(className) && - !jQuery(node.parentNode).hasClass("nohighlight")) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - var bbox = node.parentElement.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); } } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this, addItems); - }); - } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); - }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; }; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; /** * Small JavaScript module for the documentation. */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { - this.initOnKeyListeners(); - } +const Documentation = { + init: () => { + Documentation.highlightSearchWords(); + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); }, /** * i18n support */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, - LOCALE : 'unknown', + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated === 'undefined') - return string; - return (typeof translated === 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated === 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } }, - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; }, - /** - * workaround a firefox stupidity - * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; }, /** * highlight the search words provided in the url in the text */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - if (!body.length) { - body = $('body'); - } - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, + highlightSearchWords: () => { + const highlight = + new URLSearchParams(window.location.search).get("highlight") || ""; + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) === 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); }, /** * helper function to hide the search marks again */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + const url = new URL(window.location); + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); }, /** - * make the url absolute + * helper function to focus on search bar */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); }, /** - * get the current relative url + * Initialise the domain index toggle buttons */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this === '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); }, - initOnKeyListeners: function() { - $(document).keydown(function(event) { - var activeElementType = document.activeElement.tagName; - // don't navigate when in search box, textarea, dropdown or button - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' - && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey - && !event.shiftKey) { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + const blacklistedElements = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", + ]); + document.addEventListener("keydown", (event) => { + if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements + if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); } break; - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); } break; + case "Escape": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.hideSearchWords(); + event.preventDefault(); } } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } }); - } + }, }; // quick alias for translations -_ = Documentation.gettext; +const _ = Documentation.gettext; -$(document).ready(function() { - Documentation.init(); -}); +_ready(Documentation.init); diff --git a/docs/api/python/static/documentation_options.js b/docs/api/python/static/documentation_options.js index b5bc969fa9035..52b4ddafe8d93 100644 --- a/docs/api/python/static/documentation_options.js +++ b/docs/api/python/static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '1.11.0', + VERSION: '1.13.0', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', @@ -8,5 +8,7 @@ var DOCUMENTATION_OPTIONS = { LINK_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: false + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, }; \ No newline at end of file diff --git a/docs/api/python/static/graphviz.css b/docs/api/python/static/graphviz.css index b340734c742f5..19e7afd385bed 100644 --- a/docs/api/python/static/graphviz.css +++ b/docs/api/python/static/graphviz.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- graphviz extension. * - * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/docs/api/python/static/jquery-3.5.1.js b/docs/api/python/static/jquery-3.6.0.js similarity index 98% rename from docs/api/python/static/jquery-3.5.1.js rename to docs/api/python/static/jquery-3.6.0.js index 50937333b99a5..fc6c299b73e79 100644 --- a/docs/api/python/static/jquery-3.5.1.js +++ b/docs/api/python/static/jquery-3.6.0.js @@ -1,15 +1,15 @@ /*! - * jQuery JavaScript Library v3.5.1 + * jQuery JavaScript Library v3.6.0 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * - * Copyright JS Foundation and other contributors + * Copyright OpenJS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * - * Date: 2020-05-04T22:49Z + * Date: 2021-03-02T17:08Z */ ( function( global, factory ) { @@ -76,12 +76,16 @@ var support = {}; var isFunction = function isFunction( obj ) { - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; var isWindow = function isWindow( obj ) { @@ -147,7 +151,7 @@ function toType( obj ) { var - version = "3.5.1", + version = "3.6.0", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -401,7 +405,7 @@ jQuery.extend( { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? - [ arr ] : arr + [ arr ] : arr ); } else { push.call( ret, arr ); @@ -496,9 +500,9 @@ if ( typeof Symbol === "function" ) { // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); function isArrayLike( obj ) { @@ -518,14 +522,14 @@ function isArrayLike( obj ) { } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.3.5 + * Sizzle CSS Selector Engine v2.3.6 * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://js.foundation/ * - * Date: 2020-03-14 + * Date: 2021-02-16 */ ( function( window ) { var i, @@ -1108,8 +1112,8 @@ support = Sizzle.support = {}; * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { - var namespace = elem.namespaceURI, - docElem = ( elem.ownerDocument || elem ).documentElement; + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; // Support: IE <=8 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes @@ -3024,9 +3028,9 @@ var rneedsContext = jQuery.expr.match.needsContext; function nodeName( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); -}; +} var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); @@ -3997,8 +4001,8 @@ jQuery.extend( { resolveContexts = Array( i ), resolveValues = slice.call( arguments ), - // the master Deferred - master = jQuery.Deferred(), + // the primary Deferred + primary = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { @@ -4006,30 +4010,30 @@ jQuery.extend( { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { - master.resolveWith( resolveContexts, resolveValues ); + primary.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { - adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, !remaining ); // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( master.state() === "pending" || + if ( primary.state() === "pending" || isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - return master.then(); + return primary.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); } - return master.promise(); + return primary.promise(); } } ); @@ -4180,8 +4184,8 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } @@ -5089,10 +5093,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) { } -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; @@ -5387,8 +5388,8 @@ jQuery.event = { event = jQuery.event.fix( nativeEvent ), handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event @@ -5512,12 +5513,12 @@ jQuery.event = { get: isFunction( hook ) ? function() { if ( this.originalEvent ) { - return hook( this.originalEvent ); + return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { - return this.originalEvent[ name ]; + return this.originalEvent[ name ]; } }, @@ -5656,7 +5657,13 @@ function leverageNative( el, type, expectSync ) { // Cancel the outer synthetic event event.stopImmediatePropagation(); event.preventDefault(); - return result.value; + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; } // If this is an inner synthetic event for an event with a bubbling surrogate @@ -5821,34 +5828,7 @@ jQuery.each( { targetTouches: true, toElement: true, touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } - - if ( button & 2 ) { - return 3; - } - - if ( button & 4 ) { - return 2; - } - - return 0; - } - - return event.which; - } + which: true }, jQuery.event.addProp ); jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { @@ -5874,6 +5854,12 @@ jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateTyp return true; }, + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + delegateType: delegateType }; } ); @@ -6541,6 +6527,10 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); // set in CSS while `offset*` properties report correct values. // Behavior in IE 9 is more subtle than in newer versions & it passes // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) reliableTrDimensions: function() { var table, tr, trChild, trStyle; if ( reliableTrDimensionsVal == null ) { @@ -6548,17 +6538,32 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); tr = document.createElement( "tr" ); trChild = document.createElement( "div" ); - table.style.cssText = "position:absolute;left:-11111px"; + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. tr.style.height = "1px"; trChild.style.height = "9px"; + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + documentElement .appendChild( table ) .appendChild( tr ) .appendChild( trChild ); trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; documentElement.removeChild( table ); } @@ -7022,10 +7027,10 @@ jQuery.each( [ "height", "width" ], function( _i, dimension ) { // Running getBoundingClientRect on a disconnected node // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); } }, @@ -7084,7 +7089,7 @@ jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, swap( elem, { marginLeft: 0 }, function() { return elem.getBoundingClientRect().left; } ) - ) + "px"; + ) + "px"; } } ); @@ -7223,7 +7228,7 @@ Tween.propHooks = { if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || + jQuery.cssHooks[ tween.prop ] || tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { @@ -7468,7 +7473,7 @@ function defaultPrefilter( elem, props, opts ) { anim.done( function() { - /* eslint-enable no-loop-func */ + /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { @@ -7588,7 +7593,7 @@ function Animation( elem, properties, options ) { tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, @@ -7761,7 +7766,8 @@ jQuery.fn.extend( { anim.stop( true ); } }; - doAnimation.finish = doAnimation; + + doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : @@ -8401,8 +8407,8 @@ jQuery.fn.extend( { if ( this.setAttribute ) { this.setAttribute( "class", className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" + "" : + dataPriv.get( this, "__className__" ) || "" ); } } @@ -8417,7 +8423,7 @@ jQuery.fn.extend( { while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; + return true; } } @@ -8707,9 +8713,7 @@ jQuery.extend( jQuery.event, { special.bindType || type; // jQuery handler - handle = ( - dataPriv.get( cur, "events" ) || Object.create( null ) - )[ event.type ] && + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); @@ -8856,7 +8860,7 @@ var rquery = ( /\?/ ); // Cross-browser xml parsing jQuery.parseXML = function( data ) { - var xml; + var xml, parserErrorElem; if ( !data || typeof data !== "string" ) { return null; } @@ -8865,12 +8869,17 @@ jQuery.parseXML = function( data ) { // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } + } catch ( e ) {} - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); } return xml; }; @@ -8971,16 +8980,14 @@ jQuery.fn.extend( { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { + } ).filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( _i, elem ) { + } ).map( function( _i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { @@ -9033,7 +9040,8 @@ var // Anchor tag for parsing the document origin originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; + +originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -9414,8 +9422,8 @@ jQuery.extend( { // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, + jQuery( callbackContext ) : + jQuery.event, // Deferreds deferred = jQuery.Deferred(), @@ -9727,8 +9735,10 @@ jQuery.extend( { response = ajaxHandleResponses( s, jqXHR, responses ); } - // Use a noop converter for missing script - if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { s.converters[ "text script" ] = function() {}; } @@ -10466,12 +10476,6 @@ jQuery.offset = { options.using.call( elem, props ); } else { - if ( typeof props.top === "number" ) { - props.top += "px"; - } - if ( typeof props.left === "number" ) { - props.left += "px"; - } curElem.css( props ); } } @@ -10640,8 +10644,11 @@ jQuery.each( [ "top", "left" ], function( _i, prop ) { // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { - jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, - function( defaultExtra, funcName ) { + jQuery.each( { + padding: "inner" + name, + content: type, + "": "outer" + name + }, function( defaultExtra, funcName ) { // Margin is only for outerHeight, outerWidth jQuery.fn[ funcName ] = function( margin, value ) { @@ -10726,7 +10733,8 @@ jQuery.fn.extend( { } } ); -jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + +jQuery.each( + ( "blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu" ).split( " " ), function( _i, name ) { @@ -10737,7 +10745,8 @@ jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + this.on( name, null, data, fn ) : this.trigger( name ); }; - } ); + } +); diff --git a/docs/api/python/static/jquery.js b/docs/api/python/static/jquery.js index b0614034ad3a9..c4c6022f2982e 100644 --- a/docs/api/python/static/jquery.js +++ b/docs/api/python/static/jquery.js @@ -1,2 +1,2 @@ -/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
          "],col:[2,"","
          "],tr:[2,"","
          "],td:[3,"","
          "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
          ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
          "],col:[2,"","
          "],tr:[2,"","
          "],td:[3,"","
          "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
          ",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 { + const [docname, title, anchor, descr, score, filename] = result + return score }, */ @@ -28,9 +30,11 @@ if (!Scorer) { // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object - objPrio: {0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5}, // used to be unimportantResults + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, // Used when the priority is not in the mapping. objPrioDefault: 0, @@ -39,456 +43,453 @@ if (!Scorer) { partialTitle: 7, // query found in terms term: 5, - partialTerm: 2 + partialTerm: 2, }; } -if (!splitQuery) { - function splitQuery(query) { - return query.split(/\s+/); +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, highlightTerms, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + const params = new URLSearchParams(); + params.set("highlight", [...highlightTerms].join(" ")); + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + "?" + params.toString() + anchor; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, highlightTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + highlightTerms, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), highlightTerms, searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, highlightTerms, searchTerms), + 5 + ); } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings } /** * Search Module */ -var Search = { - - _index : null, - _queued_query : null, - _pulse_status : -1, - - htmlToText : function(htmlString) { - var virtualDocument = document.implementation.createHTMLDocument('virtual'); - var htmlElement = $(htmlString, virtualDocument); - htmlElement.find('.headerlink').remove(); - docContent = htmlElement.find('[role=main]')[0]; - if(docContent === undefined) { - console.warn("Content block not found. Sphinx search tries to obtain it " + - "via '[role=main]'. Could you check your theme or template."); - return ""; - } - return docContent.textContent || docContent.innerText; +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; }, - init : function() { - var params = $.getQueryParameters(); - if (params.q) { - var query = params.q[0]; - $('input[name="q"]')[0].value = query; - this.performSearch(query); - } + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); }, - loadIndex : function(url) { - $.ajax({type: "GET", url: url, data: null, - dataType: "script", cache: true, - complete: function(jqxhr, textstatus) { - if (textstatus != "success") { - document.getElementById("searchindexloader").src = url; - } - }}); - }, + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), - setIndex : function(index) { - var q; - this._index = index; - if ((q = this._queued_query) !== null) { - this._queued_query = null; - Search.query(q); + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); } }, - hasIndex : function() { - return this._index !== null; - }, + hasIndex: () => Search._index !== null, - deferQuery : function(query) { - this._queued_query = query; - }, + deferQuery: (query) => (Search._queued_query = query), - stopPulse : function() { - this._pulse_status = 0; - }, + stopPulse: () => (Search._pulse_status = -1), - startPulse : function() { - if (this._pulse_status >= 0) - return; - function pulse() { - var i; + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { Search._pulse_status = (Search._pulse_status + 1) % 4; - var dotString = ''; - for (i = 0; i < Search._pulse_status; i++) - dotString += '.'; - Search.dots.text(dotString); - if (Search._pulse_status > -1) - window.setTimeout(pulse, 500); - } + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; pulse(); }, /** * perform a search for something (or wait until index is loaded) */ - performSearch : function(query) { + performSearch: (query) => { // create the required interface elements - this.out = $('#search-results'); - this.title = $('

          ' + _('Searching') + '

          ').appendTo(this.out); - this.dots = $('').appendTo(this.title); - this.status = $('

           

          ').appendTo(this.out); - this.output = $('