microsoft/onnxruntime-extensions

Public

mirrored fromhttps://github.com/microsoft/onnxruntime-extensionsAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
13d9e27ccd8a0de9a1225756fbf6860a1931484f

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

onnxruntime_extensions/_ortapi2.py

136lines · modecode

1# Copyright (c) Microsoft Corporation. All rights reserved.
2# Licensed under the MIT License. See License.txt in the project root for
3# license information.
4###############################################################################
5
6import numpy as np
7import onnxruntime as _ort
8from ._ocos import default_opset_domain, get_library_path # noqa
9from ._cuops import * # noqa
10
11
12def get_opset_version_from_ort():
13 _ORT_OPSET_SUPPORT_TABLE = {
14 "1.5": 11,
15 "1.6": 12,
16 "1.7": 13,
17 "1.8": 14,
18 "1.9": 15,
19 "1.10": 15,
20 "1.11": 16,
21 "1.12": 17
22 }
23
24 ort_ver_string = '.'.join(_ort.__version__.split('.')[0:2])
25 return _ORT_OPSET_SUPPORT_TABLE.get(ort_ver_string, 11)
26
27
28def make_onnx_model(graph, opset_version=0, extra_domain=default_opset_domain(), extra_opset_version=1):
29 if opset_version == 0:
30 opset_version = get_opset_version_from_ort()
31 fn_mm = onnx.helper.make_model_gen_version if hasattr(onnx.helper, 'make_model_gen_version'
32 ) else onnx.helper.make_model
33 model = fn_mm(graph, opset_imports=[
34 onnx.helper.make_operatorsetid('ai.onnx', opset_version)])
35 model.opset_import.extend([onnx.helper.make_operatorsetid(extra_domain, extra_opset_version)])
36 return model
37
38
39class OrtPyFunction:
40
41 __name__ = 'OrtPyFunction'
42
43 @classmethod
44 def get_ort_session_options(cls):
45 # ONNXRuntime has an issue to support reusing the SessionOptions object.
46 # Create a new one every time here
47 so = _ort.SessionOptions()
48 so.register_custom_ops_library(get_library_path())
49 return so
50
51 def __init__(self):
52 self._onnx_model = None
53 self.ort_session = None
54 self.default_inputs = {}
55
56 def create_from_customop(self, op_type, *args, **kwargs):
57 graph = SingleOpGraph.build_my_graph(op_type, *args, **kwargs)
58 self._bind(make_onnx_model(graph))
59 return self
60
61 def add_default_input(self, **kwargs):
62 inputs = {
63 ky_: val_ if isinstance(val_, (np.ndarray, np.generic)) else \
64 np.asarray(list(val_), dtype=np.uint8) for ky_, val_ in kwargs.items()
65 }
66
67 self.default_inputs.update(inputs)
68
69 @property
70 def onnx_model(self):
71 assert self._oxml is not None, "No onnx model attached yet."
72 return self._oxml
73
74 @property
75 def input_names(self):
76 return [vi_.name for vi_ in self.onnx_model.graph.input]
77
78 @property
79 def output_names(self):
80 return [vi_.name for vi_ in self.onnx_model.graph.output]
81
82 def _bind(self, oxml):
83 self.inputs = list(oxml.graph.input)
84 self.outputs = list(oxml.graph.output)
85 self._oxml = oxml
86 return self
87
88 def _ensure_ort_session(self):
89 if self.ort_session is None:
90 sess = _ort.InferenceSession(self.onnx_model.SerializeToString(), self.get_ort_session_options())
91 self.ort_session = sess
92
93 return self.ort_session
94
95 @classmethod
96 def from_customop(cls, op_type, *args, **kwargs):
97 return cls().create_from_customop(op_type, *args, **kwargs)
98
99 @classmethod
100 def from_model(cls, path_or_model, *args, **kwargs):
101 return cls()._bind(onnx.load_model(path_or_model) if isinstance(path_or_model, str) else path_or_model)
102
103 def _argument_map(self, *args, **kwargs):
104 idx = 0
105 feed = {}
106 for i_ in self.inputs:
107 if i_.name in self.default_inputs:
108 feed[i_.name] = self.default_inputs[i_.name]
109 continue
110
111 x = args[idx]
112 ts_x = np.array(x) if isinstance(x, (int, float, bool)) else x
113 # an annoying bug is numpy by default is int32, while pytorch is int64.
114 # so cast the input here automatically.
115 feed[i_.name] = \
116 ts_x.astype(np.int64) if i_.type.tensor_type.elem_type == onnx_proto.TensorProto.INT64 else ts_x
117 idx += 1
118
119 # feed.update(kwargs)
120 return feed
121
122 def __call__(self, *args, **kwargs):
123 self._ensure_ort_session()
124 outputs = self.ort_session.run(None, self._argument_map(*args, **kwargs))
125 return outputs[0] if len(outputs) == 1 else tuple(outputs)
126
127
128def optimize_model(model_or_file, output_file):
129 sess_options = OrtPyFunction.get_ort_session_options()
130 sess_options.graph_optimization_level = _ort.GraphOptimizationLevel.ORT_ENABLE_BASIC
131 sess_options.optimized_model_filepath = output_file
132 _ort.InferenceSession(model_or_file if isinstance(model_or_file, str)
133 else model_or_file.SerializeToString(), sess_options)
134
135
136ONNXRuntimeError = _ort.capi.onnxruntime_pybind11_state.Fail