microsoft/onnxruntime-extensions

Public

mirrored from https://github.com/microsoft/onnxruntime-extensionsAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2ef88b0bda3208844b2bee2ea682bc76a4085c63

Branches

Tags

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

Clone

HTTPS

Download ZIP

ocos/pyfunc/_ocos.py

81lines · 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
6from pathlib import Path
7from ._ortcustomops import PyCustomOpDef, add_custom_op
8
9
10def get_library_path():
11 pkg_dir = Path(__file__).parent
12 return str(pkg_dir / "_ortcustomops.pyd")
13
14
15class Opdef:
16
17 _odlist = {}
18
19 def __init__(self, op_type, func):
20 self.op_type = op_type
21 self.body = func
22 self._id = id(self)
23
24 @staticmethod
25 def declare(*args, **kwargs):
26 if len(args) > 0 and hasattr(args[0], '__call__'):
27 raise RuntimeError("Unexpected arguments {}.".format(args))
28 # return Opdef._create(args[0])
29 return lambda f: Opdef._create(f, *args, **kwargs)
30
31 @staticmethod
32 def _create(func, *args, **kwargs):
33 name = kwargs.get('op_type', None)
34 op_type = name or func.__name__
35 opdef = Opdef(op_type, func)
36 od_id = id(opdef)
37
38 # Tells python this object cannot be destroyed
39 # because it is also stored in C++ container.
40 Opdef._odlist[od_id] = opdef
41 opdef._nativedef = PyCustomOpDef()
42 opdef._nativedef.op_type = op_type
43 opdef._nativedef.obj_id = od_id
44
45 # TODO: add handle more types and multiple inputs/outputs.
46 # by default the op is single in/out
47 inputs = kwargs.get('inputs', None)
48 if inputs is None:
49 inputs = [PyCustomOpDef.dt_float]
50 opdef._nativedef.input_types = inputs
51 outputs = kwargs.get('outputs', None)
52 if outputs is None:
53 outputs = [PyCustomOpDef.dt_float]
54 opdef._nativedef.output_types = outputs
55 add_custom_op(opdef._nativedef)
56 return opdef
57
58 def __call__(self, *args, **kwargs):
59 return self.body(*args, **kwargs)
60
61
62def _on_pyop_invocation(k_id, feed):
63 if k_id not in Opdef._odlist:
64 raise RuntimeError(
65 "Unable to find function id={}. "
66 "Did you decorate the operator with @onnx_op?.".format(k_id))
67 op_ = Opdef._odlist[k_id]
68 rv = op_.body(*feed)
69 if isinstance(rv, tuple):
70 # Multiple outputs.
71 res = []
72 for r in rv:
73 res.append(r.shape)
74 res.append(r.flatten().tolist())
75 res = tuple(res)
76 else:
77 res = (rv.shape, rv.flatten().tolist())
78 return (k_id, ) + res
79
80
81PyCustomOpDef.install_hooker(_on_pyop_invocation)