def test_spacetodepth():
    n, c, h, w = shape = (1, 1, 4, 6)
    input1 = np.random.rand(n, c, h, w).astype("float32")
    blocksize = 2
    inputs = [helper.make_tensor_value_info("input1", TensorProto.FLOAT, shape=shape)]

    outputs = [helper.make_tensor_value_info("output", TensorProto.FLOAT, shape=(1, 4, 2, 3))]

    nodes = [helper.make_node("SpaceToDepth", ["input1"], ["output"], block_size=blocksize)]

    graph = helper.make_graph(nodes,
                              "spacetodepth_test",
                              inputs,
                              outputs)

    spacetodepth_model = helper.make_model(graph)

    bkd_rep = backend.prepare(spacetodepth_model)
    output = bkd_rep.run([input1])

    tmp = np.reshape(input1, [n, c,
                    h // blocksize, blocksize,
                    w // blocksize, blocksize])
    tmp = np.transpose(tmp, [0, 3, 5, 1, 2, 4])
    numpy_op = np.reshape(tmp, [n, c * (blocksize**2),
                    h // blocksize,
                    w // blocksize])

    npt.assert_almost_equal(output[0], numpy_op)
Exemplo n.º 2
0
    def test_nested_graph(self):  # type: () -> None
        n1 = helper.make_node(
            "Scale", ["X"], ["Y"], scale=2., name="n1")
        n2 = helper.make_node(
            "Scale", ["Y"], ["Z"], scale=3., name="n2")

        graph = helper.make_graph(
            [n1, n2],
            "nested",
            inputs=[
                helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])
            ],
            outputs=[
                helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])
            ]
        )

        i1 = helper.make_node(
            "If", ["cond"], ["Z"], then_branch=graph, else_branch=graph)

        graph = helper.make_graph(
            [i1],
            "test",
            inputs=[
                helper.make_tensor_value_info("cond", TensorProto.BOOL, [1])
            ],
            outputs=[],
        )

        checker.check_graph(graph)
Exemplo n.º 3
0
    def test_small_model(self):
        # Create one input
        X = helper.make_tensor_value_info('IN', TensorProto.FLOAT, [2, 3])
        # Create one output
        Y = helper.make_tensor_value_info('OUT', TensorProto.FLOAT, [2, 3])
        # Create a node
        node_def = helper.make_node('Abs', ['IN'], ['OUT'])

        # Create the model
        graph_def = helper.make_graph([node_def], "test-model", [X], [Y])
        onnx_model = helper.make_model(graph_def,
                                       producer_name='onnx-example')

        model = Model()
        model.BuildFromOnnxModel(onnx_model)
        schedule = model.OptimizeSchedule()
        schedule = schedule.replace('\n', ' ')
        expected_schedule = r'// Target: .+// MachineParams: .+// Delete this line if not using Generator Pipeline pipeline = get_pipeline\(\);.+Func OUT = pipeline.get_func\(1\);.+{.+}.+'
        self.assertRegex(schedule, expected_schedule)

        input = np.random.rand(2, 3) - 0.5
        outputs = model.run([input])
        self.assertEqual(1, len(outputs))
        output = outputs[0]
        expected = np.abs(input)
        np.testing.assert_allclose(expected, output)
Exemplo n.º 4
0
    def test_onnx_to_caffe2_zipfile(self):
        buf = tempfile.NamedTemporaryFile()
        onnx_model = zipfile.ZipFile(buf, 'w')
        output = tempfile.NamedTemporaryFile()
        init_net_output = tempfile.NamedTemporaryFile()

        node_def = helper.make_node(
            "MatMul", ["X", "W"], ["Y"])
        X = np.random.rand(2, 3).astype(np.float32)
        W = np.random.rand(3, 2).flatten().astype(np.float32)
        graph_def = helper.make_graph(
            [node_def],
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (2, 3)),
             helper.make_tensor_value_info("W", TensorProto.FLOAT, (3, 2))],
            [helper.make_tensor_value_info("Y", TensorProto.FLOAT, (2, 2))],
            initializer=[helper.make_tensor("W",
                                            TensorProto.FLOAT,
                                            [3, 2],
                                            b'__EXTERNAL',
                                            raw=True)])
        model_def = helper.make_model(graph_def, producer_name='onnx-to-caffe2-test')
        onnx_model.writestr('__MODEL_PROTO', model_def.SerializeToString())
        onnx_model.writestr('W', W.tobytes())
        onnx_model.close()

        W = W.reshape((3, 2))
        Y_expect = np.matmul(X, W)

        c2_model = c2.prepare_zip_archive(buf)
        Y = c2_model.run(X).Y
        np.testing.assert_allclose(Y, Y_expect)
Exemplo n.º 5
0
 def test_split_from_GLU(self):  # type: () -> None
     graph = self._make_graph(
         [('x', TensorProto.FLOAT, (5, 6, 7))],
         [make_node('Split', ['x'], ['y', 'z'], axis=1)],
         [])
     self._assert_inferred(graph, [make_tensor_value_info('y', TensorProto.FLOAT, (5, 3, 7)),
                                   make_tensor_value_info('z', TensorProto.FLOAT, (5, 3, 7))])
Exemplo n.º 6
0
    def test_make_tensor_value_info(self):  # type: () -> None
        vi = helper.make_tensor_value_info('X', TensorProto.FLOAT, (2, 4))
        checker.check_value_info(vi)

        # scalar value
        vi = helper.make_tensor_value_info('Y', TensorProto.FLOAT, ())
        checker.check_value_info(vi)
Exemplo n.º 7
0
 def test_onnx_to_caffe2_loop(self):
     body_nodes = [helper.make_node(
         "MatMul", ["_X", "W"], ["_Y"])]
     nodes = self._make_fake_loop_op(body_nodes,
                                     [(TensorProto.FLOAT, (2, 2), "X")],
                                     [(TensorProto.FLOAT, (2, 2), "Y")])
     X = np.random.rand(2, 2).astype(np.float32)
     W = np.random.rand(2, 2).flatten().astype(np.float32)
     graph_def = helper.make_graph(
         nodes,
         "test",
         [helper.make_tensor_value_info("X", TensorProto.FLOAT, (2, 2)),
          helper.make_tensor_value_info("W", TensorProto.FLOAT, (2, 2))],
         [helper.make_tensor_value_info("Y", TensorProto.FLOAT, (2, 2))],
         initializer=[helper.make_tensor("W",
                                         TensorProto.FLOAT,
                                         [2, 2],
                                         W.tolist())]
     )
     model_def = helper.make_model(graph_def, producer_name='onnx-to-caffe2-test')
     Y = X
     for _ in range(10):
         Y = np.matmul(Y, W.reshape(2, 2))
     p = c2.prepare(model_def)
     out = p.run(X)
     np.testing.assert_allclose(out.Y, Y)
Exemplo n.º 8
0
def verify_constantfill(is_shape, input_dim, out_dim, value, dtype, **kwargs):
    input_a = np.random.uniform(size=input_dim).astype(dtype)
    out = np.empty(shape=out_dim, dtype=dtype)
    out.fill(value)

    if is_shape == True:
        fill_node = helper.make_node("ConstantFill", [], ["out"], shape=input_dim, value=value, **kwargs)
    else:
        fill_node = helper.make_node("ConstantFill", ["input_a"], ["out"], value=value, dtype=dtype, **kwargs)

    graph = helper.make_graph([fill_node],
                              "fill_test",
                              inputs = [helper.make_tensor_value_info("input_a",
                                            TensorProto.FLOAT, list(input_dim))],
                              outputs = [helper.make_tensor_value_info("out",
                                            TensorProto.FLOAT, list(out.shape))])

    model = helper.make_model(graph, producer_name='fill_test')

    for target, ctx in ctx_list():
        if is_shape == True:
            tvm_out = get_tvm_output(model, [], target, ctx, out.shape)
        else:
            tvm_out = get_tvm_output(model, [input_a], target, ctx, out.shape)

        tvm.testing.assert_allclose(out, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 9
0
def verify_mean(input_dim):
    dtype = 'float32'

    a_np1 = np.random.uniform(size=input_dim).astype(dtype)
    a_np2 = np.random.uniform(size=input_dim).astype(dtype)
    a_np3 = np.random.uniform(size=input_dim).astype(dtype)

    b_np = np.mean((a_np1, a_np2, a_np3), axis=0)

    mean_node = helper.make_node("Mean", ["a_np1", "a_np2", "a_np3"], ["out"])

    graph = helper.make_graph([mean_node],
                              "Mean_test",
                              inputs = [helper.make_tensor_value_info("a_np1",
                                            TensorProto.FLOAT, list(input_dim)),
                                        helper.make_tensor_value_info("a_np2",
                                            TensorProto.FLOAT, list(input_dim)),
                                        helper.make_tensor_value_info("a_np3",
                                            TensorProto.FLOAT, list(input_dim))],
                              outputs = [helper.make_tensor_value_info("out",
                                            TensorProto.FLOAT, list(b_np.shape))])

    model = helper.make_model(graph, producer_name='Mean_test')

    for target, ctx in ctx_list():
        tvm_out = get_tvm_output(model, [a_np1, a_np2, a_np3], target, ctx, b_np.shape)
        tvm.testing.assert_allclose(b_np, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 10
0
def verify_reduce_x(name, indata, axis, keepdims):
    indata = np.array(indata).astype(np.float32)
    #  numpy expect result
    if name == 'ReduceMax':
        outdata = np.maximum.reduce(indata, axis=axis, keepdims=keepdims == 1)
    elif name == 'ReduceMin':
        outdata = np.minimum.reduce(indata, axis=axis, keepdims=keepdims == 1)
    elif name == 'ReduceSum':
        outdata = np.sum(indata, axis=axis, keepdims=keepdims == 1)
    elif name == 'ReduceMean':
        outdata = np.mean(indata, axis=axis, keepdims=keepdims == 1)
    else:
        raise Exception('unsupport op: {}'.format(name))
    if len(np.asarray(outdata).shape) == 0:
        outdata = np.asarray([outdata])
    #  onnx graph
    if axis is None:
        node = helper.make_node(name, inputs=['input'], outputs=['output'],
                                keepdims=keepdims)
    else:
        node = helper.make_node(name, inputs=['input'], outputs=['output'],
                                axis=axis, keepdims=keepdims)
    graph = helper.make_graph([node],
                              '{}_test'.format(name),
                              inputs = [helper.make_tensor_value_info("input",
                                            TensorProto.FLOAT, list(indata.shape))],
                              outputs = [helper.make_tensor_value_info("output",
                                            TensorProto.FLOAT, list(outdata.shape))])
    model = helper.make_model(graph, producer_name='{}_test'.format(name))
    #  tvm result
    for target, ctx in ctx_list():
        tvm_out = get_tvm_output(model, indata, target, ctx, outdata.shape, 'float32')
    tvm.testing.assert_allclose(outdata, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 11
0
def verify_pad(indata, pads, value=0.0):
    indata = np.array(indata).astype(np.float32)
    #  numpy expect result
    len_dim = len(pads) // 2
    np_pads = [(pads[i], pads[i+len_dim]) for i in range(len_dim)]
    outdata = np.pad(indata, pad_width=np_pads, mode='constant', constant_values=value)
    #  onnx graph
    node = helper.make_node(
        'Pad',
        inputs=['input'],
        outputs=['output'],
        mode='constant',
        pads=pads,
        value=value
    )
    graph = helper.make_graph([node],
                              'pad_test',
                              inputs = [helper.make_tensor_value_info("input",
                                            TensorProto.FLOAT, list(indata.shape))],
                              outputs = [helper.make_tensor_value_info("output",
                                            TensorProto.FLOAT, list(outdata.shape))])
    model = helper.make_model(graph, producer_name='pad_test')
    #  tvm result
    for target, ctx in ctx_list():
        tvm_out = get_tvm_output(model, indata, target, ctx, outdata.shape, 'float32')
    tvm.testing.assert_allclose(outdata, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 12
0
def test_shape():
    in_shape = (4, 3, 3, 4)
    ref_shape = (6, 2, 4, 3)

    ref_array = np.array(ref_shape)
    ref_node = onnx.helper.make_node('Constant',
                                 inputs=[],
                                 outputs=['ref_in'],
                                 value=onnx.helper.make_tensor(name = 'const_tensor',
                                                               data_type = onnx.TensorProto.INT32,
                                                               dims = ref_array.shape,
                                                               vals = ref_array.flatten().astype(int)))
    reshape_node = helper.make_node("Reshape", ["in", "ref_in"], ["out"])

    shape_node = helper.make_node("Shape", ['out'], ['final_out'])

    graph = helper.make_graph([ref_node, reshape_node, shape_node],
                              "shape_test",
                              inputs = [helper.make_tensor_value_info("in",
                                            TensorProto.FLOAT, list(in_shape))],
                              outputs = [helper.make_tensor_value_info("final_out",
                                            TensorProto.FLOAT, list(ref_shape))])

    model = helper.make_model(graph, producer_name='shape_test')

    for target, ctx in ctx_list():
        x = np.random.uniform(size=in_shape).astype('int32')
        tvm_out = get_tvm_output(model, x, target, ctx, ref_shape, 'int32')

    tvm.testing.assert_allclose(ref_shape, tvm_out)
Exemplo n.º 13
0
    def test_eliminate_identity_single_use(self):  # type: () -> None
        nodes = [helper.make_node("Identity", ["X"], ["Y"])]
        nodes.extend(self._make_fake_loop_op(
            [helper.make_node("Identity", ["_Y"], ["_Y2"])],
            [(TensorProto.FLOAT, (5,), "Y")],
            [(TensorProto.FLOAT, (5,), "Y2")]))
        graph = helper.make_graph(
            nodes,
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
            [helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,)),
             helper.make_tensor_value_info("Y2", TensorProto.FLOAT, (5,))])
        optimized_model = self._optimized(graph, ["eliminate_identity"])

        # All identity nodes should have been eliminated
        def check_identity(node):  # type: (NodeProto) -> None
            assert node.op_type != "Identity"
        self._visit_all_nodes_recursive(optimized_model.graph, check_identity)
        # Use of the output from the Identity node in the main graph should
        # have been replaced with the input to the identity node
        assert len(optimized_model.graph.output) == 2
        assert optimized_model.graph.output[0].name == "X"
        # Use of the output from the Identity node in the loop graph should
        # have been replaced with the input to that identity node
        assert len(optimized_model.graph.node[2].attribute[0].g.output) == 2
        assert optimized_model.graph.node[2].attribute[0].g.output[1].name == "_Y"
Exemplo n.º 14
0
 def _make_fake_loop_op(self,
                        body_nodes,  # type: Sequence[NodeProto]
                        input_types,  # type: Sequence[Tuple[TensorProto.DataType, Sequence[int], Text]]
                        output_types  # type: Sequence[Tuple[TensorProto.DataType, Sequence[int], Text]]
                        ):  # type: (...) -> List[NodeProto]
     zero = helper.make_tensor("trip_count_value", TensorProto.INT32, (), [10])
     true = helper.make_tensor("condition", TensorProto.BOOL, (), [True])
     # lcd is a dummy loop-carried dependency that only exists because
     # right now the schema checker is broken and assumes a variadic
     # input needs at least one value.
     graph_inputs = [helper.make_tensor_value_info("i", TensorProto.INT32, ()),
                     helper.make_tensor_value_info("cond", TensorProto.BOOL, ())]
     for type, shape, name in input_types:
         graph_inputs.append(helper.make_tensor_value_info("_" + name, type, shape))
     graph_outputs = [helper.make_tensor_value_info("cond", TensorProto.BOOL, ())]
     for type, shape, name in output_types:
         graph_outputs.append(helper.make_tensor_value_info("_" + name, type, shape))
     body_graph = helper.make_graph(body_nodes, "body_graph", graph_inputs,
                                    graph_outputs)
     loop_inputs = ["trip_count", "condition"]
     loop_inputs.extend([name for _, _, name in input_types])
     # TODO: fix checker to accept 0-input variadic inputs
     if len(loop_inputs) == 2:
         loop_inputs.append("")
     loop_outputs = [name for _, _, name in output_types]
     retval_nodes = [
         helper.make_node("Constant", [], ["trip_count"], value=zero),
         helper.make_node("Constant", [], ["condition"], value=true),
         helper.make_node("Loop", loop_inputs, loop_outputs, body=body_graph)
     ]
     return retval_nodes
Exemplo n.º 15
0
def test_reshape_like():
    in_shape = (4, 3, 3, 4)
    ref_shape = (3, 4, 4, 3)

    ref_array = np.random.uniform(size=ref_shape).astype('float32')
    ref_node = onnx.helper.make_node('Constant',
                                 inputs=[],
                                 outputs=['ref_in'],
                                 value=onnx.helper.make_tensor(name = 'const_tensor',
                                                               data_type = onnx.TensorProto.FLOAT,
                                                               dims = ref_array.shape,
                                                               vals = ref_array.flatten().astype(float)))
    copy_node = helper.make_node("Identity", ["ref_in"], ["copy_in"])
    reshape_node = helper.make_node("Reshape", ["in", "copy_in"], ["out"])

    graph = helper.make_graph([ref_node, copy_node, reshape_node],
                              "reshape_like_test",
                              inputs = [helper.make_tensor_value_info("in",
                                            TensorProto.FLOAT, list(in_shape))],
                              outputs = [helper.make_tensor_value_info("out",
                                            TensorProto.FLOAT, list(ref_shape))])

    model = helper.make_model(graph, producer_name='reshape_like_test')

    for target, ctx in ctx_list():
        x = np.random.uniform(size=in_shape).astype('float32')
        tvm_out = get_tvm_output(model, x, target, ctx, ref_shape, 'float32')

    tvm.testing.assert_allclose(ref_shape, tvm_out.shape)
Exemplo n.º 16
0
    def test_fuse_transpose_into_gemm(self):  # type: () -> None
        nodes = [helper.make_node("Transpose", ["X"], ["A"], perm=[1, 0]),
                 helper.make_node("Transpose", ["Y"], ["B"], perm=[1, 0]),
                 helper.make_node("Gemm", ["A", "B", "C"], ["Z"])]
        nodes.extend(self._make_fake_loop_op(
            [helper.make_node("Transpose", ["_X"], ["_A"], perm=[1, 0]),
             helper.make_node("Transpose", ["_Y"], ["_B"], perm=[1, 0]),
             helper.make_node("Gemm", ["_A", "_B", "_C"], ["_Z2"])],
            [(TensorProto.FLOAT, (2, 3), "X"),
             (TensorProto.FLOAT, (5, 2), "Y"),
             (TensorProto.FLOAT, (3, 5), "C")],
            [(TensorProto.FLOAT, (2, 3), "Z2")]))
        graph = helper.make_graph(
            nodes,
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (2, 3)),
             helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5, 2)),
             helper.make_tensor_value_info("C", TensorProto.FLOAT, (3, 5))],
            [helper.make_tensor_value_info("Z", TensorProto.FLOAT, (3, 5))])
        optimized_model = self._optimized(graph, ["fuse_transpose_into_gemm"])

        # Gemm, Constant (trip count), Constant (cond), Loop
        assert len(list(optimized_model.graph.node)) == 4
        assert optimized_model.graph.node[0].op_type == "Gemm"
        # Gemm
        assert len(optimized_model.graph.node[3].attribute[0].g.node) == 1
        assert optimized_model.graph.node[3].attribute[0].g.node[0].op_type == "Gemm"
Exemplo n.º 17
0
    def test_extract_constant_to_initializer(self):  # type: () -> None
        conv = helper.make_node("Conv", ["X", "Y"], ["Z"])
        constant = helper.make_node("Constant", [], ["A"],
                                    value=helper.make_tensor(
                                        name="bias",
                                        data_type=TensorProto.FLOAT,
                                        dims=(16,),
                                        vals=np.random.randn(16).astype(np.float32).tolist()))
        add = helper.make_node("Add", ["Z", "A"], ["B"])
        graph = helper.make_graph(
            [conv, constant, add],
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 5, 3, 3)),
             helper.make_tensor_value_info("Y", TensorProto.FLOAT, (16, 5, 3, 3))],
            [helper.make_tensor_value_info("B", TensorProto.FLOAT, (1, 16, 3, 3))],
        )
        optimized_model = self._optimized(graph, ["extract_constant_to_initializer"])
        self.assertEqual(
            set(vi.name for vi in optimized_model.graph.input),
            {'X', 'Y', 'A'})

        self.assertEqual(len(optimized_model.graph.initializer), 1)
        init = optimized_model.graph.initializer[0]
        self.assertEqual(init.name, 'A')
        self.assertEqual(init.dims, [16])
        self.assertEqual(init.data_type, TensorProto.FLOAT)

        self.assertEqual([n.op_type for n in optimized_model.graph.node], ['Conv', 'Add'])
Exemplo n.º 18
0
    def test_fuse_add_bias_into_conv_use_weight_shape(self):  # type: () -> None
        nodes = [helper.make_node("Conv", ["X", "Y"], ["Z"]),
                 helper.make_node("Add", ["Z", "A"], ["B"])]
        nodes.extend(self._make_fake_loop_op(
            [helper.make_node("Conv", ["_X", "_Y"], ["_Z"]),
             helper.make_node("Add", ["_Z", "_A"], ["_B2"])],
            [(TensorProto.FLOAT, (1, 5, 3, 3), "X"),
             (TensorProto.FLOAT, (16, 5, 3, 3), "Y"),
             (TensorProto.FLOAT, (16, 1, 1), "A")],
            [(TensorProto.FLOAT, (1, 16, 3, 3), "B2")]))
        graph = helper.make_graph(
            nodes,
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 5, 3, 3)),
             helper.make_tensor_value_info("Y", TensorProto.FLOAT, (16, 5, 3, 3)),
             helper.make_tensor_value_info("A", TensorProto.FLOAT, (16, 1, 1))],
            [helper.make_tensor_value_info("B", TensorProto.FLOAT, (1, 16, 3, 3))],
        )
        optimized_model = self._optimized(graph, ["fuse_add_bias_into_conv"])

        # Squeeze, Conv, Constant (trip count), Constant (condition), Loop
        assert len(list(optimized_model.graph.node)) == 5
        assert optimized_model.graph.node[0].op_type == 'Squeeze'
        assert optimized_model.graph.node[1].op_type == 'Conv'
        assert optimized_model.graph.output[0].name == 'Z'
        # Squeeze, Conv
        assert len(optimized_model.graph.node[4].attribute[0].g.node) == 2
        assert optimized_model.graph.node[4].attribute[0].g.node[0].op_type == 'Squeeze'
        assert optimized_model.graph.node[4].attribute[0].g.node[1].op_type == 'Conv'
        # Output 1 since 0 is 'cond'
        assert optimized_model.graph.node[4].attribute[0].g.output[1].name == '_Z'
Exemplo n.º 19
0
    def test_fuse_add_bias_into_conv_use_move_constant(self):  # type: () -> None
        conv = helper.make_node("Conv", ["X", "Y"], ["Z"])
        constant = helper.make_node("Constant", [], ["A"],
                                    value=helper.make_tensor(
                                        name="bias",
                                        data_type=TensorProto.FLOAT,
                                        dims=(16,),
                                        vals=np.random.randn(16).astype(np.float32).tolist()))
        add = helper.make_node("Add", ["Z", "A"], ["B"])
        graph = helper.make_graph(
            [conv, constant, add],
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 5, 3, 3)),
             helper.make_tensor_value_info("Y", TensorProto.FLOAT, (16, 5, 3, 3))],
            [helper.make_tensor_value_info("B", TensorProto.FLOAT, (1, 16, 3, 3))],
            value_info=[
                helper.make_tensor_value_info("A", TensorProto.FLOAT, (16, 1, 1)),
            ]
        )
        optimized_model = self._optimized(graph, ["fuse_add_bias_into_conv"])

        assert len(optimized_model.graph.node) == 3
        assert optimized_model.graph.node[0].op_type == 'Constant'
        assert optimized_model.graph.node[1].op_type == 'Squeeze'
        assert optimized_model.graph.node[2].op_type == 'Conv'
        assert optimized_model.graph.output[0].name == 'Z'
        assert optimized_model.graph.output[0].type.tensor_type.elem_type == TensorProto.FLOAT
        assert len(optimized_model.graph.output[0].type.tensor_type.shape.dim) == 4
Exemplo n.º 20
0
    def test_lift_lex_if(self):  # type: () -> None
        nodes = [helper.make_node("Identity", ["X"], ["Y"])]
        nodes.extend(self._make_fake_if_op(
            [helper.make_node("Identity", ["X"], ["_Y2"]),
             helper.make_node("Identity", ["Y"], ["_Y3"])],
            [helper.make_node("Identity", ["X"], ["_Y2"]),
             helper.make_node("Identity", ["X"], ["_Y3"])],
            [(TensorProto.FLOAT, (5,), "Y2"),
             (TensorProto.FLOAT, (5,), "Y3")]))
        graph = helper.make_graph(
            nodes,
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
            [helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,)),
             helper.make_tensor_value_info("Y2", TensorProto.FLOAT, (5,))])
        # "If" node now diverges from ONNX schema. Disable checking.
        optimized_model = self._optimized(graph, ["lift_lexical_references"])

        # Identity, Constant (condition), If
        assert len(optimized_model.graph.node) == 3
        # else_branch, then_branch, __control_inputs
        assert len(optimized_model.graph.node[2].attribute) == 3
        assert optimized_model.graph.node[2].attribute[2].name == "__control_inputs"
        assert optimized_model.graph.node[2].attribute[2].strings[0] == b"X"
        assert optimized_model.graph.node[2].attribute[2].strings[1] == b"Y"
Exemplo n.º 21
0
def _test_upsample_bilinear_opset9():
    scale = 2
    in_shape = (1, 1, 3, 3)
    out_shape = (1, 1, 3*scale, 3*scale)
    y = helper.make_node("Upsample", ['in','scales'], ['out'], mode='linear')
    scales=[1.0, 1.0, 2.0, 2.0]
    in_array = np.random.uniform(size=in_shape).astype(np.float32)
    out_array = topi.testing.bilinear_resize_python(in_array, (3*scale, 3*scale), "NCHW")

    ref_array = np.array(scales)
    ref_node = helper.make_node('Constant',
                                 inputs=[],
                                 outputs=['scales'],
                                 value=onnx.helper.make_tensor(name = 'const_tensor',
                                                               data_type = TensorProto.FLOAT,
                                                               dims = ref_array.shape,
                                                               vals = ref_array.flatten().astype(float)))

    graph = helper.make_graph([ref_node, y],
                              'upsample_bilinear_opset9_test',
                              inputs = [helper.make_tensor_value_info("in", TensorProto.FLOAT, list(in_shape))],
                              outputs = [helper.make_tensor_value_info("out", TensorProto.FLOAT, list(out_shape))])

    model = helper.make_model(graph, producer_name='upsample_bilinear_opset9_test')
    inputs = []
    inputs.append(in_array)

    for target, ctx in ctx_list():
        tvm_out = get_tvm_output(model, inputs, target, ctx, out_shape, 'float32')
        tvm.testing.assert_allclose(out_array, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 22
0
    def test_eliminate_unused_initializer_no_eliminate_used(self):  # type: () -> None
        nodes = [helper.make_node("Add", ["X", "A"], ["Z"])]
        nodes.extend(self._make_fake_loop_op(
            [helper.make_node("Add", ["_X", "_A"], ["_Z2"])],
            [(TensorProto.FLOAT, (1, 2), "X"),
             (TensorProto.FLOAT, (1, 2), "A")],
            [(TensorProto.FLOAT, (1, 2), "Z2")]))
        graph = helper.make_graph(
            nodes,
            "test",
            [helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 2)),
             helper.make_tensor_value_info("A", TensorProto.FLOAT, (1, 2))],
            [helper.make_tensor_value_info("Z", TensorProto.FLOAT, (1, 2))],
            [helper.make_tensor("A", TensorProto.FLOAT,
                                dims=(1, 2),
                                vals=np.random.randn(1, 2).astype(np.float32).tobytes(),
                                raw=True)])
        optimized_model = self._optimized(graph, ["eliminate_unused_initializer"])

        # Add, Constant (trip count), Constant (cond), Loop
        assert len(list(optimized_model.graph.node)) == 4
        assert optimized_model.graph.node[0].op_type == "Add"
        assert optimized_model.graph.output[0].name == "Z"
        # Add
        assert len(optimized_model.graph.node[3].attribute[0].g.node) == 1
        assert optimized_model.graph.node[3].attribute[0].g.node[0].op_type == 'Add'
        assert optimized_model.graph.node[3].attribute[0].g.output[1].name == '_Z2'

        assert len(list(optimized_model.graph.initializer)) == 1
Exemplo n.º 23
0
def _test_power_iteration(x_shape, y_shape):
    if isinstance(y_shape, int):
        y_shape = [y_shape]

    x = np.random.uniform(size=x_shape).astype(np.float32)
    y = np.random.uniform(size=y_shape).astype(np.float32)

    np_res = np.power(x, y).astype(np.float32)

    res = helper.make_node("Pow", ['x', 'y'], ['out'])

    graph = helper.make_graph([res],
                              'power_test',
                              inputs = [helper.make_tensor_value_info("x",
                                            TensorProto.FLOAT, list(x_shape)),
                                        helper.make_tensor_value_info("y",
                                            TensorProto.FLOAT, list(y_shape))],
                              outputs = [helper.make_tensor_value_info("out",
                                            TensorProto.FLOAT, list(np_res.shape))])

    model = helper.make_model(graph, producer_name='power_test')

    for target, ctx in ctx_list():
        tvm_out = get_tvm_output(model, [x, y], target, ctx, np_res.shape)
        tvm.testing.assert_allclose(np_res, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 24
0
    def test_initializer(self):
        X = np.array([[1, 2], [3, 4]]).astype(np.float32)
        Y = np.array([[1, 2], [3, 4]]).astype(np.float32)
        weight = np.array([[1, 0], [0, 1]])
        graph_def = make_graph(
            [make_node("Add", ["X", "Y"], ["Z0"]),
             make_node("Cast", ["Z0"], ["Z"], to="float"),
             make_node("Mul", ["Z", "weight"], ["W0"]),
             make_node("Tanh", ["W0"], ["W1"]),
             make_node("Sigmoid", ["W1"], ["W2"]),
             make_node("Scale", ["W2"], ["W3"], scale=-1.0)],
            name="test_initializer",
            inputs=[
                make_tensor_value_info("X", onnx.TensorProto.FLOAT, (2, 2)),
                make_tensor_value_info("Y", onnx.TensorProto.FLOAT, (2, 2)),
                make_tensor_value_info("weight", onnx.TensorProto.FLOAT, (2, 2)),
            ],
            outputs=[
                make_tensor_value_info("W3", onnx.TensorProto.FLOAT, (2, 2))
            ],
            initializer=[make_tensor("weight",
                                     onnx.TensorProto.FLOAT,
                                     [2, 2],
                                     weight.flatten().astype(float))]
        )

        def sigmoid(x):
            return 1 / (1 + np.exp(-x))

        W_ref = -sigmoid(np.tanh((X + Y) * weight))
        c2_rep = c2.prepare(make_model(graph_def, producer_name='caffe2-ref-test'))
        output = c2_rep.run({"X": X, "Y": Y})
        np.testing.assert_almost_equal(output["W3"], W_ref)
Exemplo n.º 25
0
def verify_lrn(shape, nsize, dtype, alpha=None, beta=None, bias=None):
    in_array = np.random.uniform(size=shape).astype(dtype)

    if alpha == None and beta == None and bias==None:
        alpha = 0.0001
        beta = 0.75
        bias = 1.0
        node = onnx.helper.make_node('LRN', inputs=['in'], outputs=['out'], size=nsize)
    else:
        node = onnx.helper.make_node('LRN', inputs=['in'], outputs=['out'], alpha=alpha,
                                     beta=beta, bias=bias, size=nsize)

    graph = helper.make_graph([node],
                              "lrn_test",
                              inputs = [helper.make_tensor_value_info("in", TensorProto.FLOAT, list(shape))],
                              outputs = [helper.make_tensor_value_info("out", TensorProto.FLOAT, list(shape))])
    model = helper.make_model(graph, producer_name='lrn_test')

    def _get_python_lrn():
        square_sum = np.zeros(shape).astype(dtype)
        for n, c, h, w in np.ndindex(in_array.shape):
            square_sum[n, c, h, w] = sum(in_array[n,
                                         max(0, c - int(math.floor((nsize - 1) / 2))): \
                                             min(5, c + int(math.ceil((nsize - 1) / 2)) + 1),
                                         h,
                                         w] ** 2)
        py_out = in_array / ((bias + (alpha / nsize) * square_sum) ** beta)
        return py_out

    for target, ctx in ctx_list():
        input_name = model.graph.input[0].name
        py_out = _get_python_lrn()
        tvm_out = get_tvm_output(model, in_array, target, ctx, py_out.shape, 'float32')
        tvm.testing.assert_allclose(py_out, tvm_out, rtol=1e-5, atol=1e-5)
Exemplo n.º 26
0
def verify_split(indata, outdatas, split, axis=0):
    indata = np.array(indata).astype(np.float32)
    outdatas = [np.array(o).astype(np.float32) for o in outdatas]
    node = helper.make_node(
        'Split',
        inputs=['input'],
        outputs=['output_{}'.format(i) for i in range(len(split))],
        axis=axis,
        split=split
    )
    graph = helper.make_graph([node],
                              'split_test',
                              inputs = [helper.make_tensor_value_info("input",
                                            TensorProto.FLOAT, list(indata.shape))],
                              outputs = [helper.make_tensor_value_info("output_{}".format(i),
                                            TensorProto.FLOAT, list(outdatas[i].shape))
                                            for i in range(len(split))
                                         ])
    model = helper.make_model(graph, producer_name='split_test')

    for target, ctx in ctx_list():
        output_shape = [o.shape for o in outdatas]
        output_type = ['float32', 'float32', 'float32']
        tvm_out = get_tvm_output(model, indata, target, ctx, output_shape, output_type)
    for o, t in zip(outdatas, tvm_out):
        tvm.testing.assert_allclose(o, t)
Exemplo n.º 27
0
    def test_scalars(self):
        # Create 2 inputs
        X = helper.make_tensor_value_info('A', TensorProto.INT32, [])
        Y = helper.make_tensor_value_info('B', TensorProto.INT32, [])
        # Create one output
        Z = helper.make_tensor_value_info('C', TensorProto.INT32, [])
        # Create a node
        node_def = helper.make_node('Add', ['A', 'B'], ['C'])

        # Create the model
        graph_def = helper.make_graph([node_def], "scalar-model", [X, Y], [Z])
        onnx_model = helper.make_model(graph_def,
                                       producer_name='onnx-example')

        model = Model()
        model.BuildFromOnnxModel(onnx_model)
        schedule = model.OptimizeSchedule()
        schedule = schedule.replace('\n', ' ')
        expected_schedule = r'// Target: .+// MachineParams: .+// Delete this line if not using Generator Pipeline pipeline = get_pipeline\(\);.+Func C = pipeline.get_func\(2\);.+{.+}.+'
        self.assertRegex(schedule, expected_schedule)

        input1 = np.random.randint(-10, 10, size=())
        input2 = np.random.randint(-10, 10, size=())
        outputs = model.run([input1, input2])
        self.assertEqual(1, len(outputs))
        output = outputs[0]
        expected = input1 + input2
        np.testing.assert_allclose(expected, output)
Exemplo n.º 28
0
 def test_topk(self):  # type: () -> None
     graph = self._make_graph(
         [('x', TensorProto.FLOAT, (3, 4, 5, 10))],
         [make_node('TopK', ['x'], ['y', 'z'], k=2, axis=2)],
         [])
     self._assert_inferred(graph,
                           [make_tensor_value_info('y', TensorProto.FLOAT, (3, 4, 2, 10)),
                            make_tensor_value_info('z', TensorProto.INT64, (3, 4, 2, 10))])
Exemplo n.º 29
0
 def test_GLU_partial(self):  # type: () -> None
     graph = self._make_graph(
         [('x', TensorProto.FLOAT, (5, 6, 7))],
         [make_node('Split', ['x'], ['y', 'z'], axis=1),
          make_node('Sigmoid', ['z'], ['a'])],
         [])
     self._assert_inferred(graph, [make_tensor_value_info('y', TensorProto.FLOAT, (5, 3, 7)),
                                   make_tensor_value_info('z', TensorProto.FLOAT, (5, 3, 7)),
                                   make_tensor_value_info('a', TensorProto.FLOAT, (5, 3, 7))])
Exemplo n.º 30
0
 def _rnn_forward(self, seqlen, batchsize, inpsize, hiddensize):  # type: (int, int, int, int) -> None
     graph = self._make_graph(
         [('x', TensorProto.FLOAT, (seqlen, batchsize, inpsize)),
          ('w', TensorProto.FLOAT, (1, hiddensize, inpsize)),
          ('r', TensorProto.FLOAT, (1, hiddensize, hiddensize))],
         [make_node('RNN', ['x', 'w', 'r'], ['all', 'last'], hidden_size=hiddensize)],
         [])
     self._assert_inferred(graph, [
         make_tensor_value_info('all', TensorProto.FLOAT, (seqlen, 1, batchsize, hiddensize)),
         make_tensor_value_info('last', TensorProto.FLOAT, (1, batchsize, hiddensize))])
    def test_matmul_integer(self):
        if legacy_opset_pre_ver(10):
            raise unittest.SkipTest(
                "ONNX version {} doesn't support MatMulInteger.".format(
                    defs.onnx_opset_version()))

        node_def = helper.make_node("MatMulInteger",
                                    ["A", "B", "a_zero_point", "b_zero_point"],
                                    ["Z"])
        # A & B are 3-D tensor and a_zero_point & b_zero_point are scalar
        A = self._get_rnd_int(-20, 20, shape=(2, 3, 4), dtype=np.int8)
        B = self._get_rnd_int(-20, 20, shape=(2, 4, 6), dtype=np.int8)
        a_zero_point = self._get_rnd_int(-20, 20, dtype=np.int8)
        b_zero_point = self._get_rnd_int(-20, 20, dtype=np.int8)
        A_minus_zero_point = np.subtract(A.astype(np.int32),
                                         a_zero_point.astype(np.int32))
        B_minus_zero_point = np.subtract(B.astype(np.int32),
                                         b_zero_point.astype(np.int32))
        z = np.matmul(A_minus_zero_point, B_minus_zero_point)
        graph_def = helper.make_graph(
            [node_def],
            name="test_unknown_shape",
            inputs=[
                helper.make_tensor_value_info("A", TensorProto.INT8,
                                              [None, None, None]),
                helper.make_tensor_value_info("B", TensorProto.INT8,
                                              [None, None, None]),
                helper.make_tensor_value_info("a_zero_point", TensorProto.INT8,
                                              []),
                helper.make_tensor_value_info("b_zero_point", TensorProto.INT8,
                                              [])
            ],
            outputs=[
                helper.make_tensor_value_info("Z", TensorProto.INT32,
                                              [None, None, None])
            ])
        tf_rep = onnx_graph_to_tensorflow_rep(graph_def)
        output = tf_rep.run({
            "A": A,
            "B": B,
            "a_zero_point": a_zero_point,
            "b_zero_point": b_zero_point
        })
        np.testing.assert_almost_equal(output["Z"], z)
        # A & B are 4-D tensor and a_zero_point & b_zero_point are 1-D tensor
        A = self._get_rnd_int(-20, 20, shape=(2, 5, 3, 4), dtype=np.int8)
        B = self._get_rnd_int(-20, 20, shape=(2, 1, 4, 6), dtype=np.int8)
        a_zero_point = self._get_rnd_int(-20,
                                         20,
                                         shape=(A.shape[-2]),
                                         dtype=np.int8)
        b_zero_point = self._get_rnd_int(-20,
                                         20,
                                         shape=(B.shape[-1]),
                                         dtype=np.int8)
        a_zero_point_with_reshape = np.reshape(a_zero_point, [A.shape[-2], 1])
        A_minus_zero_point = np.subtract(
            A.astype(np.int32), a_zero_point_with_reshape.astype(np.int32))
        B_minus_zero_point = np.subtract(B.astype(np.int32),
                                         b_zero_point.astype(np.int32))
        z = np.matmul(A_minus_zero_point, B_minus_zero_point)
        graph_def = helper.make_graph(
            [node_def],
            name="test_unknown_shape",
            inputs=[
                helper.make_tensor_value_info("A", TensorProto.INT8,
                                              [None, None, None, None]),
                helper.make_tensor_value_info("B", TensorProto.INT8,
                                              [None, None, None, None]),
                helper.make_tensor_value_info("a_zero_point", TensorProto.INT8,
                                              [None]),
                helper.make_tensor_value_info("b_zero_point", TensorProto.INT8,
                                              [None])
            ],
            outputs=[
                helper.make_tensor_value_info("Z", TensorProto.INT32,
                                              [None, None, None, None])
            ])
        tf_rep = onnx_graph_to_tensorflow_rep(graph_def)
        output = tf_rep.run({
            "A": A,
            "B": B,
            "a_zero_point": a_zero_point,
            "b_zero_point": b_zero_point
        })
        np.testing.assert_almost_equal(output["Z"], z)
Exemplo n.º 32
0
    def parseModel(self, domain, graph, expInput=None, expOutput=None):
        order, expanded_order = graph.topologicalSort()
        index = 0

        #Inputs
        inputs = list()

        #inits
        initializers = list()

        #Nodes
        nodes = list()
        #         print(len(expanded_order))
        for id, value in expanded_order.items():
            index = index + 1
            node = graph.nodes.get(id)
            name = node.type
            m = node.params
            l = node.learned_params
            #             print(id, index, name, m)

            # it's important that the values in input and output are all string
            #             layerName = prefix+"_"+str(id)
            layerName = str(id)
            input = list(map(str, value['prior']))
            if expOutput:
                expOutputNum = str(expOutput[0])
                input = [expOutputNum + "_" + s for s in input]
                layerName = expOutputNum + "_" + layerName

            if expInput:
                if len(input) == 0:
                    input = expInput

            if expOutput and index == len(expanded_order):
                output = expOutput
                #XXX This handles the output of nested sequential modules
                # to come back into normal flow of ids
                layerName = expOutputNum  #XXX
            else:
                output = [layerName]
            # for first node add a dummy input
            if len(input) == 0:
                input = ['X']
                inputs.append(
                    helper.make_tensor_value_info('X', TensorProto.FLOAT, [1]))

            if m.get('in_channels'):
                in_channels = m.get('in_channels')
            else:
                in_channels = 1

            if m.get('out_channels'):
                out_channels = m.get('out_channels')
            else:
                out_channels = 1

            if m.get('num_features'):
                num_features = m.get('num_features')
            else:
                num_features = 1

            if m.get('in_features'):
                in_features = m.get('in_features')
            else:
                in_features = 1

            if m.get('out_features'):
                out_features = m.get('out_features')
            else:
                out_features = 1

            if m.get('p'):
                ratio = m.get('p')
            else:
                ratio = 0.1

            if m.get('kernel_size'):
                kernel_size = m.get('kernel_size')
                if type(kernel_size) == tuple:
                    kernel_size = list(kernel_size)
                else:
                    kernel_size = [kernel_size, kernel_size]
            else:
                kernel_size = [1, 1]

            if m.get('stride'):
                stride = m.get('stride')
                if type(stride) == tuple:
                    stride = list(stride)
                else:
                    stride = [stride, stride]
            else:
                stride = [1, 1]

            if m.get('padding'):
                padding = m.get('padding')
                if type(padding) == tuple:
                    padding = list(padding)
                    padding.extend(padding)
                else:
                    padding = [padding, padding, padding, padding]
            else:
                padding = [0, 0, 0, 0]

            if m.get('subgraph'):
                subgraph = m.get('subgraph')

            # copy the network weights
            weight = l.get('weight')
            bias = l.get('bias')
            running_mean = l.get('running_mean')
            running_var = l.get('running_var')

            #helper.make_tensor(name='a',data_type=TensorProto.FLOAT, dims=(1,), vals=np.ones(1).tolist())
            if name == 'Conv2d':
                learned_input = [
                    "learned_" + layerName + "_W",
                    "learned_" + layerName + "_B"
                ]
                input.extend(learned_input)

                # declare learned parameters
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_W", TensorProto.FLOAT, [
                            out_channels, in_channels, kernel_size[0],
                            kernel_size[1]
                        ]))
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_B", TensorProto.FLOAT,
                        [out_channels]))

                # initialize learned parameters with existing weights
                if self.isValid(weight):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_W",
                                           TensorProto.FLOAT,
                                           dims=[
                                               out_channels, in_channels,
                                               kernel_size[0], kernel_size[1]
                                           ],
                                           vals=self.toTensor(weight)))
                if self.isValid(bias):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_B",
                                           TensorProto.FLOAT,
                                           dims=[out_channels],
                                           vals=self.toTensor(bias)))

                nodes.append(
                    helper.make_node("Conv",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain,
                                     kernel_shape=kernel_size,
                                     strides=stride,
                                     pads=padding,
                                     dilations=[1, 1],
                                     group=1))
            elif name == 'BatchNorm2d':
                learned_input = [
                    "learned_" + layerName + "_W",
                    "learned_" + layerName + "_B",
                    "learned_" + layerName + "_M",
                    "learned_" + layerName + "_V"
                ]
                input.extend(learned_input)

                # declare learned parameters
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_W", TensorProto.FLOAT,
                        [num_features]))
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_B", TensorProto.FLOAT,
                        [num_features]))
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_M", TensorProto.FLOAT,
                        [num_features]))
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_V", TensorProto.FLOAT,
                        [num_features]))

                # initialize learned parameters with existing weights
                if self.isValid(weight):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_W",
                                           TensorProto.FLOAT, [num_features],
                                           vals=self.toTensor(weight)))
                if self.isValid(bias):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_B",
                                           TensorProto.FLOAT, [num_features],
                                           vals=self.toTensor(bias)))
                if self.isValid(running_mean):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_M",
                                           TensorProto.FLOAT, [num_features],
                                           vals=self.toTensor(running_mean)))
                if self.isValid(running_var):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_V",
                                           TensorProto.FLOAT, [num_features],
                                           vals=self.toTensor(running_var)))

                nodes.append(
                    helper.make_node("BatchNormalization",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain,
                                     epsilon=9.99999974737875e-06,
                                     momentum=1))
            elif name == 'ReLU':
                nodes.append(
                    helper.make_node("Relu",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'Sigmoid':
                nodes.append(
                    helper.make_node("Sigmoid",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'MaxPool2d':
                nodes.append(
                    helper.make_node("MaxPool",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain,
                                     kernel_shape=[3, 3],
                                     pads=[0, 0, 0, 0],
                                     strides=[2, 2]))
            elif name == 'AvgPool2d':
                nodes.append(
                    helper.make_node("AveragePool",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain,
                                     kernel_shape=[3, 3],
                                     pads=[0, 0, 0, 0],
                                     strides=[2, 2]))
            elif name == 'Linear':
                learned_input = [layerName + "_W", layerName + "_B"]
                input.extend(learned_input)

                # declare learned parameters
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_W", TensorProto.FLOAT,
                        [out_features, in_features]))
                inputs.append(
                    helper.make_tensor_value_info(
                        "learned_" + layerName + "_B", TensorProto.FLOAT,
                        [out_features]))

                # initialize learned parameters with existing weights
                if self.isValid(weight):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_W",
                                           TensorProto.FLOAT,
                                           [out_features, in_features],
                                           vals=self.toTensor(weight)))
                if self.isValid(bias):
                    initializers.append(
                        helper.make_tensor("learned_" + layerName + "_B",
                                           TensorProto.FLOAT, [out_features],
                                           vals=self.toTensor(bias)))

                nodes.append(
                    helper.make_node("Gemm",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain,
                                     alpha=1,
                                     beta=1,
                                     transB=1))
            elif name == 'Dropout':
                nodes.append(
                    helper.make_node("Dropout",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain,
                                     ratio=ratio))
            elif name == 'Softmax':
                nodes.append(
                    helper.make_node("Softmax",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'Identity':
                nodes.append(
                    helper.make_node("Identity",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'Reshape':
                nodes.append(
                    helper.make_node("Reshape",
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'BCELoss':
                nodes.append(
                    helper.make_node(name,
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'MSELoss':
                nodes.append(
                    helper.make_node(name,
                                     input,
                                     output,
                                     name=layerName,
                                     domain=domain))
            elif name == 'Sequential':
                sub_nodes, sub_inputs, sub_outputs, sub_initializers = self.parseModel(
                    domain, subgraph, input, output)
                #                 onnx_graph = helper.make_graph(sub_nodes, model_name", sub_inputs, sub_outputs)
                #                 print(helper.printable_graph(onnx_graph))
                nodes.extend(sub_nodes)
                inputs.extend(sub_inputs)
                initializers.extend(sub_initializers)
            else:
                # Group or Sequential nodes
                if node.group == True:
                    sub_nodes, sub_inputs, sub_outputs, sub_initializers = self.parseModel(
                        domain, subgraph, input, output)
                    nodes.extend(sub_nodes)
                    inputs.extend(sub_inputs)
                    initializers.extend(sub_initializers)
                else:
                    print('Not Implement', name)

        # Outputs
        outputs = list()
        outputs.append(
            helper.make_tensor_value_info(layerName, TensorProto.FLOAT, [1]))
        return nodes, inputs, outputs, initializers
Exemplo n.º 33
0
  def test_sequence_ops(self):
    # test SequenceConstruct and SequenceAt
    a = np.random.randn(2, 1, 2).astype(np.float32)
    b = np.random.randn(1, 1, 2).astype(np.float32)
    c = np.random.randn(3, 1, 2).astype(np.float32)
    seq_construct_node = helper.make_node('SequenceConstruct', ['a', 'b', 'c'],
                                          ['S'])
    seq_at_node = helper.make_node('SequenceAt', ['S', 'at'], ['Y'])
    out_value_info = helper.make_tensor_value_info('Y', onnx.TensorProto.FLOAT,
                                                   [None])
    a_value_info = helper.make_tensor_value_info('a', onnx.TensorProto.FLOAT,
                                                 [2, 1, 2])
    b_value_info = helper.make_tensor_value_info('b', onnx.TensorProto.FLOAT,
                                                 [1, 1, 2])
    c_value_info = helper.make_tensor_value_info('c', onnx.TensorProto.FLOAT,
                                                 [3, 1, 2])
    at_value_info = helper.make_tensor_value_info('at', onnx.TensorProto.INT32,
                                                  [])

    graph = helper.make_graph(
        [seq_construct_node, seq_at_node],
        name='seq_construct_at_test',
        inputs=[a_value_info, b_value_info, c_value_info, at_value_info],
        outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'at': 0})
    np.testing.assert_almost_equal(output["Y"], a)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'at': -2})
    np.testing.assert_almost_equal(output["Y"], b)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'at': 2})
    np.testing.assert_almost_equal(output["Y"], c)

    # test SequenceEmpty, SequenceInsert, and SequenceAt
    p = np.int32(0)
    seq_empty_node = helper.make_node('SequenceEmpty', [], ['S'])
    seq_insert_node1 = helper.make_node('SequenceInsert', ['S', 'a'], ['S1'])
    seq_insert_node2 = helper.make_node('SequenceInsert', ['S1', 'b'], ['S2'])
    seq_insert_node3 = helper.make_node('SequenceInsert', ['S2', 'c', 'p'],
                                        ['S3'])
    seq_at_node = helper.make_node('SequenceAt', ['S3', 'at'], ['Y'])

    p_value_info = helper.make_tensor_value_info('p', onnx.TensorProto.INT32,
                                                 [])

    graph = helper.make_graph([
        seq_empty_node, seq_insert_node1, seq_insert_node2, seq_insert_node3,
        seq_at_node
    ],
                              name='seq_empty_insert_at_test',
                              inputs=[
                                  a_value_info, b_value_info, c_value_info,
                                  p_value_info, at_value_info
                              ],
                              outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'p': p, 'at': 0})
    np.testing.assert_almost_equal(output["Y"], c)

    # test SequenceConstruct, SequenceErase, and SequenceLength
    seq_construct_node = helper.make_node('SequenceConstruct', ['a', 'b', 'c'],
                                          ['S'])
    seq_erase_node = helper.make_node('SequenceErase', ['S', 'p'], ['S1'])
    seq_length_node = helper.make_node('SequenceLength', ['S1'], ['Y'])

    graph = helper.make_graph(
        [seq_construct_node, seq_erase_node, seq_length_node],
        name='seq_construct_erase_length_test',
        inputs=[a_value_info, b_value_info, c_value_info, p_value_info],
        outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'p': p})
    np.testing.assert_almost_equal(output["Y"], 2)

    # test SequenceConstruct and SequenceErase
    seq_construct_node = helper.make_node('SequenceConstruct', ['a', 'b', 'c'],
                                          ['S'])
    seq_erase_node = helper.make_node('SequenceErase', ['S', 'p'], ['S1'])
    seq_at_node = helper.make_node('SequenceAt', ['S1', 'at'], ['Y'])

    graph = helper.make_graph([seq_construct_node, seq_erase_node, seq_at_node],
                              name='seq_construct_erase_test',
                              inputs=[
                                  a_value_info, b_value_info, c_value_info,
                                  p_value_info, at_value_info
                              ],
                              outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'p': p, 'at': 0})
    np.testing.assert_almost_equal(output["Y"], b)
    output = tf_rep.run({'a': a, 'b': b, 'c': c, 'p': p, 'at': 1})
    np.testing.assert_almost_equal(output["Y"], c)

    # test SequenceConstruct and ConcatFromSequence
    seq_construct_node = helper.make_node('SequenceConstruct', ['a', 'b', 'c'],
                                          ['S'])
    concat_from_seq_node = helper.make_node('ConcatFromSequence', ['S'], ['Y'],
                                            axis=1)
    a = np.array([[1, 2],[3, 4]]).astype(np.float32)
    b = np.array([[5, 6],[7, 8]]).astype(np.float32)
    c = np.array([[9, 10],[11, 12]]).astype(np.float32)
    a_value_info = helper.make_tensor_value_info('a', onnx.TensorProto.FLOAT,
                                                 [2, 2])
    b_value_info = helper.make_tensor_value_info('b', onnx.TensorProto.FLOAT,
                                                 [2, 2])
    c_value_info = helper.make_tensor_value_info('c', onnx.TensorProto.FLOAT,
                                                 [2, 2])

    graph = helper.make_graph([seq_construct_node, concat_from_seq_node],
                              name='seq_construct_concat_test',
                              inputs=[a_value_info, b_value_info, c_value_info],
                              outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'b': b, 'c': c})
    d = np.concatenate((a, b, c), axis=1).astype(np.float32)
    np.testing.assert_almost_equal(output["Y"], d)

    # test SplitToSequence and SequenceAt
    a = np.array([[1, 2, 3, 4, 5, 6, 7], [11, 12, 13, 14, 15, 16, 17],
                  [21, 22, 23, 24, 25, 26, 27]]).astype(np.float32)
    b = np.int32([2, 1])
    seq_split_node = helper.make_node('SplitToSequence', ['a', 'b'], ['S'])
    seq_at_node = helper.make_node('SequenceAt', ['S', 'at'], ['Y'])
    a_value_info = helper.make_tensor_value_info('a', onnx.TensorProto.FLOAT,
                                                 [3, 7])
    b_value_info = helper.make_tensor_value_info('b', onnx.TensorProto.INT32,
                                                 [2])
    at_value_info = helper.make_tensor_value_info('at', onnx.TensorProto.INT32,
                                                  [])

    graph = helper.make_graph(
        [seq_split_node, seq_at_node],
        name='split_to_seq_test',
        inputs=[a_value_info, b_value_info, at_value_info],
        outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'b': b, 'at': 1})
    np.testing.assert_almost_equal(output["Y"], np.split(a, [2, 3])[1])

    axis = 1
    seq_split_node = helper.make_node('SplitToSequence', ['a'], ['S'],
                                      axis=axis)
    seq_at_node = helper.make_node('SequenceAt', ['S', 'at'], ['Y'])
    at_value_info = helper.make_tensor_value_info('at', onnx.TensorProto.INT32,
                                                  [])

    graph = helper.make_graph([seq_split_node, seq_at_node],
                              name='split_to_seq_test',
                              inputs=[a_value_info, at_value_info],
                              outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'at': 0})
    np.testing.assert_almost_equal(output["Y"], np.split(a, 7, axis=1)[0])

    seq_split_node = helper.make_node('SplitToSequence', ['a'], ['S'],
                                      keepdims=0)
    seq_at_node = helper.make_node('SequenceAt', ['S', 'at'], ['Y'])
    at_value_info = helper.make_tensor_value_info('at', onnx.TensorProto.INT32,
                                                  [])

    graph = helper.make_graph([seq_split_node, seq_at_node],
                              name='split_to_seq_test',
                              inputs=[a_value_info, at_value_info],
                              outputs=[out_value_info])
    model = helper.make_model(graph, producer_name='backend-test')
    tf_rep = prepare(model)
    output = tf_rep.run({'a': a, 'at': 0})
    expected = [np.squeeze(res) for res in np.split(a, 3)]
    np.testing.assert_almost_equal(output["Y"], expected[0])
Exemplo n.º 34
0
    def create_reduce_lp(self, shape, axes, keep_dims, reduce_p, ir_version):
        """
            ONNX net                              IR net

            Input->ReduceLX(axes)->Output   =>    Input->ReduceLX

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        output_shape = shape.copy()
        _axes = axes.copy() if axes is not None else list(range(len(shape)))
        for axis in _axes:
            output_shape[axis] = 1

        if not keep_dims:
            output_shape = [dim for dim in output_shape if dim != 1]

        input = helper.make_tensor_value_info('input', TensorProto.FLOAT, shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT, output_shape)

        args = dict(keepdims=keep_dims)
        if axes:
            args['axes'] = axes
        node_def = onnx.helper.make_node(
            "ReduceL" + str(reduce_p),
            inputs=['input'],
            outputs=['output'],
            **args
        )

        # Create the graph (GraphProto)
        graph_def = helper.make_graph(
            [node_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        onnx_net = helper.make_model(graph_def, producer_name='test_model')

        #
        #   Create reference IR net
        #   Please, specify 'type': 'Input' for input node
        #   Moreover, do not forget to validate ALL layer attributes!!!
        #

        ref_net = None
        if check_ir_version(10, None, ir_version):
            nodes_attributes = {
                'input': {'kind': 'op', 'type': 'Parameter'},
                'input_data': {'shape': shape, 'kind': 'data'},
                'input_data_1': {'shape': [len(_axes)], 'value': _axes, 'kind': 'data'},
                'const_1': {'kind': 'op', 'type': 'Const'},
                'const_data_1': {'shape': [len(_axes)], 'kind': 'data'},
                'reduce': {'kind': 'op', 'type': "ReduceL" + str(reduce_p), 'keep_dims': keep_dims},
                'reduce_data': {'shape': output_shape, 'kind': 'data'},
                'result': {'kind': 'op', 'type': 'Result'}
            }

            ref_net = build_graph(nodes_attributes,
                                  [('input', 'input_data'),
                                   ('input_data_1', 'const_1'),
                                   ('const_1', 'const_data_1'),
                                   ('input_data', 'reduce'),
                                   ('const_data_1', 'reduce'),
                                   ('reduce', 'reduce_data'),
                                   ('reduce_data', 'result')
                                   ])

        return onnx_net, ref_net
Exemplo n.º 35
0
def test_cast_errors():
    from onnx.onnx_cpp2py_export.checker import ValidationError

    np.random.seed(133391)
    input_data = np.ceil(np.random.rand(2, 3, 4) * 16)

    # missing 'to' attribute
    node = onnx.helper.make_node("Cast", inputs=["A"], outputs=["B"])
    input_tensors = [
        make_tensor_value_info(name, onnx.TensorProto.FLOAT, value.shape)
        for name, value in zip(node.input, [input_data])
    ]
    output_tensors = [
        make_tensor_value_info(node.output[0], onnx.TensorProto.FLOAT16,
                               input_data.shape)
    ]  # type: ignore

    graph = make_graph([node], "compute_graph", input_tensors, output_tensors)
    model = make_model(graph, producer_name="NgraphBackend")
    with pytest.raises(ValidationError):
        import_onnx_model(model)

    # unsupported data type representation
    node = onnx.helper.make_node("Cast",
                                 inputs=["A"],
                                 outputs=["B"],
                                 to=1.2345)
    input_tensors = [
        make_tensor_value_info(name, onnx.TensorProto.FLOAT, value.shape)
        for name, value in zip(node.input, [input_data])
    ]
    output_tensors = [
        make_tensor_value_info(node.output[0], onnx.TensorProto.INT32,
                               input_data.shape)
    ]  # type: ignore

    graph = make_graph([node], "compute_graph", input_tensors, output_tensors)
    model = make_model(graph, producer_name="NgraphBackend")
    with pytest.raises(ValidationError):
        import_onnx_model(model)

    # unsupported input tensor data type:
    node = onnx.helper.make_node("Cast",
                                 inputs=["A"],
                                 outputs=["B"],
                                 to=onnx.TensorProto.INT32)
    input_tensors = [
        make_tensor_value_info(name, onnx.TensorProto.COMPLEX64, value.shape)
        for name, value in zip(node.input, [input_data])
    ]
    output_tensors = [
        make_tensor_value_info(node.output[0], onnx.TensorProto.INT32,
                               input_data.shape)
    ]  # type: ignore

    graph = make_graph([node], "compute_graph", input_tensors, output_tensors)
    model = make_model(graph, producer_name="NgraphBackend")
    with pytest.raises((RuntimeError, OVTypeError)):
        import_onnx_model(model)

    # unsupported output tensor data type:
    node = onnx.helper.make_node("Cast",
                                 inputs=["A"],
                                 outputs=["B"],
                                 to=onnx.TensorProto.COMPLEX128)
    input_tensors = [
        make_tensor_value_info(name, onnx.TensorProto.FLOAT, value.shape)
        for name, value in zip(node.input, [input_data])
    ]
    output_tensors = [
        make_tensor_value_info(node.output[0], onnx.TensorProto.COMPLEX128,
                               input_data.shape)
    ]  # type: ignore

    graph = make_graph([node], "compute_graph", input_tensors, output_tensors)
    model = make_model(graph, producer_name="NgraphBackend")
    with pytest.raises(RuntimeError):
        import_onnx_model(model)
Exemplo n.º 36
0
def test_nodes_topologically_sorted():
    # test analysis pass (nodes_topologically_sorted) with different models
    # test with data/onnx/mnist-conv/model.onnx
    raw_m = get_data("finn.data", "onnx/mnist-conv/model.onnx")
    model = ModelWrapper(raw_m)
    ret = model.analysis(ta.nodes_topologically_sorted)
    assert ret["nodes_topologically_sorted"] is True

    # remove first node and add it at the end
    graph = model.graph
    first_node = graph.node[0]
    graph.node.remove(first_node)
    graph.node.append(first_node)
    ret = model.analysis(ta.nodes_topologically_sorted)
    assert ret["nodes_topologically_sorted"] is False

    # test with manually created small network
    Neg_node = oh.make_node("Neg", inputs=["in1"], outputs=["neg1"])
    Round_node = oh.make_node("Round", inputs=["neg1"], outputs=["round1"])

    Ceil_node = oh.make_node("Ceil", inputs=["neg1"], outputs=["ceil1"])
    Add_node = oh.make_node("Add",
                            inputs=["round1", "ceil1"],
                            outputs=["out1"])

    in1 = oh.make_tensor_value_info("in1", TensorProto.FLOAT, [4, 4])
    out1 = oh.make_tensor_value_info("out1", TensorProto.FLOAT, [4, 4])

    graph = oh.make_graph(
        nodes=[Neg_node, Round_node, Ceil_node, Add_node],
        name="simple_graph",
        inputs=[in1],
        outputs=[out1],
        value_info=[
            oh.make_tensor_value_info("neg1", TensorProto.FLOAT, [4, 4]),
            oh.make_tensor_value_info("round1", TensorProto.FLOAT, [4, 4]),
            oh.make_tensor_value_info("ceil1", TensorProto.FLOAT, [4, 4]),
        ],
    )

    onnx_model = oh.make_model(graph, producer_name="simple-model")
    model = ModelWrapper(onnx_model)

    ret = model.analysis(ta.nodes_topologically_sorted)
    assert ret["nodes_topologically_sorted"] is True

    # create same graph but with "wrong" node order
    graph = oh.make_graph(
        nodes=[Round_node, Ceil_node, Neg_node, Add_node],
        name="simple_graph",
        inputs=[in1],
        outputs=[out1],
        value_info=[
            oh.make_tensor_value_info("neg1", TensorProto.FLOAT, [4, 4]),
            oh.make_tensor_value_info("round1", TensorProto.FLOAT, [4, 4]),
            oh.make_tensor_value_info("ceil1", TensorProto.FLOAT, [4, 4]),
        ],
    )

    onnx_model = oh.make_model(graph, producer_name="simple-model")
    model = ModelWrapper(onnx_model)

    ret = model.analysis(ta.nodes_topologically_sorted)
    assert ret["nodes_topologically_sorted"] is False
Exemplo n.º 37
0
    def test_gemm_conversion(self):
        node_def = make_node('Gemm', ['A', 'B', 'C'], ["Y"], alpha=2., beta=3.)
        node_def_broadcast = make_node('Gemm', ['A', 'B', 'C'], ["Y"],
                                       alpha=2.,
                                       beta=3.,
                                       broadcast=1)
        node_def_transpose_b = make_node('Gemm', ['A', 'B', 'C'], ["Y"],
                                         alpha=2.,
                                         beta=3.,
                                         transB=1)

        node_def_transpose_b_broadcast = make_node('Gemm', ['A', 'B', 'C'],
                                                   ["Y"],
                                                   alpha=2.,
                                                   beta=3.,
                                                   transB=1,
                                                   broadcast=1)

        backend = C.Caffe2Backend()

        # without broadcast and without shape info, gemm will be
        # converted to matmul + add
        _, op_strs = backend.convert_node(node_def.SerializeToString())
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])

        # opset7
        # If C is a 1d tensor, gemm will be converted to FC/FCTransposed
        _, op_strs = backend.convert_node(
            node_def_transpose_b.SerializeToString(), [
                make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                       (3, )).SerializeToString()
            ], 7)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'FC'])

        _, op_strs = backend.convert_node(node_def.SerializeToString(), [
            make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                   (3, )).SerializeToString()
        ], 7)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'FCTransposed'])

        # opset6 without broadcast(C should match A*B's dim)
        # The gemm will be converted to matmul + add, since the FC requires c
        # to be 1d tensor.
        _, op_strs = backend.convert_node(node_def.SerializeToString(), [
            make_tensor_value_info("A", onnx.TensorProto.FLOAT,
                                   (3, 2)).SerializeToString(),
            make_tensor_value_info("B", onnx.TensorProto.FLOAT,
                                   (2, 3)).SerializeToString(),
            make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                   (3, 3)).SerializeToString()
        ], 6)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])

        # opset6 with broadcast
        # If C is a 1d tensor, gemm will be converted to FC/FCTransposed
        _, op_strs = backend.convert_node(
            node_def_transpose_b_broadcast.SerializeToString(), [
                make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                       (3, )).SerializeToString()
            ], 6)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'FC'])

        _, op_strs = backend.convert_node(
            node_def_broadcast.SerializeToString(), [
                make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                       (3, )).SerializeToString()
            ], 6)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'FCTransposed'])

        # opset7
        # If C is a scalar and B's last dim is 1, gemm will be converted to FC/FCTransposed
        _, op_strs = backend.convert_node(
            node_def_transpose_b.SerializeToString(), [
                make_tensor_value_info("B", onnx.TensorProto.FLOAT,
                                       (1, 2)).SerializeToString(),
                make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                       (1, )).SerializeToString()
            ], 7)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'FC'])

        _, op_strs = backend.convert_node(node_def.SerializeToString(), [
            make_tensor_value_info("B", onnx.TensorProto.FLOAT,
                                   (2, 1)).SerializeToString(),
            make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                   (1, )).SerializeToString()
        ], 7)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'FCTransposed'])
        # If C is a scalar and B's last dim is not 1, gemm will be converted
        # to matmul + add.
        _, op_strs = backend.convert_node(
            node_def_transpose_b.SerializeToString(), [
                make_tensor_value_info("B", onnx.TensorProto.FLOAT,
                                       (2, 2)).SerializeToString(),
                make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                       (1, )).SerializeToString()
            ], 7)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])
        # If C is a scalar and B's shape info is not available,
        # gemm will be converted to matmul + add.
        _, op_strs = backend.convert_node(
            node_def_transpose_b.SerializeToString(), [
                make_tensor_value_info("C", onnx.TensorProto.FLOAT,
                                       (1, )).SerializeToString()
            ], 7)
        op_names = []
        for s in op_strs:
            op = caffe2_pb2.OperatorDef()
            op.ParseFromString(s)
            op_names.append(op.type)
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])
Exemplo n.º 38
0
def GenerateModel6(model_name):
    nodes = [  # LayerNorm subgraph
        helper.make_node("Shape", ["input_ids"], ["shape1_out"], "shape1"),
        helper.make_node("Gather", ["shape1_out", "indices_0"], ["gather0_out"], "gather0"),
        helper.make_node("Unsqueeze", ["gather0_out", "axes_0"], ["unsqueeze0_out"], "unsqueeze0") if opset_version == 13 \
            else helper.make_node("Unsqueeze", ["gather0_out"], ["unsqueeze0_out"], "unsqueeze0", axes=[0]),
        helper.make_node("Shape", ["input_ids"], ["shape2_out"], "shape2"),
        helper.make_node("Gather", ["shape2_out", "indices_1"], ["gather1_out"], "gather1"),
        helper.make_node("Unsqueeze", ["gather1_out", "axes_0"], ["unsqueeze1_out"], "unsqueeze1")  if opset_version == 13 \
            else helper.make_node("Unsqueeze", ["gather1_out"], ["unsqueeze1_out"], "unsqueeze1", axes=[0]),
        helper.make_node("Concat", ["unsqueeze0_out", "unsqueeze1_out"], ["concat_out"], "concat", axis=0),
        helper.make_node("Reshape", ["concat_out", "reshape_init"], ["reshape_out"], "reshape"),
        helper.make_node("Equal", ["reshape_out", "equal_init"], ["equal_out"], "equal"),
        helper.make_node("Where", ["equal_out", "where_init", "reshape_out"], ["where_out"], "where"),
        helper.make_node("Range", ["start_0", "gather1_out", "delta_1"], ["range_out"], "range"),
        helper.make_node("Unsqueeze", ["range_out", "axes_0"], ["unsqueeze2_out"], "unsqueeze2") if opset_version == 13 \
            else helper.make_node("Unsqueeze", ["range_out"], ["unsqueeze2_out"], "unsqueeze2", axes=[0]),
        helper.make_node("Expand", ["unsqueeze2_out", "where_out"], ["expand_out"], "expand"),
        helper.make_node("Gather", ["pos_embed", "expand_out"], ["pos_gather_out"], "pos_gather"),
        helper.make_node("Gather", ["word_embed", "input_ids"], ["word_gather_out"], "word_gather"),
        helper.make_node("Add", ["word_gather_out", "pos_gather_out"], ["word_add_pos_out"], "word_add_pos"),
        helper.make_node("Gather", ["seg_embed", "segment_ids"], ["seg_gather_out"], "seg_gather"),
        helper.make_node("Add", ["word_add_pos_out", "seg_gather_out"], ["add3_out"], "add3"),
        helper.make_node("LayerNormalization", ["add3_out", "layer_norm_weight", "layer_norm_bias"], ["layernorm_out"],
                         "layernorm",
                         axis=-1,
                         epsion=0.000009999999747378752),
        helper.make_node("Cast", ["input_mask"], ["mask_cast_out"], "mask_cast", to=6),
        helper.make_node("ReduceSum", ["mask_cast_out", "axes_1"], ["mask_index_out"], "mask_index", keepdims=0) if opset_version == 13 \
            else helper.make_node("ReduceSum", ["mask_cast_out"], ["mask_index_out"], "mask_index", axes=[1], keepdims=0),
        helper.make_node("Attention", ["layernorm_out", "qkv_weights", "qkv_bias", "mask_index_out"], ["att_out"],
                         "att",
                         domain="com.microsoft",
                         num_heads=2),
        helper.make_node("MatMul", ["att_out", "matmul_weight"], ["matmul_out"], "matmul"),
        helper.make_node("Add", ["matmul_out", "add_bias"], ["add_out"], "add"),
        helper.make_node("Add", ["add_out", "layernorm_out"], ["add2_out"], "add2")
    ]

    # hidden_size=4, num_heads=2, max_seq_length=3
    initializers = [  # initializers
        helper.make_tensor('indices_0', TensorProto.INT64, [], [0]),
        helper.make_tensor('indices_1', TensorProto.INT64, [], [1]),
        helper.make_tensor('start_0', TensorProto.INT64, [], [0]),
        helper.make_tensor('delta_1', TensorProto.INT64, [], [1]),
        helper.make_tensor('word_embed', TensorProto.FLOAT, [2, 4], [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('pos_embed', TensorProto.FLOAT, [4, 4],
                           [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('seg_embed', TensorProto.FLOAT, [2, 4], [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('layer_norm_weight', TensorProto.FLOAT, [4], [1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('layer_norm_bias', TensorProto.FLOAT, [4], [0.1, 0.2, 0.3, 0.4]),
        helper.make_tensor('qkv_weights', TensorProto.FLOAT, [4, 12], [0.1] * 4 * 12),
        helper.make_tensor('qkv_bias', TensorProto.FLOAT, [12], [0.1] * 12),
        helper.make_tensor('matmul_weight', TensorProto.FLOAT, [4, 4],
                           [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('add_bias', TensorProto.FLOAT, [4], [0.1, 0.2, 0.3, 0.4]),
        helper.make_tensor('reshape_init', TensorProto.INT64, [1], [-1]),
        helper.make_tensor('equal_init', TensorProto.INT64, [2], [-1, -1]),
        helper.make_tensor('where_init', TensorProto.INT64, [2], [1, 1]),
        helper.make_tensor('axes_0', TensorProto.INT64, [1], [0]),
        helper.make_tensor('axes_1', TensorProto.INT64, [1], [1]),
    ]

    graph = helper.make_graph(
        nodes,
        "EmbedLayerNorm_format6",  #name
        [  # inputs
            helper.make_tensor_value_info('input_ids', TensorProto.INT64, ['batch', 3]),
            helper.make_tensor_value_info('segment_ids', TensorProto.INT64, ['batch', 3]),
            helper.make_tensor_value_info('input_mask', TensorProto.INT64, ['batch', 3]),
        ],
        [  # outputs
            helper.make_tensor_value_info('add2_out', TensorProto.FLOAT, ['batch', 3, 4]),
        ],
        initializers)

    model = helper.make_model(graph)
    onnx.save(model, model_name)
Exemplo n.º 39
0
def GenerateModel5(model_name):
    batch_size = 2
    hidden_size = 4
    attention_heads = 2
    sequence_length = 3

    nodes = [
        helper.make_node("Gather", ["word_embed", "input_ids"], ["word_gather_out"], "word_gather", axis=0),
        helper.make_node("Add", ["word_gather_out", "pos_gather_out"], ["word_add_pos_out"], "word_add_pos"),
        helper.make_node("Gather", ["seg_embed", "segment_ids"], ["seg_gather_out"], "seg_gather", axis=0),
        helper.make_node("Add", ["word_add_pos_out", "seg_gather_out"], ["add3_out"], "add3"),
        helper.make_node("LayerNormalization", ["add3_out", "layer_norm_weight", "layer_norm_bias"], ["layernorm_out"],
                         "layernorm",
                         axis=-1,
                         epsion=0.000009999999747378752),
        helper.make_node("Cast", ["input_mask"], ["mask_cast_out"], "mask_cast", to=6),
        helper.make_node("ReduceSum", ["mask_cast_out", "axes_1"], ["mask_index_out"], "mask_index", keepdims=0) if opset_version == 13 \
            else helper.make_node("ReduceSum", ["mask_cast_out"], ["mask_index_out"], "mask_index", axes=[1], keepdims=0),

        helper.make_node("Attention", ["layernorm_out", "qkv_weights", "qkv_bias", "mask_index_out"], ["att_out"],
                         "att",
                         domain="com.microsoft",
                         num_heads=attention_heads),
        helper.make_node("MatMul", ["att_out", "matmul_weight"], ["matmul_out"], "matmul"),
        helper.make_node("Add", ["matmul_out", "add_bias"], ["add_out"], "add"),
        helper.make_node("Add", ["add_out", "layernorm_out"], ["add2_out"], "add2")
    ]

    qkv_weights = [1.0] * hidden_size * (3 * hidden_size)

    initializers = [  # initializers
        helper.make_tensor('word_embed', TensorProto.FLOAT, [2, hidden_size], [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('pos_gather_out', TensorProto.FLOAT, [batch_size, sequence_length, hidden_size], [
            1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 8.0, 7.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,
            8.0, 7.0, 6.0
        ]),
        helper.make_tensor('seg_embed', TensorProto.FLOAT, [2, hidden_size], [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('layer_norm_weight', TensorProto.FLOAT, [hidden_size], [1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('layer_norm_bias', TensorProto.FLOAT, [hidden_size], [0.1, 0.2, 0.3, 0.4]),
        helper.make_tensor('qkv_weights', TensorProto.FLOAT, [hidden_size, 3 * hidden_size], qkv_weights),
        helper.make_tensor('qkv_bias', TensorProto.FLOAT, [3 * hidden_size],
                           [0.1, 0.2, 0.3, 0.4, 0.1, 0.2, 0.3, 0.4, 0.1, 0.2, 0.3, 0.4]),
        helper.make_tensor('matmul_weight', TensorProto.FLOAT, [hidden_size, hidden_size],
                           [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]),
        helper.make_tensor('add_bias', TensorProto.FLOAT, [hidden_size], [0.1, 0.2, 0.3, 0.4]),
        helper.make_tensor('axes_1', TensorProto.INT64, [1], [1]),
    ]

    graph = helper.make_graph(
        nodes,
        "EmbedLayerNorm_format5",  #name
        [  # inputs
            helper.make_tensor_value_info('input_ids', TensorProto.INT64, [batch_size, sequence_length]),
            helper.make_tensor_value_info('segment_ids', TensorProto.INT64, [batch_size, sequence_length]),
            helper.make_tensor_value_info('input_mask', TensorProto.INT64, [batch_size, sequence_length]),
        ],
        [  # outputs
            helper.make_tensor_value_info('add2_out', TensorProto.FLOAT, [batch_size, sequence_length, hidden_size]),
        ],
        initializers)

    model = helper.make_model(graph)
    onnx.save(model, model_name)
Exemplo n.º 40
0
# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

import onnx
from onnx import helper, TensorProto

INPUT_1 = helper.make_tensor_value_info('input1', TensorProto.FLOAT, [1])
OUTPUT = helper.make_tensor_value_info('output', TensorProto.INT8, [1])

nodes = [
    helper.make_node(
        'Cast',
        ['input1'],
        ['output'],
        to=TensorProto.INT8
    ),
]
graph_def = helper.make_graph(
    nodes,
    'cast',
    [INPUT_1],
    [OUTPUT],
)
model_def = helper.make_model(graph_def, producer_name='cast_float_int8.py', opset_imports=[onnx.OperatorSetIdProto(version=12)])
onnx.save(model_def, 'cast_float_int8.onnx')
                         inputs=['A_reshaped', 'mul'],
                         outputs=['equal'],
                         name='equal'),
        helper.make_node(op_type="Where",
                         inputs=['equal', 'const1', 'A_reshaped'],
                         outputs=['where'],
                         name='where'),
        helper.make_node(op_type="Expand",
                         inputs=['B', 'where'],
                         outputs=['C'],
                         name='expand'),
    ],
    name='test-model',
    inputs=[
        # create inputs with symbolic dims
        helper.make_tensor_value_info("A", TensorProto.FLOAT, None),
        helper.make_tensor_value_info("B", TensorProto.FLOAT, None),
    ],
    outputs=[helper.make_tensor_value_info('C', TensorProto.FLOAT, None)],
    initializer=[
        helper.make_tensor('shape', TensorProto.INT64, [1], [-1]),
        helper.make_tensor('neg_one', TensorProto.INT64, [1], [-1]),
    ])

model = helper.make_model(graph_def_0,
                          opset_imports=[helper.make_operatorsetid("", 12)])
onnx.save_model(model, "cpu_fallback_pattern_0.onnx")

graph_def_1 = helper.make_graph(
    nodes=[
        helper.make_node(op_type="Shape",
# onnx_model = onnx.load("../convert/artosyn_paddle/artosyn_paddle_resnet_v2_50_onnx.onnx")
graph = onnx_model.graph

# rewrite the input tensor of graph
input_tensor = graph.input[0]
input_shape = input_tensor.type.tensor_type.shape.dim
input_tensor_new = onnx.helper.make_tensor_value_info(name = input_tensor.name, elem_type = 1, 
                                                      shape = [1, input_shape[1].dim_value, input_shape[2].dim_value, input_shape[3].dim_value])
graph.input.remove(input_tensor)
graph.input.insert(0, input_tensor_new)

# append all tensor infos to graph input
weight_infos = []
tensors = graph.initializer
for i, tensor in enumerate(tensors):
    value_info = helper.make_tensor_value_info(tensor.name, ONNX_DTYPE[tensor.data_type], tensor.dims)
    weight_infos.append(value_info)
    graph.input.insert(i+1, value_info) # because 0 is for placeholder, so start index is 1


node = graph.node
print("---------------------------------")
print(graph.input[0])
print(len(graph.input))
value_info = graph.value_info
print("Before shape inference: \n")
# print(value_info)
print("------------------------------------------------------------")
print("After shape inference: \n")
inferred_onnx_model = shape_inference.infer_shapes(onnx_model)
onnx.checker.check_model(onnx_model)
Exemplo n.º 43
0
    def create_global_net(self, shape, op, ir_version):
        """
            ONNX net                            IR net

            Input->GlobalPooling>Output   =>    Input->Pooling

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        out_shape = np.ones(len(shape))
        out_shape[:2] = np.array(shape)[:2]
        out_shape = out_shape.astype(np.int).tolist()
        input = helper.make_tensor_value_info('input', TensorProto.FLOAT,
                                              shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
                                               out_shape)

        node_def = onnx.helper.make_node(op,
                                         inputs=['input'],
                                         outputs=['output'])

        # Create the graph (GraphProto)
        graph_def = helper.make_graph(
            [node_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        onnx_net = helper.make_model(graph_def, producer_name='test_model')

        #
        #   Create reference IR net
        #

        ref_net = None

        if check_ir_version(10, None, ir_version):
            nodes_attributes = {
                'input': {
                    'kind': 'op',
                    'type': 'Parameter'
                },
                'input_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'input_axes_data': {
                    'kind': 'data',
                    'value': list(range(2, len(shape)))
                },
                'axes': {
                    'kind': 'op',
                    'type': 'Const'
                },
                'axes_data': {
                    'shape': [len(shape) - 2],
                    'kind': 'data'
                },
                'node': {
                    'kind': 'op',
                    'type': None
                },
                'node_data': {
                    'shape': out_shape,
                    'kind': 'data'
                },
                'result': {
                    'kind': 'op',
                    'type': 'Result'
                }
            }

            if op == 'GlobalAveragePool':
                nodes_attributes['node']['type'] = 'ReduceMean'
            else:
                nodes_attributes['node']['type'] = 'ReduceMax'

            ref_net = build_graph(nodes_attributes,
                                  [('input', 'input_data'),
                                   ('input_data', 'node'),
                                   ('input_axes_data', 'axes'),
                                   ('axes', 'axes_data'),
                                   ('axes_data', 'node'),
                                   ('node', 'node_data'),
                                   ('node_data', 'result')])

        return onnx_net, ref_net
Exemplo n.º 44
0
import onnx
from onnx import helper
from onnx import TensorProto, GraphProto, OperatorSetIdProto
from onnx import numpy_helper
import numpy as np

X1 = helper.make_tensor_value_info('x1', TensorProto.INT64, [4, 4])
X2 = helper.make_tensor_value_info('x2', TensorProto.INT64, [4, 1])
X3 = helper.make_tensor_value_info('x3', TensorProto.INT64, [4, 1])
Y = helper.make_tensor_value_info('output', TensorProto.INT64, [4, 4])

less1 = helper.make_node('Less', ['x1', 'x2'], ['less1'], name='less1')
less2 = helper.make_node('Less', ['x1', 'x3'], ['less2'], name='less2')
cast1 = helper.make_node('Cast', ['less1'], ['cast1'], name='cast1', to=9)
and_node = helper.make_node('And', ['cast1', 'less2'], ['and_node'],
                            name='and_node')
cast2 = helper.make_node('Cast', ['and_node'], ['cast2'], name='cast2', to=9)
cast3 = helper.make_node('Cast', ['cast2'], ['cast3'], name='cast3', to=1)
cast4 = helper.make_node('Cast', ['x1'], ['cast4'], name='cast4', to=7)
cast5 = helper.make_node('Cast', ['cast4'], ['cast5'], name='cast5', to=1)
matmul = helper.make_node('MatMul', ['cast3', 'cast5'], ['matmul'],
                          name='matmul')
cast6 = helper.make_node('Cast', ['matmul'], ['cast6'], name='cast6', to=7)
cast7 = helper.make_node('Cast', ['cast6'], ['output'], name='cast7', to=7)

# Create the graph (GraphProto)
graph_def = helper.make_graph([
    less1, less2, cast1, and_node, cast2, cast3, cast4, cast5, matmul, cast6,
    cast7
], 'cast_elimination_model', [X1, X2, X3], [Y])
Exemplo n.º 45
0
    def create_net(self,
                   shape,
                   kernel_shape,
                   pads,
                   strides,
                   op,
                   ir_version,
                   count_include_pad=None,
                   auto_pad=None,
                   storage_order=None,
                   ceil=False,
                   opset=None):
        """
            ONNX net                      IR net

            Input->Pooling>Output   =>    Input->Pooling

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        node_args = dict(kernel_shape=kernel_shape)
        if auto_pad is not None:
            node_args['auto_pad'] = auto_pad
            if auto_pad == 'VALID':
                pads = np.zeros(len(shape[2:]) * 2, dtype=np.int)
        else:
            auto_pad = 'NOTSET'
        if count_include_pad is not None:
            node_args['count_include_pad'] = count_include_pad
        else:
            count_include_pad = 0
        if storage_order is not None:
            node_args['storage_order'] = storage_order
        if pads is not None:
            if auto_pad == 'NOTSET':
                node_args['pads'] = pads
            _pads = np.transpose(np.array(pads).reshape([2, -1]))
        else:
            _pads = np.zeros([len(kernel_shape), 2])
        if strides is not None:
            node_args['strides'] = strides
        else:
            strides = np.ones(len(kernel_shape))

        if ceil:
            node_args['ceil_mode'] = 1

        if auto_pad in ['SAME_UPPER', 'SAME_LOWER']:
            out_spacial_shape = np.ceil(
                np.array(shape[2:], dtype=np.float) / strides)
        else:
            rounding = np.ceil if ceil else np.floor
            out_spacial_shape = rounding(
                (float_array(shape[2:]) + np.add(_pads[:, 0], _pads[:, 1]) -
                 float_array(kernel_shape)) / strides + 1)

        out_shape = np.array(shape)
        out_shape[2:] = out_spacial_shape
        out_shape = out_shape.astype(np.int).tolist()
        concat_axis = 0
        out_concat_shape = out_shape.copy()
        out_concat_shape[concat_axis] *= 2
        input = helper.make_tensor_value_info('input', TensorProto.FLOAT,
                                              shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
                                               out_concat_shape)

        constant = np.random.randint(-127, 127, out_shape).astype(np.float)

        node_def = onnx.helper.make_node(op,
                                         inputs=['input'],
                                         outputs=['pool'],
                                         **node_args)

        node_const_def = onnx.helper.make_node(
            'Constant',
            inputs=[],
            outputs=['const1'],
            value=helper.make_tensor(
                name='const_tensor',
                data_type=TensorProto.FLOAT,
                dims=constant.shape,
                vals=constant.flatten(),
            ),
        )

        node_concat_def = onnx.helper.make_node('Concat',
                                                inputs=['pool', 'const1'],
                                                outputs=['output'],
                                                axis=concat_axis)

        graph_def = helper.make_graph(
            [node_def, node_const_def, node_concat_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        args = dict(producer_name='test_model')
        if opset:
            args['opset_imports'] = [helper.make_opsetid("", opset)]
        onnx_net = helper.make_model(graph_def, **args)

        #
        #   Create reference IR net
        #

        ref_net = None

        if check_ir_version(10, None, ir_version):
            nodes_attributes = {
                'input': {
                    'kind': 'op',
                    'type': 'Parameter'
                },
                'input_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'node': {
                    'kind': 'op',
                    'type': None,
                    'pads_begin': _pads[:, 0] if len(shape) > 3 else _pads[0,
                                                                           0],
                    'pads_end': _pads[:, 1] if len(shape) > 3 else _pads[0, 1],
                    'kernel': kernel_shape[0]
                    if len(kernel_shape) == 1 else kernel_shape,
                    'rounding_type':
                    'ceil' if auto_pad != 'NOTSET' or ceil else 'floor',
                    'auto_pad': None
                },
                'node_data': {
                    'shape': out_shape,
                    'kind': 'data'
                },
                'node_indicies_data': {
                    'shape': out_shape,
                    'kind': 'data'
                },
                'input_const_data': {
                    'kind': 'data',
                    'value': constant.flatten()
                },
                'const': {
                    'kind': 'op',
                    'type': 'Const'
                },
                'const_data': {
                    'shape': out_shape,
                    'kind': 'data'
                },
                'concat': {
                    'kind': 'op',
                    'type': 'Concat',
                    'axis': concat_axis
                },
                'concat_data': {
                    'shape': out_concat_shape,
                    'kind': 'data'
                },
                'result': {
                    'kind': 'op',
                    'type': 'Result'
                }
            }
            if op == 'AveragePool':
                nodes_attributes['node']['type'] = 'AvgPool'
                nodes_attributes['node'][
                    'exclude-pad'] = True if count_include_pad == 0 else False
            else:
                nodes_attributes['node']['type'] = 'MaxPool'

            edges = [('input', 'input_data'), ('input_data', 'node'),
                     ('node', 'node_data', {
                         'out': 0
                     }), ('input_const_data', 'const'),
                     ('const', 'const_data'), ('node_data', 'concat'),
                     ('const_data', 'concat'), ('concat', 'concat_data'),
                     ('concat_data', 'result')]
            if op == "MaxPool":
                edges.append(('node', 'node_indicies_data', {'out': 1}))
            ref_net = build_graph(nodes_attributes,
                                  edges,
                                  nodes_with_edges_only=True)

        return onnx_net, ref_net
Exemplo n.º 46
0
    def test_augment_graph(self):
        ''' TEST_CONFIG_1'''

        #     Conv
        #      |
        #     Clip
        #      |
        #     MatMul

        A = helper.make_tensor_value_info('A', TensorProto.FLOAT, [1, 1, 5, 5])
        B = helper.make_tensor_value_info('B', TensorProto.FLOAT, [1, 1, 3, 3])
        E = helper.make_tensor_value_info('E', TensorProto.FLOAT, [1, 1, 5, 1])
        F = helper.make_tensor_value_info('F', TensorProto.FLOAT, [1, 1, 5, 1])
        conv_node = onnx.helper.make_node('Conv', ['A', 'B'], ['C'],
                                          name='Conv',
                                          kernel_shape=[3, 3],
                                          pads=[1, 1, 1, 1])
        clip_node = onnx.helper.make_node('Clip', ['C'], ['D'], name='Clip')
        matmul_node = onnx.helper.make_node('MatMul', ['D', 'E'], ['F'],
                                            name='MatMul')
        graph = helper.make_graph([conv_node, clip_node, matmul_node],
                                  'test_graph_1', [A, B, E], [F])

        model = helper.make_model(graph)
        test_model_path = './test_model_1.onnx'
        onnx.save(model, test_model_path)

        # Augmenting graph
        data_reader = TestDataReader()
        augmented_model_path = './augmented_test_model_1.onnx'
        calibrater = ONNXCalibrater(test_model_path, data_reader,
                                    ['Conv', 'MatMul'], [], [],
                                    augmented_model_path)
        augmented_model = calibrater.augment_graph()
        onnx.save(augmented_model, augmented_model_path)

        # Checking if each added ReduceMin and ReduceMax node and its output exists
        augmented_model_node_names = [
            node.name for node in augmented_model.graph.node
        ]
        augmented_model_outputs = [
            output.name for output in augmented_model.graph.output
        ]
        added_node_names = [
            'C_ReduceMin', 'C_ReduceMax', 'D_ReduceMin', 'D_ReduceMax',
            'F_ReduceMin', 'F_ReduceMax'
        ]
        added_outputs = [
            'C_ReduceMin', 'C_ReduceMax', 'D_ReduceMin', 'D_ReduceMax',
            'F_ReduceMin', 'F_ReduceMax'
        ]
        # Original 3 nodes + added ReduceMin/Max nodes * 6 (exlude graph input/output)
        self.assertEqual(len(augmented_model_node_names), 9)
        # Original 1 graph output + added outputs * 6
        self.assertEqual(len(augmented_model_outputs), 7)
        for name in added_node_names:
            self.assertTrue(name in augmented_model_node_names)
        for output in added_outputs:
            self.assertTrue(output in augmented_model_outputs)

        print('Finished TEST_CONFIG_1')
        '''TEST_CONFIG_2'''

        #   Conv
        #    |
        #   Conv

        G = helper.make_tensor_value_info('G', TensorProto.FLOAT, [1, 1, 5, 5])
        H = helper.make_tensor_value_info('H', TensorProto.FLOAT, [1, 1, 3, 3])
        J = helper.make_tensor_value_info('J', TensorProto.FLOAT, [1, 1, 3, 3])
        K = helper.make_tensor_value_info('K', TensorProto.FLOAT, [1, 1, 5, 5])
        conv_node_1 = onnx.helper.make_node('Conv', ['G', 'H'], ['I'],
                                            name='Conv',
                                            kernel_shape=[3, 3],
                                            pads=[1, 1, 1, 1])
        conv_node_2 = onnx.helper.make_node('Conv', ['I', 'J'], ['K'],
                                            name='Conv',
                                            kernel_shape=[3, 3],
                                            pads=[1, 1, 1, 1])
        graph = helper.make_graph([conv_node_1, conv_node_2], 'test_graph_2',
                                  [G, H, J], [K])
        model = helper.make_model(graph)
        test_model_path = './test_model_2.onnx'
        onnx.save(model, test_model_path)

        # Augmenting graph
        data_reader = TestDataReader()
        augmented_model_path = './augmented_test_model_2.onnx'
        calibrater = ONNXCalibrater(test_model_path, data_reader,
                                    ['Conv', 'MatMul'], [], [],
                                    augmented_model_path)
        augmented_model = calibrater.augment_graph()
        onnx.save(augmented_model, augmented_model_path)

        augmented_model_node_names = [
            node.name for node in augmented_model.graph.node
        ]
        augmented_model_outputs = [
            output.name for output in augmented_model.graph.output
        ]
        added_node_names = [
            'I_ReduceMin', 'I_ReduceMax', 'K_ReduceMin', 'K_ReduceMax'
        ]
        added_outputs = [
            'I_ReduceMin', 'I_ReduceMax', 'K_ReduceMin', 'K_ReduceMax'
        ]
        # Original 2 nodes + added ReduceMin/Max nodes * 4
        self.assertEqual(len(augmented_model_node_names), 6)
        # Original 1 graph output + added outputs * 4
        self.assertEqual(len(augmented_model_outputs), 5)
        for name in added_node_names:
            self.assertTrue(name in augmented_model_node_names)
        for output in added_outputs:
            self.assertTrue(output in augmented_model_outputs)

        print('Finished TEST_CONFIG_2')
        '''TEST_CONFIG_3'''

        #   Relu
        #    |
        #   Conv  \
        #    |     |
        #   Clip   |
        #    |    /
        #   MatMul

        L = helper.make_tensor_value_info('L', TensorProto.FLOAT, [1, 1, 5, 5])
        N = helper.make_tensor_value_info('N', TensorProto.FLOAT, [1, 1, 3, 3])
        Q = helper.make_tensor_value_info('Q', TensorProto.FLOAT, [1, 1, 5, 5])
        relu_node = onnx.helper.make_node('Relu', ['L'], ['M'], name='Relu')
        conv_node = onnx.helper.make_node('Conv', ['M', 'N'], ['O'],
                                          name='Conv',
                                          kernel_shape=[3, 3],
                                          pads=[1, 1, 1, 1])
        clip_node = onnx.helper.make_node('Clip', ['O'], ['P'], name='Clip')
        matmul_node = onnx.helper.make_node('MatMul', ['P', 'M'], ['Q'],
                                            name='MatMul')
        graph = helper.make_graph(
            [relu_node, conv_node, clip_node, matmul_node], 'test_graph_3',
            [L, N], [Q])
        model = helper.make_model(graph)
        test_model_path = './test_model_3.onnx'
        onnx.save(model, test_model_path)

        # Augmenting graph
        data_reader = TestDataReader()
        augmented_model_path = './augmented_test_model_3.onnx'
        calibrater = ONNXCalibrater(test_model_path, data_reader,
                                    ['Conv', 'MatMul'], [], [],
                                    augmented_model_path)
        augmented_model = calibrater.augment_graph()
        onnx.save(augmented_model, augmented_model_path)

        augmented_model_node_names = [
            node.name for node in augmented_model.graph.node
        ]
        augmented_model_outputs = [
            output.name for output in augmented_model.graph.output
        ]
        added_node_names = [
            'M_ReduceMin', 'M_ReduceMax', 'O_ReduceMin', 'O_ReduceMax',
            'P_ReduceMin', 'P_ReduceMax', 'Q_ReduceMin', 'Q_ReduceMax'
        ]
        added_outputs = [
            'M_ReduceMin', 'M_ReduceMax', 'O_ReduceMin', 'O_ReduceMax',
            'P_ReduceMin', 'P_ReduceMax', 'Q_ReduceMin', 'Q_ReduceMax'
        ]
        # Original 4 nodes + added ReduceMin/Max nodes * 8
        self.assertEqual(len(augmented_model_node_names), 12)
        # Original 1 graph output + added outputs * 8
        self.assertEqual(len(augmented_model_outputs), 9)
        for name in added_node_names:
            self.assertTrue(name in augmented_model_node_names)
        for output in added_outputs:
            self.assertTrue(output in augmented_model_outputs)

        print('Finished TEST_CONFIG_3')
Exemplo n.º 47
0
    def create_reduce_lp_const(self, shape, axes, keep_dims, reduce_p, ir_version):
        """
            ONNX net                              IR net

            Input->ReduceLX(axes)->Output   =>    Input->ReduceLX

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        output_shape = shape.copy()
        _axes = axes.copy() if axes is not None else list(range(len(shape)))
        for axis in _axes:
            output_shape[axis] = 1

        if not keep_dims:
            output_shape = [dim for dim in output_shape if dim != 1]
        if len(output_shape) == 0:
            output_shape = [1]

        concat_axis = 0
        concat_output_shape = output_shape.copy()
        concat_output_shape[concat_axis] *= 2

        input = helper.make_tensor_value_info('input', TensorProto.FLOAT, output_shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT, concat_output_shape)

        constant = np.random.randn(*shape).astype(np.float)

        node_const_def = onnx.helper.make_node(
            'Constant',
            inputs=[],
            outputs=['const1'],
            value=helper.make_tensor(
                name='const_tensor',
                data_type=TensorProto.FLOAT,
                dims=constant.shape,
                vals=constant.flatten(),
            ),
        )

        args = dict(keepdims=keep_dims)
        if axes:
            args['axes'] = axes
        node_def = onnx.helper.make_node(
            "ReduceL" + str(reduce_p),
            inputs=['const1'],
            outputs=['reduce'],
            **args
        )

        node_concat_def = onnx.helper.make_node(
            'Concat',
            inputs=['input', 'reduce'],
            outputs=['output'],
            axis=concat_axis
        )

        # Create the graph (GraphProto)
        graph_def = helper.make_graph(
            [node_const_def, node_def, node_concat_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        onnx_net = helper.make_model(graph_def, producer_name='test_model')

        #
        #   Create reference IR net
        #   Please, specify 'type': 'Input' for input node
        #   Moreover, do not forget to validate ALL layer attributes!!!
        #
        constant = np.power(np.sum(a=np.abs(np.power(constant, reduce_p)), axis=tuple(_axes), keepdims=keep_dims), 1 / reduce_p)
        ref_net = None
        if check_ir_version(10, None, ir_version):
            nodes_attributes = {
                'input': {'kind': 'op', 'type': 'Parameter'},
                'input_data': {'shape': output_shape, 'kind': 'data'},
                'input_const_data': {'kind': 'data', 'value': constant.flatten()},
                'const': {'kind': 'op', 'type': 'Const'},
                'const_data': {'shape': constant.shape, 'kind': 'data'},
                'concat': {'kind': 'op', 'type': 'Concat', 'axis': concat_axis},
                'concat_data': {'shape': concat_output_shape, 'kind': 'data'},
                'result': {'kind': 'op', 'type': 'Result'}
            }
            ref_net = build_graph(nodes_attributes,
                                  [('input', 'input_data'),
                                   ('input_const_data', 'const'),
                                   ('const', 'const_data'),
                                   ('input_data', 'concat'),
                                   ('const_data', 'concat'),
                                   ('concat', 'concat_data'),
                                   ('concat_data', 'result')
                                   ])

        return onnx_net, ref_net
Exemplo n.º 48
0
    def test_quant_param_calculation(self):
        '''TEST_CONFIG_4'''

        #   Relu
        #    |      \
        #   Conv     \
        #    |        \
        #   Relu       |
        #    |       Conv
        #   Conv      /
        #      \     /
        #         |
        #        Add

        input0 = helper.make_tensor_value_info('input0', TensorProto.FLOAT,
                                               [1, 3, 1, 3])
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
                                               [1, 3, 1, 3])

        X1_weight = generate_input_initializer([3, 3, 1, 1], np.float32,
                                               'X1_weight')
        X1_bias = generate_input_initializer([3], np.float32, 'X1_bias')
        X3_weight = generate_input_initializer([3, 3, 1, 1], np.float32,
                                               'X3_weight')
        X3_bias = generate_input_initializer([3], np.float32, 'X3_bias')
        X5_weight = generate_input_initializer([3, 3, 1, 1], np.float32,
                                               'X5_weight')
        X5_bias = generate_input_initializer([3], np.float32, 'X5_bias')

        relu_node_1 = onnx.helper.make_node('Relu', ['input0'], ['X1'],
                                            name='Relu1')
        conv_node_1 = onnx.helper.make_node('Conv',
                                            ['X1', 'X1_weight', 'X1_bias'],
                                            ['X2'],
                                            name='Conv1')
        relu_node_2 = onnx.helper.make_node('Relu', ['X2'], ['X3'],
                                            name='Relu2')
        conv_node_2 = onnx.helper.make_node('Conv',
                                            ['X3', 'X3_weight', 'X3_bias'],
                                            ['X4'],
                                            name='Conv2')
        conv_node_3 = onnx.helper.make_node('Conv',
                                            ['X1', 'X5_weight', 'X5_bias'],
                                            ['X5'],
                                            name='Conv3')
        add_node = onnx.helper.make_node('Add', ['X4', 'X5'], ['output'],
                                         name='Add')

        graph = helper.make_graph([
            relu_node_1, conv_node_1, relu_node_2, conv_node_2, conv_node_3,
            add_node
        ], 'test_graph_4', [input0], [output])
        graph.initializer.add().CopyFrom(X1_weight)
        graph.initializer.add().CopyFrom(X1_bias)
        graph.initializer.add().CopyFrom(X3_weight)
        graph.initializer.add().CopyFrom(X3_bias)
        graph.initializer.add().CopyFrom(X5_weight)
        graph.initializer.add().CopyFrom(X5_bias)

        model = helper.make_model(graph)
        test_model_path = './test_model_4.onnx'
        onnx.save(model, test_model_path)
        data_reader = TestDataReaderSecond()
        augmented_model_path = './augmented_test_model_4.onnx'
        calibrater = ONNXCalibrater(test_model_path, data_reader,
                                    ['Conv', 'MatMul'], [], [],
                                    augmented_model_path)
        augmented_model = calibrater.augment_graph()
        onnx.save(augmented_model, augmented_model_path)

        #test calculation of quantization params
        #TO_DO: check rmin/rmax
        dict_for_quantization = calibrater.get_intermediate_outputs()
        quantization_params_dict = calibrater.calculate_quantization_params(
            dict_for_quantization)

        #check the size of the quantization dictionary
        self.assertEqual(len(quantization_params_dict), 5)

        #check the computation of zp and scale
        for key, value in quantization_params_dict.items():

            self.assertTrue(value is not None)
            self.assertTrue(len(value) == 2)

            thresholds = dict_for_quantization[key]
            rmin = min(thresholds[0], 0)
            rmax = max(thresholds[1], 0)
            if key == 'X2':  #next_node is Relu
                if rmin < 0: rmin = 0

            scale_expected = np.float32((rmax - rmin) /
                                        255 if rmin != rmax else 1)
            zp_expected = np.uint8(
                round(max(0, min(255, (0 - rmin) / scale_expected))))
            zp_actual = value[0]
            scale_actual = value[1]

            self.assertEqual(zp_expected, zp_actual)
            self.assertEqual(scale_expected, scale_actual)

        print('Finished' + ' test calculation of quantization params.')
Exemplo n.º 49
0
# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
import onnx
from onnx import helper, TensorProto

IN8 = helper.make_tensor_value_info('in8', TensorProto.INT8, [3])
IN16 = helper.make_tensor_value_info('in16', TensorProto.BFLOAT16, [3])
OUT8 = helper.make_tensor_value_info('out8', TensorProto.INT8, [3])
OUT16 = helper.make_tensor_value_info('out16', TensorProto.BFLOAT16, [3])

nodes = [
    helper.make_node(
        'Cast',
        ['in8'],
        ['out16'],
        to=getattr(TensorProto, 'BFLOAT16')
    ),
    helper.make_node(
        'Cast',
        ['in16'],
        ['out8'],
        to=getattr(TensorProto, 'INT8')
    ),
]
graph_def = helper.make_graph(
    nodes,
    'unstable_types',
    [IN8, IN16],
    [OUT8, OUT16],
)
model_def = helper.make_model(graph_def, producer_name='unstable_types.py', opset_imports=[onnx.OperatorSetIdProto(version=13)])
onnx.save(model_def, 'unstable_types.onnx')
Exemplo n.º 50
0
    def create_net(self, shape, ir_version):
        """
            ONNX net                    IR net

            Input->Sqrt->Output   =>    Input->Power

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        input = helper.make_tensor_value_info('input', TensorProto.FLOAT,
                                              shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
                                               shape)

        node_def = onnx.helper.make_node('Sqrt',
                                         inputs=['input'],
                                         outputs=['output'])

        # Create the graph (GraphProto)
        graph_def = helper.make_graph(
            [node_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        onnx_net = helper.make_model(graph_def, producer_name='test_model')

        #
        #   Create reference IR net
        #
        ref_net = None
        if check_ir_version(10, None, ir_version):
            nodes_attributes = {
                'input': {
                    'kind': 'op',
                    'type': 'Parameter'
                },
                'input_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'const_indata': {
                    'shape': None,
                    'kind': 'data'
                },
                'const': {
                    'kind': 'op',
                    'type': 'Const'
                },
                'const_data': {
                    'shape': np.ones(len(shape)),
                    'kind': 'data'
                },
                'node': {
                    'kind': 'op',
                    'type': 'Power'
                },
                'node_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'result': {
                    'kind': 'op',
                    'type': 'Result'
                }
            }
            ref_net = build_graph(nodes_attributes, [('input', 'input_data'),
                                                     ('const_indata', 'const'),
                                                     ('const', 'const_data'),
                                                     ('input_data', 'node'),
                                                     ('const_data', 'node'),
                                                     ('node', 'node_data'),
                                                     ('node_data', 'result')])

        return onnx_net, ref_net
Exemplo n.º 51
0
    def graph_def_to_onnx_graph(
        cls,
        graph_def,
        init_func=None,
        constants=None,
        value_info=None,
        graph_name=None,
        verbose=True,
        enforce_no_running=False,
    ):
        if value_info is None: value_info = {}
        if not isinstance(value_info, dict):
            raise ValueError('Please pass value_info as a '
                             'name -> (type, shape) dictionary')

        leaf_tensors = extract_leaf_tensors(graph_def)
        initializer = extract_initializer(graph_def)

        # Check whether we have got type shape info of all input
        missing = (leaf_tensors - set(value_info.keys()) - initializer)
        if missing:
            raise RuntimeError(
                'Could not find value info of inputs: {}'.format(
                    ', '.join(missing)))

        # Check if value_info contains the types/shapes of all the blobs, in
        # which case we don't need to infer them by running the net.
        run_native_graph = False
        for op in graph_def.op:
            for name in itertools.chain(op.input, op.output):
                if name not in value_info:
                    run_native_graph = True
                    break

        ws = None

        # Get the value info of outputs and initializer
        if run_native_graph and not enforce_no_running:
            inputs = {}
            for name, (elem_type, shape) in value_info.items():
                inputs[name] = np.random.randn(*shape).astype(
                    mapping.TENSOR_TYPE_TO_NP_TYPE[elem_type])
            ws, outputs, initializer = native_run_graph(
                graph_def, inputs, initializer, init_func)

        if enforce_no_running:
            # In some cases(e.g. PyTorch), we had ran the graph
            # outputs had been in ``value_info`` already
            import dragon.core.workspace as ws
            initializer = fetch_initializer(initializer)

        # Prepare to make the graph
        onnx_graph = GraphProto()
        onnx_graph.name = graph_name if graph_name else graph_def.name

        # Initializer should also be included in the inputs
        value_info.update(
            {init.name: (init.data_type, init.dims)
             for init in initializer})

        # Add initializer
        onnx_graph.initializer.extend(initializer)

        # Add inputs
        onnx_graph.input.extend(
            make_tensor_value_info(name=name,
                                   elem_type=value_info[name][0],
                                   shape=value_info[name][1])
            for name in leaf_tensors)

        # Add outputs
        onnx_graph.output.extend(
            make_tensor_value_info(name=name,
                                   elem_type=value_info[name][0],
                                   shape=value_info[name][1])
            for name in set(graph_def.output))

        # Add constants
        if constants is not None:
            for k, v in constants.items():
                onnx_graph.initializer.extend(
                    [numpy_helper.from_array(v, name=k)])

        # Add nodes
        shapes, ssa_names, ssa_outputs = {}, {}, defaultdict(int)

        for op in graph_def.op:
            # Get the shape of inputs and outputs
            for name in itertools.chain(op.input, op.output):
                if ws and ws.HasTensor(name):
                    blob = ws.FetchTensor(name)
                    if hasattr(blob, 'shape'):
                        shapes[name] = blob.shape
                else:
                    shapes[name] = value_info[name][1]

            # SSA rewritten
            op, shapes, ssa_names, ssa_outputs = \
                cls._ssa_rewrite(op, shapes, ssa_names, ssa_outputs)

            # Try to translate op => nodes
            nodes, const_tensors = get_nodes_def(op, shapes, ws)

            # Directly convert outputs as const tensors if necessary
            if None in nodes:
                const_tensors = [
                    numpy_helper.from_array(ws.FetchTensor(name), name=name)
                    for name in op.output
                ]
            else:
                onnx_graph.node.extend(nodes)

            # Add const tensors
            if const_tensors is not None:
                onnx_graph.initializer.extend(const_tensors)
                onnx_graph.input.extend([
                    cls._extract_value_info(tensor) for tensor in const_tensors
                ])

        if verbose: print(printable_graph(onnx_graph))

        return onnx_graph
Exemplo n.º 52
0
    def create_net_const(self, shape, precision, ir_version):
        """
            ONNX net                                   IR net

            Input->Concat(+sqrt const)->Output   =>    Input->Concat(+const)

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        concat_axis = 0
        output_shape = shape.copy()
        output_shape[concat_axis] *= 2

        input = helper.make_tensor_value_info('input', TensorProto.FLOAT,
                                              shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
                                               output_shape)

        constant = np.random.rand(*shape).astype(np.float) * 255

        node_const_def = onnx.helper.make_node(
            'Constant',
            inputs=[],
            outputs=['const'],
            value=helper.make_tensor(
                name='const_tensor',
                data_type=TensorProto.FLOAT,
                dims=constant.shape,
                vals=constant.flatten(),
            ),
        )

        node_def = onnx.helper.make_node('Sqrt',
                                         inputs=['const'],
                                         outputs=['sqrt'])

        node_concat_def = onnx.helper.make_node('Concat',
                                                inputs=['input', 'sqrt'],
                                                outputs=['output'],
                                                axis=concat_axis)

        # Create the graph (GraphProto)
        graph_def = helper.make_graph(
            [node_const_def, node_def, node_concat_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        onnx_net = helper.make_model(graph_def, producer_name='test_model')

        #
        #   Create reference IR net
        #
        constant = np.sqrt(constant)
        if precision == 'FP16':
            constant = constant.astype(np.float16)

        ref_net = None
        if check_ir_version(10, None, ir_version):
            nodes_attributes = {
                'input': {
                    'kind': 'op',
                    'type': 'Parameter'
                },
                'input_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'input_const_data': {
                    'kind': 'data',
                    'value': constant.flatten()
                },
                'const': {
                    'kind': 'op',
                    'type': 'Const'
                },
                'const_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'concat': {
                    'kind': 'op',
                    'type': 'Concat',
                    'axis': concat_axis
                },
                'concat_data': {
                    'shape': output_shape,
                    'kind': 'data'
                },
                'result': {
                    'kind': 'op',
                    'type': 'Result'
                }
            }

            ref_net = build_graph(nodes_attributes,
                                  [('input', 'input_data'),
                                   ('input_const_data', 'const'),
                                   ('const', 'const_data'),
                                   ('input_data', 'concat'),
                                   ('const_data', 'concat'),
                                   ('concat', 'concat_data'),
                                   ('concat_data', 'result')])

        return onnx_net, ref_net
Exemplo n.º 53
0
 def _extract_value_info(tensor):
     return make_tensor_value_info(name=tensor.name,
                                   elem_type=tensor.data_type,
                                   shape=tensor.dims)
    def test_slice(self):
        # test case 1 with normal inputs
        axes = [0, 1, 2]
        starts = [0, 0, 0]
        ends = [2, 2, 2]

        if legacy_opset_pre_ver(10):
            node_def = helper.make_node("Slice", ["X"], ["S"],
                                        axes=axes,
                                        starts=starts,
                                        ends=ends)
            graph_def = helper.make_graph(
                [node_def],
                name="test_unknown_shape",
                inputs=[
                    helper.make_tensor_value_info("X", TensorProto.FLOAT,
                                                  [None, None, None])
                ],
                outputs=[
                    helper.make_tensor_value_info("S", TensorProto.FLOAT,
                                                  [None, None, None])
                ])
        else:
            node_def = helper.make_node("Slice",
                                        ["X", "starts", "ends", "axes"], ["S"])
            graph_def = helper.make_graph(
                [node_def],
                name="test_unknown_shape",
                inputs=[
                    helper.make_tensor_value_info("X", TensorProto.FLOAT,
                                                  [None, None, None]),
                    helper.make_tensor_value_info("starts", TensorProto.INT32,
                                                  [None]),
                    helper.make_tensor_value_info("ends", TensorProto.INT32,
                                                  [None]),
                    helper.make_tensor_value_info("axes", TensorProto.INT32,
                                                  [None]),
                ],
                outputs=[
                    helper.make_tensor_value_info("S", TensorProto.FLOAT,
                                                  [None, None, None])
                ])
        tf_rep = onnx_graph_to_tensorflow_rep(graph_def)

        if legacy_opset_pre_ver(10):
            x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
            output = tf_rep.run({"X": x})
            np.testing.assert_almost_equal(output["S"], x[0:2, 0:2, 0:2])
        else:
            x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
            output = tf_rep.run({
                "X": x,
                "starts": starts,
                "ends": ends,
                "axes": axes
            })
            np.testing.assert_almost_equal(output["S"], x[0:2, 0:2, 0:2])

        # test case 2 with negative, out-of-bound and default inputs
        axes = [0, 2]
        starts = [0, -7]
        ends = [-8, 20]
        steps = [1, 1]

        if legacy_opset_pre_ver(10):
            node_def = helper.make_node("Slice", ["X"], ["S"],
                                        axes=axes,
                                        starts=starts,
                                        ends=ends)
            graph_def = helper.make_graph(
                [node_def],
                name="test_unknown_shape",
                inputs=[
                    helper.make_tensor_value_info("X", TensorProto.FLOAT,
                                                  [None, None, None])
                ],
                outputs=[
                    helper.make_tensor_value_info("S", TensorProto.FLOAT,
                                                  [None, None, None])
                ])
        else:
            node_def = helper.make_node(
                "Slice", ["X", "starts", "ends", "axes", "steps"], ["S"])
            graph_def = helper.make_graph(
                [node_def],
                name="test_unknown_shape",
                inputs=[
                    helper.make_tensor_value_info("X", TensorProto.FLOAT,
                                                  [None, None, None]),
                    helper.make_tensor_value_info("starts", TensorProto.INT32,
                                                  [None]),
                    helper.make_tensor_value_info("ends", TensorProto.INT32,
                                                  [None]),
                    helper.make_tensor_value_info("axes", TensorProto.INT32,
                                                  [None]),
                    helper.make_tensor_value_info("steps", TensorProto.INT32,
                                                  [None]),
                ],
                outputs=[
                    helper.make_tensor_value_info("S", TensorProto.FLOAT,
                                                  [None, None, None])
                ])
        tf_rep = onnx_graph_to_tensorflow_rep(graph_def)
        if legacy_opset_pre_ver(10):
            x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
            output = tf_rep.run({"X": x})
            np.testing.assert_almost_equal(output["S"], x[0:-8, :, -7:20])
        else:
            x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
            output = tf_rep.run({
                "X": x,
                "starts": starts,
                "ends": ends,
                "axes": axes,
                "steps": steps
            })
            np.testing.assert_almost_equal(output["S"], x[0:-8, :, -7:20])

        # test case 3 with non-default steps
        axes = [0, 1, 2]
        starts = [0, 0, 0]
        ends = [2, 2, 2]
        steps = [2, -2, -1]

        if not legacy_opset_pre_ver(10):
            x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
            output = tf_rep.run({
                "X": x,
                "starts": starts,
                "ends": ends,
                "axes": axes,
                "steps": steps
            })
            np.testing.assert_almost_equal(output["S"], x[0:2:2, 0:2:-2,
                                                          0:2:-1])
Exemplo n.º 55
0
    def create_net_const(self, shape, scale, precision, ir_version):
        """
            ONNX net                                     IR net

            Input->Concat(+scaled const)->Output   =>    Input->Concat(+const)

        """

        #
        #   Create ONNX model
        #

        import onnx
        from onnx import helper
        from onnx import TensorProto

        concat_axis = 0
        output_shape = shape.copy()
        output_shape[concat_axis] *= 2

        input = helper.make_tensor_value_info('input', TensorProto.FLOAT,
                                              shape)
        output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
                                               output_shape)

        constant = np.random.randint(-127, 127, shape).astype(np.float)
        bias = np.random.randint(-10, 10, shape[1]).astype(np.float)

        node_const_def = onnx.helper.make_node(
            'Constant',
            inputs=[],
            outputs=['const1'],
            value=helper.make_tensor(
                name='const_tensor',
                data_type=TensorProto.FLOAT,
                dims=constant.shape,
                vals=constant.flatten(),
            ),
        )

        node_def = onnx.helper.make_node('ImageScaler',
                                         inputs=['const1'],
                                         outputs=['scale'],
                                         bias=bias,
                                         scale=scale)

        node_concat_def = onnx.helper.make_node('Concat',
                                                inputs=['input', 'scale'],
                                                outputs=['output'],
                                                axis=concat_axis)

        # Create the graph (GraphProto)
        graph_def = helper.make_graph(
            [node_const_def, node_def, node_concat_def],
            'test_model',
            [input],
            [output],
        )

        # Create the model (ModelProto)
        onnx_net = helper.make_model(graph_def, producer_name='test_model')

        #
        #   Create reference IR net
        #
        ir_const = constant * scale + np.expand_dims(np.expand_dims([bias], 2),
                                                     3)
        if precision == 'FP16':
            ir_const = ir_const.astype(np.float16)

        ref_net = None

        return onnx_net, ref_net
Exemplo n.º 56
0
    def _test_overlapping_names(
        self,
        inputs0: List[Text] = ['i0', 'i1'],
        inputs1: List[Text] = ['i2', 'i3'],
        outputs0: List[Text] = ['o0', 'o1'],
        outputs1: List[Text] = ['o2', 'o3'],
        value_info0: List[Text] = ['v0', 'v1'],
        value_info1: List[Text] = ['v2', 'v3'],
        initializer0: List[Text] = ['init0', 'init1'],
        initializer1: List[Text] = ['init2', 'init3'],
        sparse_initializer0: List[Text] = ['sparse_init0', 'sparse_init1'],
        sparse_initializer1: List[Text] = ['sparse_init2', 'sparse_init3'],
    ) -> None:
        n0 = [
            helper.make_node('Identity',
                             inputs=[inputs0[i]],
                             outputs=[outputs0[i]])
            for i in range(len(inputs0))
        ]
        i0 = [
            helper.make_tensor_value_info(inputs0[i], TensorProto.FLOAT, [])
            for i in range(len(inputs0))
        ]
        o0 = [
            helper.make_tensor_value_info(outputs0[i], TensorProto.FLOAT, [])
            for i in range(len(outputs0))
        ]
        vi0 = [
            helper.make_tensor_value_info(value_info0[i], TensorProto.FLOAT,
                                          []) for i in range(len(value_info0))
        ]
        init0 = [
            helper.make_tensor(name=initializer0[i],
                               data_type=TensorProto.INT64,
                               dims=(),
                               vals=[1]) for i in range(len(initializer0))
        ]

        sparse_init0 = [
            _make_sparse_tensor(sparse_initializer0[i])
            for i in range(len(sparse_initializer0))
        ]

        n1 = [
            helper.make_node('Identity',
                             inputs=[inputs1[i]],
                             outputs=[outputs1[i]])
            for i in range(len(inputs1))
        ]
        i1 = [
            helper.make_tensor_value_info(inputs1[i], TensorProto.FLOAT, [])
            for i in range(len(inputs1))
        ]
        o1 = [
            helper.make_tensor_value_info(outputs1[i], TensorProto.FLOAT, [])
            for i in range(len(outputs1))
        ]
        vi1 = [
            helper.make_tensor_value_info(value_info1[i], TensorProto.FLOAT,
                                          []) for i in range(len(value_info1))
        ]
        init1 = [
            helper.make_tensor(name=initializer1[i],
                               data_type=TensorProto.INT64,
                               dims=(),
                               vals=[1]) for i in range(len(initializer1))
        ]
        sparse_init1 = [
            _make_sparse_tensor(sparse_initializer1[i])
            for i in range(len(sparse_initializer1))
        ]

        ops = [helper.make_opsetid("", 10)]
        m0 = helper.make_model(helper.make_graph(
            nodes=n0,
            name='g0',
            inputs=i0,
            outputs=o0,
            value_info=vi0,
            initializer=init0,
            sparse_initializer=sparse_init0),
                               producer_name='test',
                               opset_imports=ops)
        m1 = helper.make_model(helper.make_graph(
            nodes=n1,
            name='g1',
            inputs=i1,
            outputs=o1,
            value_info=vi1,
            initializer=init1,
            sparse_initializer=sparse_init1),
                               producer_name='test',
                               opset_imports=ops)

        overlap = compose.check_overlapping_names(m0.graph, m1.graph)
        i = 0

        overlapping_inputs = list(set(inputs0) & set(inputs1))
        overlapping_outputs = list(set(outputs0) & set(outputs1))
        overlapping_edges = list(set(overlapping_inputs + overlapping_outputs))
        if len(overlapping_edges) > 0:
            self.assertEqual(overlap[i], ('edge', overlapping_edges))
            i += 1

        overlapping_vis = list(set(value_info0) & set(value_info1))
        if len(overlapping_vis) > 0:
            self.assertEqual(overlap[i], ('value_info', overlapping_vis))
            i += 1

        overlapping_init = list(set(initializer0) & set(initializer1))
        if len(overlapping_init) > 0:
            self.assertEqual(overlap[i], ('initializer', overlapping_init))
            i += 1

        overlapping_sparse_init = list(
            set(sparse_initializer0) & set(sparse_initializer1))
        if len(overlapping_sparse_init) > 0:
            expected_overlap = []
            for overlapping_name in overlapping_sparse_init:
                expected_overlap.append(overlapping_name + '_values')
                expected_overlap.append(overlapping_name + '_idx')
            self.assertEqual(overlap[i],
                             ('sparse_initializer', expected_overlap))
            i += 1

        m0_new = compose.add_prefix(m0, prefix='g0/')
        overlap = compose.check_overlapping_names(m0_new.graph, m1.graph)
        self.assertEqual(0, len(overlap))
Exemplo n.º 57
0
    def caffe2_net_to_onnx_graph(cls,
                                 predict_net,
                                 init_net=None,
                                 value_info=None):
        if value_info is None:
            value_info = {}
        if not isinstance(value_info, dict):
            raise ValueError('Please pass value_info as a '
                             'name -> (type, shape) dictionary')

        cls._ssa_rewrite(predict_net, init_net, value_info)

        if init_net:
            initializer = cls.caffe2_init_net_to_initializer(init_net)
            value_info.update({
                init.name: (init.data_type, init.dims)
                for init in initializer
            })
        else:
            initializer = []

        # Check whether we have got type shape info of all input
        missing = (set(list(predict_net.external_input)) -
                   set(value_info.keys()))
        if missing:
            raise RuntimeError(
                'Could not find value info of inputs: {}'.format(
                    ', '.join(missing)))

        inputs = {}
        for name in predict_net.external_input:
            elem_type, shape = value_info[name]
            inputs[name] = np.random.randn(*shape).astype(
                mapping.TENSOR_TYPE_TO_NP_TYPE[elem_type])

        ws, outputs = c2_native_run_net(init_net, predict_net, inputs)

        for name in predict_net.external_output:
            output = outputs[name]
            elem_type = mapping.NP_TYPE_TO_TENSOR_TYPE[output.dtype]
            shape = output.shape
            value_info[name] = (elem_type, shape)

        graph_def = GraphProto()
        graph_def.name = predict_net.name
        graph_def.initializer.extend(initializer)
        # This is a mapping from Caffe2 names to ONNX names
        graph_def.input.extend(
            make_tensor_value_info(name=name,
                                   elem_type=value_info[name][0],
                                   shape=value_info[name][1])
            for name in predict_net.external_input)

        dummy_name(
            cls._all_names_in_net(predict_net)
            | cls._all_names_in_net(init_net))

        for op in predict_net.op:
            shapes = {}
            for name in itertools.chain(op.input, op.output):
                blob = ws.FetchBlob(name)
                if hasattr(blob, 'shape'):
                    shapes[name] = blob.shape
            graph_def.node.extend(cls.caffe2_op_to_onnx_node(op,
                                                             shapes=shapes))

        all_output = set(
            sum((list(node.output) for node in graph_def.node),
                [init.name for init in graph_def.initializer]))
        redundant_output = set(vi.name for vi in graph_def.output) - all_output
        if redundant_output:
            logger.warning(
                'There are graph output not produced by any node or initializer: {}'
                '! Will drop them.'.format(', '.join(redundant_output)))
        graph_def.output.extend(
            make_tensor_value_info(name=name,
                                   elem_type=value_info[name][0],
                                   shape=value_info[name][1])
            for name in predict_net.external_output if name in all_output)

        cls._annotate_consumed(graph_def)
        checker.check_graph(graph_def)
        return graph_def
Exemplo n.º 58
0
def quantitize_graph(g, verbose=False):
    """Quantitize graph."""
    new_weights = []
    quantitized_weights = []
    nodes = []
    remap = {}
    remove = []

    for i, w in enumerate(g.initializer):
        # only quantitize float32
        if w.data_type != onnx_pb.TensorProto.FLOAT:
            continue
        w_np = numpy_helper.to_array(w)
        # only look at sizes >= 32 elements
        if w_np.size < 32:
            continue

        # weights we want to quantitize
        remove.append(i)
        name = w.name
        if verbose:
            log.info("quantitizing %s", name)
        w_quant, zp, scale = eight_bit_quantitize(w_np)
        nw = numpy_helper.from_array(w_quant, name=name)
        if verbose:
            w_dequant = eight_bit_dequantitize(w_quant, zp, scale)
            rtol = np.abs(w_dequant - w_np)
            s = {}
            for j in [1.0, 5.0, 10.0, 20.0]:
                above_rtol = np.sum(rtol > np.abs(j * w_np / 100.)) / w_np.size
                s["> " + str(j) + "%"] = "{:.2f}".format(100. * above_rtol)
            log.info("above_rtol: %s", str(s))
            log.info("raw:   %s", stats(w_np))
            log.info("quant: %s", stats(w_dequant))
        output_name = _compose_quantitize(nodes, new_weights, zp, scale, name)
        remap[name] = output_name
        quantitized_weights.append(nw)

    # few things to do to initializers and graph inputs:

    # 1. remove initializers that got quantitized
    for i in reversed(remove):
        del g.initializer[i]

    # 2. add quantitized to initializers
    g.initializer.extend(new_weights)
    g.initializer.extend(quantitized_weights)

    # 3. modify the type of weights that we quantitized
    modified = {w.name: w for w in quantitized_weights}
    new_inputs = []
    remove = []
    for i, inp in enumerate(g.input):
        w = modified.get(inp.name)
        if w is not None:
            new_inputs.append(
                helper.make_tensor_value_info(w.name, w.data_type, w.dims))
            remove.append(i)
    for i in reversed(remove):
        del g.input[i]

    # 4. add new weights as inputs
    for w in new_weights:
        tv = helper.make_tensor_value_info(w.name, w.data_type, w.dims)
        new_inputs.append(tv)
    g.input.extend(new_inputs)

    # 5. rewrite consumers of the quantitized weights
    for node in g.node:
        for i, name in enumerate(node.input):
            new_name = remap.get(name)
            if new_name is not None:
                node.input[i] = new_name

    # 6. add composed nodes to graph, new nodes in the front
    nodes.extend(g.node)
    del g.node[:]
    g.node.extend(nodes)
    return g
Exemplo n.º 59
0
    def test_overlapping_function_names(self) -> None:
        '''
        Tests error checking when the name of local function entries overlaps
        '''
        ops = [helper.make_opsetid("", 10), helper.make_opsetid("local", 10)]

        def _make_function(
            domain: Text,
            fname: Text,
            inputs: List[Text],
            outputs: List[Text],
            nodes: List[NodeProto],
        ) -> FunctionProto:
            f = FunctionProto()
            f.domain = domain
            f.name = fname
            f.input.extend(inputs)
            f.output.extend(outputs)
            f.node.extend(nodes)
            f.opset_import.extend(ops)
            return f

        ops = [helper.make_opsetid("", 10), helper.make_opsetid("local", 10)]

        g = GraphProto()
        g.input.extend([
            helper.make_tensor_value_info('x0', TensorProto.FLOAT, []),
            helper.make_tensor_value_info('x1', TensorProto.FLOAT, [])
        ])
        g.output.extend([
            helper.make_tensor_value_info('y', TensorProto.FLOAT, []),
        ])
        g.node.extend([
            helper.make_node('f1',
                             domain='local',
                             inputs=['x0', 'x1'],
                             outputs=['y'])
        ])

        g1 = GraphProto()
        g1.CopyFrom(g)
        g1.name = 'g1'
        m1 = helper.make_model(g1, producer_name='test', opset_imports=ops)
        m1.functions.extend([
            _make_function(
                'local', 'f1', ['x0', 'x1'], ['y'],
                [helper.make_node('Add', inputs=['x0', 'x1'], outputs=['y'])])
        ])
        checker.check_model(m1)

        g2 = GraphProto()
        g2.CopyFrom(g)
        g2.name = 'g2'
        m2 = helper.make_model(g2, producer_name='test', opset_imports=ops)
        m2.functions.extend([
            _make_function(
                'local', 'f1', ['x0', 'x1'], ['y'],
                [helper.make_node('Mul', inputs=['x0', 'x1'], outputs=['y'])])
        ])
        checker.check_model(m2)

        m = compose.merge_models(m1,
                                 m2,
                                 io_map=[('y', 'x0'), ('y', 'x1')],
                                 prefix1='m1/',
                                 prefix2='m2/')
        checker.check_model(m)

        nodes = [n.op_type for n in m.graph.node]
        self.assertEqual(['m1/f1', 'm2/f1'], nodes)

        functions = [f.name for f in m.functions]
        self.assertEqual(['m1/f1', 'm2/f1'], functions)

        g3 = GraphProto()
        g3.CopyFrom(g)
        g3.name = 'g3'
        g3.node[0].op_type = 'f2'
        m3 = helper.make_model(g3, producer_name='test', opset_imports=ops)
        m3.functions.extend([
            _make_function('local', 'f1', ['x0', 'x1'], ['y'], [
                helper.make_node('Add', inputs=['x0', 'x1'], outputs=['y0']),
                helper.make_node('Mul', inputs=['x0', 'x1'], outputs=['y1']),
                helper.make_node('Add', inputs=['y0', 'y1'], outputs=['y'])
            ]),
            _make_function('local', 'f2', ['x0', 'x1'], ['y'], [
                helper.make_node(
                    'f1', domain='local', inputs=['x0', 'x1'], outputs=['y0']),
                helper.make_node('Mul', inputs=['x0', 'x1'], outputs=['y1']),
                helper.make_node('Add', inputs=['y0', 'y1'], outputs=['y'])
            ])
        ])
        checker.check_model(m3)

        m = compose.merge_models(m1,
                                 m3,
                                 io_map=[('y', 'x0'), ('y', 'x1')],
                                 prefix1='m1/',
                                 prefix2='m3/')
        checker.check_model(m)

        nodes = [n.op_type for n in m.graph.node]
        self.assertEqual(['m1/f1', 'm3/f2'], nodes)

        functions = [f.name for f in m.functions]
        self.assertEqual(['m1/f1', 'm3/f1', 'm3/f2'], functions)

        self.assertEqual(['Add'], [n.op_type for n in m.functions[0].node])
        self.assertEqual(['Add', 'Mul', 'Add'],
                         [n.op_type for n in m.functions[1].node])
        self.assertEqual(['m3/f1', 'Mul', 'Add'],
                         [n.op_type for n in m.functions[2].node])
Exemplo n.º 60
0
def GenerateModel(model_name):
    nodes = [
        helper.make_node("Gather", ["embed_weights", "input_1"],
                         ["gather_out"], "gather"),
        helper.make_node("Add", ["gather_out", "add_q_weight"], ["add_q_out"],
                         "add_q"),
        helper.make_node("Add", ["gather_out", "add_k_weight"], ["add_k_out"],
                         "add_k"),
        helper.make_node("Add", ["gather_out", "add_v_weight"], ["add_v_out"],
                         "add_v"),
        helper.make_node(
            "Concat",
            ["add_q_out", "add_k_out", "add_v_out"],
            ["concat_out"],
            "concat",
            axis=0,
        ),
        helper.make_node("Add", ["add_qkv_weight", "concat_out"], ["add_out"],
                         "add"),
        helper.make_node(
            "ReduceSum",
            ["add_out"],
            ["predictions"],
            "reduce_sum_1",
            axes=[0],
            keepdims=1,
        ),
    ]

    embed_weights = np.random.uniform(-1, 1, 8000).tolist()

    add_q_weight = [
        -0.23681640625,
        -0.16552734375,
        0.2191162109375,
        -0.1756591796875,
        -0.03460693359375,
        -0.05316162109375,
        -0.336181640625,
        -0.253662109375,
    ]

    add_k_weight = [
        0.0246734619140625,
        0.011993408203125,
        0.0178375244140625,
        0.00998687744140625,
        0.0255126953125,
        0.076416015625,
        -0.040771484375,
        0.0107879638671875,
    ]

    add_v_weight = [
        -0.005893707275390625,
        -0.00916290283203125,
        0.04541015625,
        0.0159454345703125,
        -0.0029163360595703125,
        -0.03472900390625,
        0.0535888671875,
        0.0091094970703125,
    ]

    initializers = [  # initializers
        helper.make_tensor("embed_weights", TensorProto.FLOAT, [1000, 8],
                           embed_weights),
        helper.make_tensor("add_q_weight", TensorProto.FLOAT, [8],
                           add_q_weight),
        helper.make_tensor("add_k_weight", TensorProto.FLOAT, [8],
                           add_k_weight),
        helper.make_tensor("add_v_weight", TensorProto.FLOAT, [8],
                           add_v_weight),
        helper.make_tensor("add_qkv_weight", TensorProto.FLOAT, [1], [1.0]),
    ]

    graph = helper.make_graph(
        nodes,
        "ConcatThreeInputs",  # name
        [
            helper.make_tensor_value_info("input_1", TensorProto.INT64,
                                          ["batch", "seq_len"])
        ],  # inputs
        [  # outputs
            helper.make_tensor_value_info("predictions", TensorProto.FLOAT,
                                          [1, 1, 8]),
        ],
        initializers,
    )

    model = helper.make_model(graph)
    onnx.save(model, model_name)