get onnx model from singa computational graph Args: inputs: a list of input tensors (each is initialized with a name) Args: y: a list of tensors, usually the outputs of the graph Returns: the onnx model
(cls, inputs, y, model_name="sonnx")
| 907 | |
| 908 | @classmethod |
| 909 | def singa_to_onnx_graph(cls, inputs, y, model_name="sonnx"): |
| 910 | """ |
| 911 | get onnx model from singa computational graph |
| 912 | Args: |
| 913 | inputs: a list of input tensors (each is initialized with a name) |
| 914 | Args: |
| 915 | y: a list of tensors, usually the outputs of the graph |
| 916 | Returns: |
| 917 | the onnx model |
| 918 | """ |
| 919 | assert len( |
| 920 | y |
| 921 | ) == 1, "Not support multiple output now." # assume there is only one output |
| 922 | y = y[0] |
| 923 | |
| 924 | graph_def = GraphProto() |
| 925 | graph_def.name = model_name |
| 926 | topol, ws, ins = utils.post_order_recursive(y.creator, y) |
| 927 | |
| 928 | # prepare the input |
| 929 | X = [] |
| 930 | for op_name, op_t in ins.items(): |
| 931 | op_t = inputs.pop(0) |
| 932 | dtype = TensorProto.INT32 if op_t.dtype == tensor.int32 else TensorProto.FLOAT |
| 933 | X.append(helper.make_tensor_value_info(op_name, dtype, op_t.shape)) |
| 934 | |
| 935 | # prepare the output |
| 936 | y_optype = cls._get_singa_op_type(y.creator) |
| 937 | if y_optype in cls._bool_operators: |
| 938 | y_dtype = cls._bool_operators[y_optype] |
| 939 | elif y.dtype == tensor.int32: |
| 940 | y_dtype = TensorProto.INT32 |
| 941 | else: |
| 942 | y_dtype = TensorProto.FLOAT |
| 943 | Y = [helper.make_tensor_value_info(y.name, y_dtype, y.shape)] |
| 944 | |
| 945 | # prepare the weight |
| 946 | W = [] |
| 947 | for op_name, op_t in ws.items(): |
| 948 | dtype = TensorProto.INT32 if op_t.dtype == tensor.int32 else TensorProto.FLOAT |
| 949 | wt = tensor.to_numpy(op_t) |
| 950 | wt = numpy_helper.from_array(wt) |
| 951 | wt.name = op_name |
| 952 | W.append(wt) |
| 953 | X.append(helper.make_tensor_value_info(op_name, dtype, op_t.shape)) |
| 954 | |
| 955 | # iterate the node graph |
| 956 | for op_name, op in topol.items(): |
| 957 | optype = cls._get_singa_op_type(op) |
| 958 | if optype in cls._unhandled_operators: |
| 959 | cls.handle_special_ops(op, X, W) |
| 960 | graph_def.node.extend(cls.singa_op_to_onnx_node(op, op_t)) |
| 961 | |
| 962 | graph_def.input.extend(X) |
| 963 | graph_def.output.extend(Y) |
| 964 | graph_def.initializer.extend(W) |
| 965 | return graph_def |
| 966 |
no test coverage detected