예제 #1
0
 def convnet():
     """Alternating layout of simple convnet (from image super-resolution).
     """
     bias1 = relay.var('bias1', shape=(64,))
     bias2 = relay.var('bias2', shape=(64,))
     bias3 = relay.var('bias3', shape=(64,))
     bias4 = relay.var('bias4', shape=(64,))
     weight1 = relay.var('weight1', shape=(64, 1, 5, 5))
     weight2 = relay.var('weight2', shape=(64, 64, 3, 3))
     weight3 = relay.var('weight3', shape=(64, 64, 3, 3))
     weight4 = relay.var('weight4', shape=(64, 64, 3, 3))
     data = relay.var("x", shape=(1, 1, 224, 224))
     n00 = relay.nn.conv2d(data, weight1, padding=[2, 2], kernel_size=[5, 5])
     n01 = relay.expand_dims(bias1, axis=1, num_newaxis=2)
     n02 = relay.add(n00, n01)
     n03 = relay.nn.relu(n02)
     n04 = relay.nn.conv2d(n03, weight2, padding=[1, 1], kernel_size=[3, 3])
     n05 = relay.expand_dims(bias2, axis=1, num_newaxis=2)
     n06 = relay.add(n04, n05)
     n07 = relay.nn.relu(n06)
     n08 = relay.nn.conv2d(n07, weight3, padding=[1, 1], kernel_size=[3, 3])
     n09 = relay.expand_dims(bias3, axis=1, num_newaxis=2)
     n10 = relay.add(n08, n09)
     n11 = relay.nn.relu(n10)
     n12 = relay.nn.conv2d(n11, weight4, padding=[1, 1], kernel_size=[3, 3])
     n13 = relay.expand_dims(bias4, axis=1, num_newaxis=2)
     n14 = relay.add(n12, n13)
     n15 = relay.reshape(n14, newshape=[1, 1, 3, 3, 224, 224])
     n16 = relay.transpose(n15, axes=[0, 1, 4, 2, 5, 3])
     net = relay.reshape(n16, newshape=[1, 1, 672, 672])
     args = relay.ir_pass.free_vars(net)
     return relay.Function(args, net)
예제 #2
0
파일: dcgan.py 프로젝트: LANHUIYING/tvm
def get_net(batch_size, random_len=100, oshape=(3, 64, 64), ngf=128, code=None, dtype="float32"):
    """get net of dcgan generator"""
    assert oshape[-1] == 64, "Only support 64x64 image"
    assert oshape[-2] == 64, "Only support 64x64 image"

    code = relay.var("data", dtype=dtype, shape=(batch_size, random_len)) if code is None else code
    dense_weight = relay.var("dense_weight")
    dense = relay.nn.dense(code, weight=dense_weight, units=4*4*ngf*8)
    relu = relay.nn.relu(dense)
    # 4 x 4
    reshape = relay.reshape(relu, newshape=(-1, ngf * 8, 4, 4))
    # 8 x 8
    dc8 = deconv2d_bn_relu(
        reshape, ishape=(ngf * 8, 4, 4), oshape=(ngf * 4, 8, 8), kshape=(4, 4), prefix="g2")
    # 16x16
    dc16 = deconv2d_bn_relu(
        dc8, ishape=(ngf * 4, 8, 8), oshape=(ngf * 2, 16, 16), kshape=(4, 4), prefix="g3")
    # 32x32
    dc32 = deconv2d_bn_relu(
        dc16, ishape=(ngf * 2, 16, 16), oshape=(ngf, 32, 32), kshape=(4, 4), prefix="g4")
    # 64x64
    dc64 = deconv2d(
        dc32, ishape=(ngf, 32, 32), oshape=oshape[-3:], kshape=(4, 4), name="g5_deconv")
    tanh = relay.tanh(dc64)

    args = relay.ir_pass.free_vars(tanh)
    return relay.Function(args, tanh)
예제 #3
0
def test_reshape_infer_type():
    n, t, d1, d2 = 10, 20, 100, 20
    x = relay.var("x", relay.TensorType((n, t, d1, d2), "float32"))
    y = relay.reshape(x, newshape=(n, t, 2000))
    assert "newshape=" in y.astext()
    yy = relay.ir_pass.infer_type(y)
    assert yy.checked_type == relay.TensorType(
        (n, t, 2000), "float32")
예제 #4
0
    def verify_reshape(shape, newshape, oshape):
        x = relay.var("x", relay.TensorType(shape, "float32"))
        z = relay.reshape(x, newshape=newshape)
        zz = relay.ir_pass.infer_type(z)
        assert "newshape=" in z.astext()
        assert zz.checked_type == relay.ty.TensorType(oshape, "float32")

        func = relay.Function([x], z)
        x_data = np.random.uniform(low=-1, high=1, size=shape).astype("float32")
        ref_res = np.reshape(x_data, oshape)
        for target, ctx in ctx_list():
            for kind in ["graph", "debug"]:
                intrp = relay.create_executor(kind, ctx=ctx, target=target)
                op_res = intrp.evaluate(func)(x_data)
                tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-5)
예제 #5
0
    def verify_reshape(shape, newshape, oshape):
        x = relay.var("x", relay.TensorType(shape, "float32"))
        y = relay.var("y", relay.TensorType((len(newshape), ), "int64"))
        z = relay.reshape(x, y)

        func = relay.Function([x, y], z)
        x_data = np.random.uniform(low=-1, high=1,
                                   size=shape).astype("float32")
        x_data = np.ones(shape).astype("float32")
        ref_res = np.reshape(x_data, oshape)
        check_grad(run_infer_type(func),
                   inputs=[x_data, np.array(newshape).astype("int64")],
                   test_inputs=[x_data],
                   eps=1e-3)
        verify_func(func, [x_data, np.array(newshape).astype("int64")],
                    ref_res)
예제 #6
0
def test_vm_reshape_tuple(x_shape=(1, 4, 2), y_shape=(1, 2, 10)):
    tup = relay.var(
        "tup",
        type_annotation=relay.TupleType(
            [relay.TensorType(x_shape),
             relay.TensorType(y_shape)]),
    )
    out = relay.reshape(relay.TupleGetItem(tup, 0), (1, -1))
    f = relay.Function([tup], out)

    x_data = np.random.uniform(size=x_shape).astype("float32")
    y_data = np.random.uniform(size=y_shape).astype("float32")

    for tgt, dev in tvm.testing.enabled_targets():
        res = veval(f, (x_data, y_data), device=dev, target=tgt)
        tvm.testing.assert_allclose(res.asnumpy(), np.reshape(x_data, (1, -1)))
예제 #7
0
    def verify_reshape(shape, newshape, oshape):
        x = relay.var("x", relay.TensorType(shape, "float32"))
        z = relay.reshape(x, newshape=newshape)
        zz = run_infer_type(z)
        assert "newshape=" in z.astext()
        assert zz.checked_type == relay.ty.TensorType(oshape, "float32")

        func = relay.Function([x], z)
        check_grad(func)
        x_data = np.random.uniform(low=-1, high=1, size=shape).astype("float32")
        ref_res = np.reshape(x_data, oshape)
        for target, ctx in ctx_list():
            for kind in ["graph", "debug"]:
                intrp = relay.create_executor(kind, ctx=ctx, target=target)
                op_res = intrp.evaluate(func)(x_data)
                tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-5)
예제 #8
0
def test_inline_no_ops():
    input = relay.var("input", shape=(12, 12), dtype="uint8")
    slice = relay.strided_slice(input, [0, 0], [6, 6])
    relu1 = relay.nn.relu(slice)
    reshape = relay.reshape(relu1, (36, ))
    relu2 = relay.nn.relu(reshape)
    func = relay.Function(relay.analysis.free_vars(relu2), relu2)
    func = run_opt_pass(func, relay.transform.InferType())

    cached_func = lower_to_te(func)
    sch = te.create_schedule([cached_func.outputs[0].op])
    inline_no_ops(cached_func, sch)
    reshape_tensor = cached_func.outputs[0].op.input_tensors[0]
    slice_tensor = reshape_tensor.op.input_tensors[0].op.input_tensors[0]
    assert sch[reshape_tensor].attach_type == AttachType.kInline
    assert sch[slice_tensor].attach_type == AttachType.kInline
예제 #9
0
    def verify_reshape(shape, newshape, oshape):
        x = relay.var("x", relay.TensorType(shape, "float32"))
        y = relay.var("y", relay.TensorType(newshape, "float32"))
        z = relay.reshape(x, relay.shape_of(y))
        func = run_infer_type(relay.Function([x, y], z))
        func2 = run_opt_pass(run_opt_pass(func, transform.DynamicToStatic()), transform.InferType())

        zz = func2.body
        assert isinstance(zz, relay.Call)
        assert zz.op == relay.op.get("reshape")
        assert "newshape=" in zz.astext()
        assert zz.checked_type == relay.ty.TensorType(oshape, "float32")

        x_data = np.random.uniform(low=-1, high=1, size=shape).astype("float32")
        y_data = np.random.uniform(low=-1, high=1, size=newshape).astype("float32")
        ref_res = np.reshape(x_data, oshape)
        verify_func(func2, [x_data, y_data], ref_res)
예제 #10
0
def make_net(network_arch, nfeat, nlabel, max_inp_len):
    out = relay.var('data', shape=(1, nfeat, 1, max_inp_len),
                    dtype='float32')  # NCHW

    needs_flat = True
    itm_ctr = defaultdict(int)
    for i, line in enumerate(network_arch):
        if line.startswith('#'):
            continue

        layer = line.rstrip().split(' ')
        itm_ctr[layer[0]] += 1
        if layer[0] == 'V':  # view
            continue

        elif layer[0] == 'C':
            if layer[1] == 'NFEAT':
                layer[1] = nfeat
            _ch_in, ch_out, k, s, p = map(int, layer[1:])
            assert s == 1
            out = _conv(out, ch_out, k, s, p, name=f'conv_{itm_ctr[layer[0]]}')

        elif layer[0] == 'GLU':
            # axis = int(layer[1])
            out = relay.nn.glu(out, 1)

        elif layer[0] == 'DO':
            out = relay.nn.dropout(out, float(layer[1]))

        elif layer[0] == 'RO':  # reorder
            pass
            # out = relay.transpose(out, tuple(map(int, layer[1:])))

        elif layer[0] == 'L':  # linear
            if layer[2] == 'NLABEL':
                layer[2] = nlabel
            if needs_flat:
                out = relay.reshape(out, (1, 908))
            out = _dense(out, int(layer[2]), name=f'dense_{itm_ctr[layer[0]]}')
            needs_flat = False

        else:
            raise RuntimeError('Unknown layer type: ' + layer[0])

    args = relay.ir_pass.free_vars(out)
    return relay.Function(args, out)
예제 #11
0
def verify_any_reshape(x_shape, newshape, x_np_shape, out_shape, variable_newshape=False):
    x = relay.var("x", shape=x_shape, dtype="float32")
    relu_x = relay.nn.relu(x)
    data = np.random.uniform(size=x_np_shape).astype("float32")
    params = [x]
    args = [data]

    if variable_newshape:
        newshape_var = relay.var("newshape", shape=(len(newshape),), dtype="int64")
        params.append(newshape_var)
        args.append(np.array(newshape, dtype="int64"))
        newshape = newshape_var

    y = relay.reshape(relu_x, newshape=newshape)
    mod = tvm.IRModule()
    mod["main"] = relay.Function(params, y)
    check_result(args, mod, data, flatten=True)
예제 #12
0
 def _get_func(ifm_shape, reshaped, ifm_layout):
     ifm = relay.var("ifm", shape=ifm_shape, dtype="int8")
     ifm_reshaped = relay.reshape(ifm, reshaped)
     conv = make_ethosu_conv2d(
         ifm_reshaped,
         reshaped[3],
         16,
         (3, 3),
         (1, 1),
         (1, 1),
         (1, 1),
         activation="NONE",
         ifm_layout=ifm_layout,
     )
     func = relay.Function(relay.analysis.free_vars(conv), conv)
     func = run_opt_pass(func, relay.transform.InferType())
     return func
예제 #13
0
    def test_full(self):
        fill_val = relay.expr.const(1.0)
        fill_shape = [10, 1]

        net = relay.full(fill_val, fill_shape, "float32")
        net = relay.reshape(net, [1, -1])
        mod = tvm.IRModule.from_expr(net)
        params = {}
        xgraph = xf_relay.from_relay(mod, params)
        layers = xgraph.get_layers()

        assert layers[0].type[0] == "Constant"
        assert layers[0].shapes == [1]
        assert layers[1].type[0] == "AnyOp"
        assert layers[1].shapes == [10, 1]
        assert layers[2].type[0] == "Reshape"
        assert layers[2].shapes == [1, 10]
예제 #14
0
파일: dnnl.py 프로젝트: wenxcs/tvm
def legalize_group_conv(attrs, inputs, types):
    """Legalize group conv / conv_transpose calculation.
    Alter weight layout from OIHW to GOIHW / IOHW to GIOHW"""
    groups = attrs.groups
    data, weight = inputs
    if groups == 1:
        if "Transpose" not in type(attrs).__name__:
            return relay.nn.conv2d(data, weight, **attrs)
        return relay.nn.conv2d_transpose(data, weight, **attrs)
    OC, IC, H, W = get_shape(weight)
    new_attrs = dict(attrs)
    weight = relay.reshape(weight, (groups, OC // groups, IC, H, W))
    if "Transpose" not in type(attrs).__name__:
        new_attrs["kernel_layout"] = "GOIHW"
        return relay.nn.conv2d(data, weight, **new_attrs)
    new_attrs["kernel_layout"] = "GIOHW"
    return relay.nn.conv2d_transpose(data, weight, **new_attrs)
예제 #15
0
def get_net(batch_size,
            random_len=100,
            oshape=(3, 64, 64),
            ngf=128,
            code=None,
            dtype="float32"):
    """get net of dcgan generator"""
    assert oshape[-1] == 64, "Only support 64x64 image"
    assert oshape[-2] == 64, "Only support 64x64 image"

    code = relay.var("data", dtype=dtype,
                     shape=(batch_size, random_len)) if code is None else code
    dense_weight = relay.var("dense_weight")
    dense = relay.nn.dense(code, weight=dense_weight, units=4 * 4 * ngf * 8)
    relu = relay.nn.relu(dense)
    # 4 x 4
    reshape = relay.reshape(relu, newshape=(-1, ngf * 8, 4, 4))
    # 8 x 8
    dc8 = deconv2d_bn_relu(reshape,
                           ishape=(ngf * 8, 4, 4),
                           oshape=(ngf * 4, 8, 8),
                           kshape=(4, 4),
                           prefix="g2")
    # 16x16
    dc16 = deconv2d_bn_relu(dc8,
                            ishape=(ngf * 4, 8, 8),
                            oshape=(ngf * 2, 16, 16),
                            kshape=(4, 4),
                            prefix="g3")
    # 32x32
    dc32 = deconv2d_bn_relu(dc16,
                            ishape=(ngf * 2, 16, 16),
                            oshape=(ngf, 32, 32),
                            kshape=(4, 4),
                            prefix="g4")
    # 64x64
    dc64 = deconv2d(dc32,
                    ishape=(ngf, 32, 32),
                    oshape=oshape[-3:],
                    kshape=(4, 4),
                    name="g5_deconv")
    tanh = relay.tanh(dc64)

    args = relay.analysis.free_vars(tanh)
    return relay.Function(args, tanh)
예제 #16
0
def tvm_lenet(num_classes=10,
              data_shape=(1, 1, 32, 32),
              dtype='float32',
              alpha=1.0,
              is_shallow=False):
    from tvm import relay
    from tvm.relay.testing import layers
    """Function to construct a Lenet"""
    data = relay.var("data", shape=data_shape, dtype=dtype)
    conv1 = layers.conv2d(data=data,
                          channels=6,
                          kernel_size=(5, 5),
                          name='conv1')
    conv1 = relay.tanh(conv1)
    pool2 = relay.nn.avg_pool2d(conv1, pool_size=(2, 2), strides=(2, 2))
    conv3 = layers.conv2d(data=pool2,
                          channels=16,
                          kernel_size=(5, 5),
                          name='conv3')
    conv3 = relay.tanh(conv3)
    pool4 = relay.nn.avg_pool2d(conv3, pool_size=(2, 2), strides=(2, 2))

    conv5 = layers.conv2d(data=pool4,
                          channels=120,
                          kernel_size=(5, 5),
                          name='conv5')
    conv5 = relay.tanh(conv5)
    # Temp
    flattened6 = relay.reshape(conv5, (1, 120))
    # flattened6 = relay.nn.batch_flatten(conv5)
    fcw7 = relay.var('fc7_weight', shape=(120, 84))
    fcw7 = relay.transpose(fcw7)
    fc7 = relay.nn.dense(data=flattened6, weight=fcw7, units=84)
    fc7 = relay.tanh(fc7)

    fcw8 = relay.var('fc6_weight', shape=(84, 10))
    fcw8 = relay.transpose(fcw8)

    fc8 = relay.nn.dense(data=fc7, weight=fcw8, units=10)

    softmax = relay.nn.softmax(data=fc8)
    fn = relay.Function(relay.analysis.free_vars(softmax), softmax)
    return fn
예제 #17
0
def test_batch_matmul_rewrite():
    data = relay.var("data", shape=(1, 4, 16, 16))
    data2 = relay.sigmoid(relay.var("data", shape=(4, 16, 64)))
    out = relay.nn.conv2d(data, relay.var("weight"), kernel_size=(3, 3), padding=(1, 1), channels=8)

    out = relay.nn.batch_flatten(out)
    out = relay.reshape(out, [1, 32, 64])
    out = relay.nn.batch_matmul(out, data2)

    qmod = quantize_and_build(out)

    def _check_batch_matmul(node):
        if isinstance(node, Call):

            if node.op.name in ["nn.batch_matmul", "nn.conv2d"]:
                assert node.checked_type.dtype == "int32"
            elif node.op.name == "nn.batch_flatten":
                assert node.checked_type.dtype == "int8"

    # check if batch_matmul is quantized
    relay.analysis.post_order_visit(qmod["main"], _check_batch_matmul)
예제 #18
0
def verify_any_reshape(x_shape, newshape, x_np_shape, out_shape, variable_newshape=False):
    x = relay.var('x', shape=x_shape, dtype="float32")
    relu_x = relay.nn.relu(x)
    data = np.random.uniform(size=x_np_shape).astype('float32')
    params = [x]
    args = [data]

    if variable_newshape:
        newshape_var = relay.var('newshape', shape=(len(newshape),), dtype='int64')
        params.append(newshape_var)
        args.append(np.array(newshape, dtype='int64'))
        newshape = newshape_var

    y = relay.reshape(relu_x, newshape=newshape)
    mod = tvm.IRModule()
    mod["main"] = relay.Function(params, y)

    for kind in ["debug", "vm"]:
        ex = relay.create_executor(kind, mod=mod, ctx=tvm.cpu(), target="llvm")
        result = ex.evaluate()(*args).asnumpy()
        assert result.shape == out_shape
        tvm.testing.assert_allclose(result.flatten(), data.flatten())
예제 #19
0
def test_vm_reshape_tensor():
    x_np = np.random.uniform(size=(8, 16)).astype("float32")
    x = relay.var("x", shape=(8, 16), dtype="float32")
    y = relay.reshape(x, [-1, 4, 8])
    mod = tvm.IRModule()
    mod["main"] = relay.Function([x], y)
    with tvm.transform.PassContext(opt_level=3):
        exec = relay.vm.compile(mod, "llvm")
    assert "reshape_tensor" in exec.bytecode
    check_result([x_np], x_np.reshape([4, 4, 8]), mod)

    x = relay.var("x", shape=(8, 16), dtype="float32")
    y = relay.reshape(x, [16, -1])
    y = relay.reverse_reshape(y, [-1, 4, 0])
    mod = tvm.IRModule()
    mod["main"] = relay.Function([x], y)
    with tvm.transform.PassContext(opt_level=3):
        exec = relay.vm.compile(mod, "llvm")
    assert exec.bytecode.count("reshape_tensor") == 1
    check_result([x_np], x_np.reshape([4, 4, 8]), mod)

    # reshape with symbolic/any shape
    for n in [tvm.tir.Any(), tvm.te.size_var("n")]:
        x = relay.var("x", shape=(n, 16), dtype="float32")
        y = relay.reshape(x, [-1, 4])
        y = relay.reshape(y, [0, 2, -1])
        mod = tvm.IRModule()
        mod["main"] = relay.Function([x], y)
        with tvm.transform.PassContext(opt_level=3):
            exec = relay.vm.compile(mod, "llvm")
        assert exec.bytecode.count("reshape_tensor") == 1
        check_result([x_np], x_np.reshape([32, 2, 2]), mod)

    # dyn.reshape
    x = relay.var("x", shape=(8, 16), dtype="float32")
    y = relay.var("y", shape=(3, ), dtype="int32")
    z = relay.reshape(x, [-1, 4, 8])
    z = relay.reshape(z, y)
    mod = tvm.IRModule()
    mod["main"] = relay.Function([x, y], z)
    with tvm.transform.PassContext(opt_level=3):
        exec = relay.vm.compile(mod, "llvm")
    assert exec.bytecode.count("reshape_tensor") == 2
    assert "reshape_tensor" in exec.bytecode
    y_np = np.array([8, 2, 8]).astype("int32")
    check_result([x_np, y_np], x_np.reshape([8, 2, 8]), mod)
예제 #20
0
파일: legalize.py 프로젝트: saudet/tvm
    def reshape_output(output: tvm.relay.Expr, ifm_input_shape: List[int]) -> tvm.relay.Expr:
        """Reshape the output back to the original dimensionality.
        Since the NPU must have the brodcastable tensor as the
        second operand, the original shape of the first ifm must
        be the output shape.

        Parameters
        ----------
        output: tvm.relay.Expr
            The output to reshape.

        ifm_input_shape: List[int]
            The shape of the non-reshaped ifm tensor.

        Returns
        -------
        reshaped_output: tvm.relay.Expr
            The reshaped output expression.
        """
        if len(ifm_input_shape) == 4:
            return output
        reshaped_output = relay.reshape(output, ifm_input_shape)
        return reshaped_output
예제 #21
0
    def test_run(x_data_list, x_shape, new_shape, should_offload_to_trt):
        result_arr = [{} for _ in range(len(x_data_list))]
        for use_trt in [True, False]:
            x = relay.var("x", shape=x_shape, dtype="float32")
            out = relay.reshape(x, new_shape)
            f = relay.Function([x], out)
            mod = tvm.IRModule()
            mod["main"] = f
            if use_trt:
                mod, _ = tensorrt.partition_for_tensorrt(
                    mod, params={}, remove_no_mac_subgraphs=False
                )
                assert are_ops_on_trt(mod, op_list=["reshape"]) == should_offload_to_trt
            if not skip_runtime_test():
                with relay.build_config(opt_level=3):
                    relay_exec = relay.create_executor("vm", mod=mod, ctx=tvm.cpu(0), target="llvm")

                for i, x_data in enumerate(x_data_list):
                    result_arr[i][use_trt] = relay_exec.evaluate()(x_data)

        if not skip_runtime_test():
            for i in range(len(x_data_list)):
                assert_result_dict_holds(result_arr[i])
    def verify_more_dynamic_broadcast_to(x_shape, out_shape):
        rank = len(out_shape)
        dtype = "float32"
        shape_type = "int64"
        reshape_shape = relay.Var(
            "shape", relay.ty.TensorType((len(x_shape), ), shape_type))
        broadcast_shape = relay.Var("shape",
                                    relay.ty.TensorType((rank, ), shape_type))
        x = relay.Var("x", relay.ty.TensorType((np.prod(x_shape), ), dtype))
        r = relay.reshape(x, reshape_shape)
        z = relay.broadcast_to(r, broadcast_shape)

        func = relay.Function([x, reshape_shape, broadcast_shape], z)

        x = np.random.uniform(size=np.prod(x_shape)).astype(dtype)
        ref_res = np.broadcast_to(np.reshape(x, x_shape), out_shape)
        for target, dev in tvm.testing.enabled_targets():
            for kind in ["vm", "debug"]:
                mod = tvm.ir.IRModule.from_expr(func)
                op_res = relay.create_executor(
                    kind, mod=mod, device=dev, target=target).evaluate(func)(
                        x, np.array(x_shape).astype(shape_type),
                        np.array(out_shape).astype(shape_type))
                tvm.testing.assert_allclose(op_res.numpy(), ref_res, rtol=1e-5)
 def expected(x, conv_weight, out_scale, channels, blocking):
     # use a fixed order of args so alpha equal check can pass
     args = [x, conv_weight]
     if blocking:
         squeezed_scale = relay.squeeze(out_scale, axis=[0, 2, 3])
         conv_weight = relay.multiply(
             conv_weight,
             relay.reshape(squeezed_scale, (channels // blocking[1], 1, 1, 1, 1, blocking[1])),
         )
     else:
         squeezed_scale = relay.squeeze(out_scale, axis=[1, 2])
         conv_weight = relay.multiply(
             conv_weight, relay.expand_dims(squeezed_scale, axis=1, num_newaxis=3)
         )
     y = relay.nn.conv2d(
         x,
         conv_weight,
         channels=channels,
         kernel_size=(3, 3),
         padding=(1, 1),
         data_layout="NCHW{}c".format(blocking[0]) if blocking else "NCHW",
         kernel_layout="OIHW1i{}o".format(blocking[1]) if blocking else "OIHW",
     )
     return relay.Function(args, y)
    def _execute(self):
        self.node_dict = {}
        # self.node_dict['1'] = relay.const(np.zeros((1, 128)), dtype='int32')
        gelu_a = relay.var('gelu_a', shape=())
        gelu_b = relay.var('gelu_b', shape=())
        gelu_c = relay.var('gelu_c', shape=())
        gelu_d = relay.var('gelu_d', shape=())
        gelu_e = relay.var('gelu_e', shape=())

        self.node_dict['1'] = relay.var('input.1', shape=(1,128), dtype='int32')
        self.node_dict['2'] = relay.var('input.2', shape=(1,128), dtype='int32')
        for gnode in self.graph:
            name = gnode['name']
            op_type = gnode['op_type']
            attrs = gnode['attrs']
            del attrs['A_shape']
            del attrs['O_shape']

            inputs = gnode['inputs']

            if op_type == 'Const':
                arr = np.zeros(attrs['shape'], dtype=np.int32)
                y =  relay.const(arr, dtype='int32')

            elif op_type == 'expand_dims':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.expand_dims(x, attrs['axis'], attrs['num_newaxis'])

            elif op_type == 'reshape':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.reshape(x, attrs['newshape'])
            elif op_type == 'take':
                data = get_input(self.node_dict, self.params, inputs[0])
                indices = get_input(self.node_dict, self.params, inputs[1])
                y = relay.take(data, indices, axis=attrs['axis'][0], mode=attrs['mode'])
            elif op_type == 'one_hot':
                x = get_input(self.node_dict, self.params, inputs[0])
                cc1 = get_input(self.node_dict, self.params, inputs[1])
                cc2 = get_input(self.node_dict, self.params, inputs[2])
                y = relay.one_hot(x, cc1, cc2, **attrs)
            elif op_type == 'strided_slice':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.strided_slice(x, **attrs)
            elif op_type == 'mean':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.mean(x, axis=attrs['axis'],
                        exclude=attrs['exclude'],
                        keepdims=attrs['keepdims'])
            elif op_type == 'nn.dense':
                x = get_input(self.node_dict, self.params, inputs[0])
                weight = get_input(self.node_dict, self.params, inputs[1])
                y = relay.nn.dense(x, weight, units=attrs['units'][0])
            elif op_type == 'add':
                x1 = get_input(self.node_dict, self.params, inputs[0])
                x2 = get_input(self.node_dict, self.params, inputs[1])
                y = relay.add(x1, x2)
            elif op_type == 'subtract':
                x1 = get_input(self.node_dict, self.params, inputs[0])
                x2 = get_input(self.node_dict, self.params, inputs[1])
                y = relay.subtract(x1, x2)
            elif op_type == 'multiply':
                x1 = get_input(self.node_dict, self.params, inputs[0])
                x2 = get_input(self.node_dict, self.params, inputs[1])
                y = relay.multiply(x1, x2)
            elif op_type == 'power':
                x1 = get_input(self.node_dict, self.params, inputs[0])
                x2 = get_input(self.node_dict, self.params, inputs[1])
                y = relay.power(x1, x2)
            elif op_type == 'transpose':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.transpose(x, **attrs)
            elif op_type == 'tanh':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.tanh(x)
            elif op_type == 'squeeze':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.squeeze(x, **attrs)
            elif op_type == 'nn.batch_matmul':
                x1 = get_input(self.node_dict, self.params, inputs[0])
                x2 = get_input(self.node_dict, self.params, inputs[1])
                y = relay.nn.batch_matmul(x1, x2)
            elif op_type == 'nn.softmax':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = relay.nn.softmax(x, **attrs)
            elif op_type == 'gelu':
                x = get_input(self.node_dict, self.params, inputs[0])
                y = x * gelu_a * (gelu_b + relay.tanh(
                           ( gelu_c * (x + gelu_d *
                                   relay.power(x, gelu_e)))))
            else:
                import pdb; pdb.set_trace()
                print( 'not supported op %s ' % op_type)
            self.node_dict[name] = y

        output_name = self.output_node_ids[0]
        output = self.node_dict[output_name]

        inputs = relay.analysis.free_vars(output)
        # inputs = [self.node_dict['1'], self.node_dict['2']]
        func = relay.Function(inputs, output)
        mod = tvm.IRModule()
        mod['main'] = func

        with relay.build_config(opt_level=0):
            graph, lib, params = relay.build(mod, 'llvm', params={})
        self.m = graph_runtime.create(graph, lib, tvm.cpu())
예제 #25
0
def _alter_conv2d_layout(attrs, inputs, tinfos, out_type):
    target = tvm.target.Target.current(allow_none=False)
    dispatch_ctx = autotvm.task.DispatchContext.current
    new_attrs = {k: attrs[k] for k in attrs.keys()}

    # Parse the attributes.
    padding = attrs.get_int_tuple("padding")
    strides = attrs.get_int_tuple("strides")
    dilation = attrs.get_int_tuple("dilation")
    data_layout = attrs["data_layout"]
    kernel_layout = attrs["kernel_layout"]
    data_tensor, kernel_tensor = tinfos
    data_dtype = data_tensor.dtype
    kernel_dtype = kernel_tensor.dtype
    out_dtype = out_type.dtype

    if isinstance(dispatch_ctx, autotvm.task.ApplyGraphBest):
        cfg = dispatch_ctx.query(target, None)
        workload = cfg.workload
    else:
        impl, outs = relay.backend.compile_engine.select_implementation(
            relay.op.get("nn.conv2d"), attrs, tinfos, out_type, target)
        workload = autotvm.task.get_workload(outs)
        if workload is None:
            # The best implementation is not an AutoTVM template.
            # It may be from the auto-scheduler
            if impl.name.find("winograd") != -1:
                if dilation != (1, 1):
                    logger.warning(
                        "Does not support weight pre-transform for dilated convolution."
                    )
                    return None

                assert data_layout == "NHWC" and kernel_layout == "HWIO"
                N, H, W, CI = get_const_tuple(data_tensor.shape)
                KH, KW, _, CO = get_const_tuple(kernel_tensor.shape)

                # Pre-compute weight transformation in winograd
                tile_size = 4
                # HWIO -> OIHW
                kernel_transform = relay.transpose(inputs[1],
                                                   axes=[3, 2, 0, 1])
                # alpha, alpha, CO, CI
                weight = relay.nn.contrib_conv2d_winograd_weight_transform(
                    kernel_transform, tile_size=tile_size)
                new_attrs["tile_size"] = tile_size
                new_attrs["channels"] = CO
                return relay.nn.contrib_conv2d_winograd_without_weight_transform(
                    inputs[0], weight, **new_attrs)
            return None

        cfg = dispatch_ctx.query(target, workload)

    topi_tmpl = workload[0]

    if topi_tmpl == "conv2d_NCHWc.x86":
        # we only convert conv2d_NCHW to conv2d_NCHWc for x86
        if data_layout == "NCHW" and kernel_layout == "OIHW":
            if cfg.is_fallback:
                _get_default_config(
                    cfg,
                    data_tensor,
                    kernel_tensor,
                    strides,
                    padding,
                    dilation,
                    out_dtype,
                    False,
                    data_layout,
                )
            batch_size, in_channel, height, width = get_const_tuple(
                data_tensor.shape)
            out_channel, _, kh, kw = get_const_tuple(kernel_tensor.shape)
            ic_bn, oc_bn = cfg["tile_ic"].size[-1], cfg["tile_oc"].size[-1]

            # update new attrs
            new_attrs["channels"] = out_channel
            new_attrs["data_layout"] = "NCHW%dc" % ic_bn
            # (oc, ic, h, w) -> (OC, IC, h, w, ic, oc)
            new_attrs["kernel_layout"] = "OIHW%di%do" % (ic_bn, oc_bn)
            new_attrs["out_layout"] = "NCHW%dc" % oc_bn

            # Store altered operator's config
            new_data = te.placeholder(
                (batch_size, in_channel // ic_bn, height, width, ic_bn),
                dtype=data_dtype)
            new_kernel = te.placeholder(
                (out_channel // oc_bn, in_channel // ic_bn, kh, kw, ic_bn,
                 oc_bn),
                dtype=kernel_tensor.dtype,
            )
            new_workload = autotvm.task.args_to_workload(
                [
                    new_data,
                    new_kernel,
                    strides,
                    padding,
                    dilation,
                    new_attrs["data_layout"],
                    new_attrs["out_layout"],
                    out_dtype,
                ],
                topi_tmpl,
            )
            dispatch_ctx.update(target, new_workload, cfg)
        else:
            assert _NCHWc_matcher.match(data_layout)
            assert _OIHWio_matcher.match(kernel_layout)
        return relay.nn.contrib_conv2d_nchwc(*inputs, **new_attrs)

    if topi_tmpl == "conv2d_NCHWc_int8.x86":
        # TODO(@icemelon9, @anijain2305): Need to support data layout NHWC with kernel layout HWIO
        assert data_layout == "NCHW" and kernel_layout == "OIHW"
        if cfg.is_fallback:
            _get_default_config_int8(
                cfg,
                data_tensor,
                kernel_tensor,
                strides,
                padding,
                dilation,
                out_dtype,
                False,
                data_layout,
            )

        batch_size, in_channel, height, width = get_const_tuple(
            data_tensor.shape)
        out_channel, channel_multiplier, kh, kw = get_const_tuple(
            kernel_tensor.shape)
        ic_bn, oc_bn = cfg["tile_ic"].size[-1], cfg["tile_oc"].size[-1]
        n_elems = 4

        # convert kernel data layout from 4D to 7D
        data_expr, kernel_expr = inputs
        kernel_IHWO = relay.transpose(kernel_expr, axes=(1, 2, 3, 0))
        kernel_IHWOo = relay.reshape(
            kernel_IHWO, (in_channel, kh, kw, out_channel // oc_bn, oc_bn))
        kernel_OHWoI = relay.transpose(kernel_IHWOo, axes=(3, 1, 2, 4, 0))
        kernel_OHWoIi = relay.reshape(
            kernel_OHWoI,
            (out_channel // oc_bn, kh, kw, oc_bn, in_channel // ic_bn, ic_bn))
        kernel_OHWoIie = relay.reshape(
            kernel_OHWoIi,
            (out_channel // oc_bn, kh, kw, oc_bn, in_channel // ic_bn,
             ic_bn // n_elems, n_elems),
        )
        kernel_OIHWioe = relay.transpose(kernel_OHWoIie,
                                         axes=(0, 4, 1, 2, 5, 3, 6))

        # update new attrs
        new_attrs["channels"] = out_channel
        new_attrs["data_layout"] = "NCHW%dc" % ic_bn
        new_attrs["out_layout"] = "NCHW%dc" % oc_bn

        # Store altered operator's config.
        new_data = te.placeholder(
            (batch_size, in_channel // ic_bn, height, width, ic_bn),
            dtype=data_dtype)
        new_kernel = te.placeholder(
            (out_channel // oc_bn, in_channel // ic_bn, kh, kw,
             ic_bn // n_elems, oc_bn, n_elems),
            dtype=kernel_dtype,
        )
        new_workload = autotvm.task.args_to_workload(
            [
                new_data,
                new_kernel,
                strides,
                padding,
                dilation,
                new_attrs["data_layout"],
                new_attrs["out_layout"],
                out_dtype,
            ],
            topi_tmpl,
        )
        dispatch_ctx.update(target, new_workload, cfg)

        return relay.nn.contrib_conv2d_nchwc(data_expr, kernel_OIHWioe,
                                             **new_attrs)

    if topi_tmpl == "depthwise_conv2d_NCHWc.x86":
        if data_layout == "NCHW" and kernel_layout == "OIHW":
            if cfg.is_fallback:
                _get_default_config(
                    cfg,
                    data_tensor,
                    kernel_tensor,
                    strides,
                    padding,
                    dilation,
                    out_dtype,
                    True,
                    data_layout,
                )

            batch_size, in_channel, height, width = get_const_tuple(
                data_tensor.shape)
            out_channel, channel_multiplier, kh, kw = get_const_tuple(
                kernel_tensor.shape)
            ic_bn, oc_bn = cfg["tile_ic"].size[-1], cfg["tile_oc"].size[-1]
            assert channel_multiplier == 1

            # update new attrs
            new_attrs["channels"] = out_channel
            new_attrs["data_layout"] = "NCHW%dc" % ic_bn
            new_attrs["kernel_layout"] = "OIHW1i%do" % oc_bn
            new_attrs["out_layout"] = "NCHW%dc" % oc_bn

            # Store altered operator's config.
            new_data = te.placeholder(
                (batch_size, in_channel // ic_bn, height, width, ic_bn),
                dtype=data_dtype)
            new_kernel = te.placeholder(
                (out_channel // oc_bn, 1, kh, kw, 1, oc_bn),
                dtype=kernel_dtype)
            new_workload = autotvm.task.args_to_workload(
                [
                    new_data,
                    new_kernel,
                    strides,
                    padding,
                    dilation,
                    new_attrs["data_layout"],
                    new_attrs["out_layout"],
                    out_dtype,
                ],
                topi_tmpl,
            )
            dispatch_ctx.update(target, new_workload, cfg)
        else:
            assert _NCHWc_matcher.match(data_layout)
            assert _OIHWio_matcher.match(kernel_layout)
        return relay.nn.contrib_depthwise_conv2d_nchwc(*inputs, **new_attrs)

    return None
예제 #26
0
def _alter_conv2d_layout(attrs, inputs, tinfos, out_type):
    target = tvm.target.Target.current(allow_none=False)
    dispatch_ctx = autotvm.task.DispatchContext.current

    new_attrs = {k: attrs[k] for k in attrs.keys()}

    strides = attrs.get_int_tuple("strides")
    padding = attrs.get_int_tuple("padding")
    dilation = attrs.get_int_tuple("dilation")
    data_layout = attrs["data_layout"]
    kernel_layout = attrs["kernel_layout"]
    data, kernel = tinfos
    out_dtype = out_type.dtype

    impl, outs = relay.backend.compile_engine.select_implementation(
        relay.op.get("nn.conv2d"), attrs, tinfos, out_type, target
    )
    workload = autotvm.task.get_workload(outs)
    if workload is None:
        # The best implementation is not an AutoTVM template.
        # It may be from the auto-scheduler
        if impl.name.find("winograd") != -1:
            if dilation != (1, 1):
                logger.warning("Does not support weight pre-transform for dilated convolution.")
                return None

            assert data_layout == "NHWC" and kernel_layout == "HWIO"
            N, H, W, CI = get_const_tuple(data.shape)
            KH, KW, _, CO = get_const_tuple(kernel.shape)

            # Pre-compute weight transformation in winograd
            tile_size = _pick_tile_size(tinfos[0], tinfos[1], layout="NHWC")

            # HWIO -> OIHW
            kernel_transform = relay.transpose(inputs[1], axes=[3, 2, 0, 1])
            # alpha, alpha, CO, CI
            weight = relay.nn.contrib_conv2d_winograd_weight_transform(
                kernel_transform, tile_size=tile_size
            )
            new_attrs["tile_size"] = tile_size
            new_attrs["channels"] = CO
            return relay.nn.contrib_conv2d_winograd_without_weight_transform(
                inputs[0], weight, **new_attrs
            )

        return None
    cfg = dispatch_ctx.query(target, workload)
    if cfg.is_fallback:  # if is fallback, clear query cache and return None
        autotvm.task.clear_fallback_cache(target, workload)
        return None

    topi_tmpl = workload[0]
    idxd = tvm.tir.indexdiv

    if topi_tmpl == "conv2d_nchw_spatial_pack.mali":
        assert data_layout == "NCHW" and kernel_layout == "OIHW"
        N, CI, H, W = get_const_tuple(data.shape)
        CO, _, KH, KW = get_const_tuple(kernel.shape)
        VC = cfg["tile_co"].size[-1]

        new_attrs["kernel_layout"] = "OIHW%do" % VC

        new_data = data
        new_kernel = te.placeholder((idxd(CO, VC), CI, KH, KW, VC), dtype=kernel.dtype)
        new_workload = autotvm.task.args_to_workload(
            [new_data, new_kernel, strides, padding, dilation, out_dtype],
            "conv2d_nchw_spatial_pack.mali",
        )
        dispatch_ctx.update(target, new_workload, cfg)

        return relay.nn.conv2d(*inputs, **new_attrs)
    elif topi_tmpl == "conv2d_nchw_winograd.mali":
        assert data_layout == "NCHW" and kernel_layout == "OIHW"
        N, CI, H, W = get_const_tuple(data.shape)
        CO, _, KH, KW = get_const_tuple(kernel.shape)
        tile_size = _pick_tile_size(data, kernel)
        VC = cfg["tile_bna"].val

        weight_expr = inputs[1]
        weight_expr = relay.nn.contrib_conv2d_winograd_weight_transform(
            weight_expr, tile_size=tile_size
        )
        weight_expr = relay.reshape(
            weight_expr, newshape=(KH + tile_size - 1, KW + tile_size - 1, idxd(CO, VC), VC, CI)
        )
        weight_expr = relay.transpose(weight_expr, axes=[0, 1, 2, 4, 3])

        new_attrs["tile_size"] = tile_size

        new_data = data
        new_kernel = te.placeholder(
            (KH + tile_size - 1, KW + tile_size - 1, idxd(CO, VC), CI, VC), kernel.dtype
        )
        new_workload = autotvm.task.args_to_workload(
            [new_data, new_kernel, strides, padding, dilation, out_dtype],
            "conv2d_nchw_winograd.mali",
        )
        dispatch_ctx.update(target, new_workload, cfg)

        return relay.nn.contrib_conv2d_winograd_without_weight_transform(
            inputs[0], weight_expr, **new_attrs
        )
    else:
        return None
예제 #27
0
def relay_conv2d_weight_grad(c, data, wsize, dout, stride, pad, dil, groups):
    # This implementation should match the one in pytorch backend
    # (myia.compile.backends.pytorch_conv_grad.conv2d_weight)

    assert wsize.is_constant(tuple)
    assert stride.is_constant(tuple)
    assert pad.is_constant(tuple)
    assert dil.is_constant(tuple)
    assert groups.is_constant(int)

    batch, in_channel, in_h, in_w = data.abstract.xshape()
    out_channel, _, filter_h, filter_w = wsize.value
    grad_sh0, grad_sh1, grad_h, grad_w = dout.abstract.xshape()
    pad_h, pad_w = pad.value

    data = c.ref(data)
    dout = c.ref(dout)

    fpad_h = pad_h * 2
    fpad_w = pad_w * 2
    fpad_top = (pad_h + 1) // 2
    fpad_left = (pad_w + 1) // 2
    fpad_bottom = fpad_h - fpad_top
    fpad_right = fpad_w - fpad_left

    padded_weight_grad_h = (in_h - (grad_h - 1) * stride.value[0] - 1 +
                            fpad_top + fpad_bottom) // dil.value[0] + 1
    padded_weight_grad_w = (in_w - (grad_w - 1) * stride.value[1] - 1 +
                            fpad_left + fpad_right) // dil.value[1] + 1

    dout = relay.tile(dout, [1, in_channel // groups.value, 1, 1])
    dout = relay.reshape(dout, [-1, 1, 0, 0])
    data = relay.reshape(data, [1, -1, 0, 0])

    d = relay.nn.conv2d(
        data,
        dout,
        strides=dil.value,
        padding=pad.value,
        dilation=stride.value,
        groups=batch * in_channel,
    )

    conv_sh1 = grad_sh0 * grad_sh1 * (in_channel // groups.value)
    d = relay.reshape(
        d,
        [batch, conv_sh1 // batch, padded_weight_grad_h, padded_weight_grad_w],
    )
    d = relay.sum(d, axis=0)

    if groups.value > 1:
        d = relay.reshape(
            d,
            [
                grad_sh1,
                in_channel // groups.value,
                padded_weight_grad_h,
                padded_weight_grad_w,
            ],
        )
    else:
        d = relay.reshape(
            d,
            [
                in_channel // groups.value,
                grad_sh1,
                padded_weight_grad_h,
                padded_weight_grad_w,
            ],
        )
        d = relay.transpose(d, [1, 0, 2, 3])

    if padded_weight_grad_h > filter_h or padded_weight_grad_w > filter_w:
        d = relay.strided_slice(d,
                                begin=[0, 0, 0, 0],
                                end=[None, None, filter_h, filter_w])
    return d
예제 #28
0
    def callback(self, pre: tvm.relay.Expr, post: tvm.relay.Expr,
                 node_map: tvm.ir.container.Map) -> tvm.relay.Expr:
        params = ethosu_patterns.MeanParams(post.op.body)
        params.ifm.tensor = post.args[0]

        ifm_shape = params.ifm.shape
        ofm_shape = params.ofm.shape
        lut = relay.const([], "int8")
        axis = params.axis
        reduced_op = params.ifm.tensor

        # Enforce 4d input
        if len(ifm_shape) < 4:
            axis = [x + 1 for x in axis]
            if len(ifm_shape) == 3:
                ifm_shape = [1, params.height, params.width, ifm_shape[2]]
            else:
                ifm_shape = [1, params.height, params.width, 1]
            reduced_op = relay.reshape(reduced_op, ifm_shape)

        filter_height = ifm_shape[1] if 1 in axis else 1
        filter_width = ifm_shape[2] if 2 in axis else 1
        in_channels = out_channels = ifm_shape[-1]

        # If the height is greater than max kernel height, reshape the input
        # from [filter_height, filter_width] to [1, (filter_height*filter_width)]
        # only in the case the axis is [1, 2].
        if axis == [1, 2] and filter_height > 64:
            ifm_shape = (ifm_shape[0], 1, filter_height * filter_width,
                         in_channels)
            filter_width = filter_height * filter_width
            filter_height = 1
            reduced_op = relay.reshape(reduced_op, ifm_shape)

        if axis == [1, 2] and params.keepdims:
            weight_scale = 1
            weight_values = np.ones(
                [out_channels, filter_height, filter_width, in_channels])
            scale_bias = vela_api.pack_biases(
                biases=np.zeros(ifm_shape[-1]),
                ifm_scale=params.ifm.q_params.scale_f32,
                ifm_dtype=np.dtype(params.ifm.dtype),
                weight_scales=np.array([weight_scale], dtype=np.float),
                ofm_scale=params.ofm.q_params.scale_f32,
                is_activation_tanh_or_sigmoid=False,
            )

            reduced_op = ethosu_ops.ethosu_depthwise_conv2d(
                ifm=reduced_op,
                weight=relay.const(weight_values, params.ifm.dtype),
                scale_bias=relay.const(scale_bias, "uint8"),
                lut=lut,
                ifm_scale=float(params.ifm.q_params.scale_f32),
                ifm_zero_point=int(params.ifm.q_params.zero_point),
                weight_zero_point=0,
                ofm_scale=float(params.ofm.q_params.scale_f32),
                ofm_zero_point=int(params.ofm.q_params.zero_point),
                kernel_shape=(filter_height, filter_width),
                ofm_channels=out_channels,
                ofm_dtype="int16",
            )

            n = int(filter_height * filter_width)
            eps = 1 / (256 * (n + 1)) if n % 2 == 0 else 0

            scalar_tensor = relay.const(np.ones([1, 1, 1, 1], dtype="int16"),
                                        dtype="int16")

            reduced_op = ethosu_ops.ethosu_binary_elementwise(
                ifm=reduced_op,
                ifm2=scalar_tensor,
                lut=lut,
                operator_type="MUL",
                ifm_scale=float(params.ofm.q_params.scale_f32),
                ifm_zero_point=int(params.ofm.q_params.zero_point),
                ifm2_scale=1 / (n - eps),
                ifm2_zero_point=0,
                ofm_scale=float(params.ofm.q_params.scale_f32),
                ofm_zero_point=int(params.ofm.q_params.zero_point),
                ifm_channels=out_channels,
                ifm2_channels=out_channels,
                reversed_operands=False,
                ofm_dtype="int8",
                rounding_mode="NATURAL",
            )
        elif (params.ifm.q_params.scale_f32 == params.ofm.q_params.scale_f32
              and params.ifm.q_params.zero_point
              == params.ofm.q_params.zero_point):
            reduced_op = ethosu_ops.ethosu_pooling(
                ifm=reduced_op,
                lut=lut,
                pooling_type="AVG",
                ifm_scale=float(params.ifm.q_params.scale_f32),
                ifm_zero_point=0,
                ofm_scale=float(params.ofm.q_params.scale_f32),
                ofm_zero_point=0,
                pool_shape=(filter_height, filter_width),
                ofm_channels=out_channels,
                rounding_mode="TRUNCATE",
            )
        else:
            weight_scale = 1 / (filter_height * filter_width)
            weight_values = np.ones(
                [out_channels, filter_height, filter_width, in_channels])
            bias = -1 * int(
                params.ifm.q_params.zero_point) * filter_height * filter_width

            scale_bias = vela_api.pack_biases(
                biases=np.ones([ifm_shape[-1]]) * bias,
                ifm_scale=params.ifm.q_params.scale_f32,
                ifm_dtype=np.dtype(params.ifm.dtype),
                weight_scales=np.array([weight_scale], dtype=np.float),
                ofm_scale=params.ofm.q_params.scale_f32,
                is_activation_tanh_or_sigmoid=False,
            )
            reduced_op = ethosu_ops.ethosu_depthwise_conv2d(
                ifm=reduced_op,
                weight=relay.const(weight_values, params.ifm.dtype),
                scale_bias=relay.const(scale_bias, "uint8"),
                lut=lut,
                ifm_scale=float(params.ifm.q_params.scale_f32),
                ifm_zero_point=0,
                weight_zero_point=0,
                ofm_scale=float(params.ofm.q_params.scale_f32),
                ofm_zero_point=int(params.ofm.q_params.zero_point),
                kernel_shape=(filter_height, filter_width),
                ofm_channels=out_channels,
                rounding_mode="NATURAL",
            )

        # Reshape to original ofm shape
        if len(ofm_shape) < 4:
            reduced_op = relay.reshape(reduced_op, ofm_shape)

        return reduced_op
예제 #29
0
 def expected():
     x = relay.var("x", shape=(1, 16, 16, 16), dtype="float32")
     w = relay.var("w", shape=(32, 16, 3, 3), dtype="float32")
     y = relay.nn.conv2d(x, w, padding=(1, 1))
     y = relay.reshape(y, newshape=(32, 16, 16))
     return relay.Function([x, w], y)
예제 #30
0
파일: test_runtime.py 프로젝트: szha/tvm
 def get_model(input_shape, var_names):
     """Return a model and any parameters it may have."""
     a = relay.var(next(var_names), shape=input_shape, dtype="float32")
     out = relay.reshape(a, (1, 1, 1000))
     out = relay.reshape(out, (1, 1000))
     return out
예제 #31
0
파일: conv2d.py 프로젝트: aiblackmaner/tvm
def _alter_conv2d_layout(attrs, inputs, tinfos, out_type):
    target = tvm.target.Target.current(allow_none=False)
    dispatch_ctx = autotvm.task.DispatchContext.current

    _, outs = relay.backend.compile_engine.select_implementation(
        relay.op.get("nn.conv2d"), attrs, tinfos, out_type, target)
    workload = autotvm.task.get_workload(outs)
    if workload is None:
        # The best implementation is not an AutoTVM template,
        # we then assume it's not necessary to alter this op.
        return None
    cfg = dispatch_ctx.query(target, workload)
    if cfg.is_fallback:  # if is fallback, clear query cache and return None
        autotvm.task.clear_fallback_cache(target, workload)
        return None

    topi_tmpl = workload[0]
    new_attrs = {k: attrs[k] for k in attrs.keys()}

    strides = attrs.get_int_tuple("strides")
    padding = attrs.get_int_tuple("padding")
    dilation = attrs.get_int_tuple("dilation")
    data_layout = attrs["data_layout"]
    kernel_layout = attrs["kernel_layout"]
    data, kernel = tinfos
    out_dtype = out_type.dtype

    idxd = tvm.tir.indexdiv

    if topi_tmpl == "conv2d_nchw_spatial_pack.bifrost":
        assert data_layout == "NCHW" and kernel_layout == "OIHW"
        N, CI, H, W = get_const_tuple(data.shape)
        CO, _, KH, KW = get_const_tuple(kernel.shape)
        VC = cfg["tile_co"].size[-1]

        new_attrs["kernel_layout"] = "OIHW%do" % VC

        new_data = data
        new_kernel = te.placeholder((idxd(CO, VC), CI, KH, KW, VC),
                                    dtype=kernel.dtype)
        new_workload = autotvm.task.args_to_workload(
            [new_data, new_kernel, strides, padding, dilation, out_dtype],
            "conv2d_nchw_spatial_pack.bifrost",
        )
        dispatch_ctx.update(target, new_workload, cfg)

        return relay.nn.conv2d(*inputs, **new_attrs)

    if topi_tmpl == "conv2d_nchw_winograd.bifrost":
        assert data_layout == "NCHW" and kernel_layout == "OIHW"
        N, CI, H, W = get_const_tuple(data.shape)
        CO, _, KH, KW = get_const_tuple(kernel.shape)
        tile_size = 2

        weight_expr = inputs[1]
        weight_expr = relay.nn.contrib_conv2d_winograd_weight_transform(
            weight_expr, tile_size=tile_size)
        weight_expr = relay.reshape(weight_expr,
                                    newshape=(KH + tile_size - 1,
                                              KW + tile_size - 1, CO, CI))

        new_attrs["tile_size"] = tile_size

        new_data = data
        new_kernel = te.placeholder(
            (KH + tile_size - 1, KW + tile_size - 1, CO, CI), kernel.dtype)
        new_workload = autotvm.task.args_to_workload(
            [new_data, new_kernel, strides, padding, dilation, out_dtype],
            "conv2d_nchw_winograd.bifrost",
        )
        dispatch_ctx.update(target, new_workload, cfg)

        return relay.nn.contrib_conv2d_winograd_without_weight_transform(
            inputs[0], weight_expr, **new_attrs)

    return None
예제 #32
0
conv7_weight = relay.var("conv7_weight")
conv8_weight = relay.var("conv8_weight")

bias1 =  relay.var("bias", relay.TensorType((96,), "float32"))
bias2 =  relay.var("2bias")
bias3 =  relay.var("3bias")
bias4 =  relay.var("4bias")
bias5 =  relay.var("5bias")
bias6 =  relay.var("6bias")
bias7 =  relay.var("7bias")
bias8 =  relay.var("8bias")


simple_net = relay.nn.conv2d(data=data, weight=conv1_weight, kernel_size=(11,11), channels=96, strides=(4,4),padding=(0, 0))
simple_net = relay.nn.bias_add(data=simple_net, bias=bias1)
simple_net = relay.reshape(simple_net, (batch_size,96,55,55))
simple_net = relay.nn.relu(data=simple_net)
simple_net = relay.reshape(simple_net, (batch_size,96,55,55))
simple_net = relay.nn.lrn(data=simple_net,size=5, axis=1, bias=2, alpha=.00001, beta=0.75)
simple_net = relay.reshape(simple_net, (batch_size,96,55,55))
simple_net = relay.nn.max_pool2d(data=simple_net, pool_size=(3, 3), strides=(2, 2), padding=(0, 0), layout="NCHW")

simple_net = relay.nn.conv2d(data=simple_net, weight=conv2_weight, kernel_size=(5,5), channels=256, strides=(1,1),padding=(2, 2))
simple_net = relay.nn.bias_add(data=simple_net, bias=bias2)
simple_net = relay.reshape(simple_net, (batch_size,256,27,27))
simple_net = relay.nn.relu(data=simple_net)
simple_net = relay.reshape(simple_net, (batch_size,256,27,27))
simple_net = relay.nn.lrn(data=simple_net,size=5, axis=1, bias=2, alpha=.00001, beta=0.75)
simple_net = relay.reshape(simple_net, (batch_size,256,27,27))
simple_net = relay.nn.max_pool2d(data=simple_net, pool_size=(3, 3), strides=(2, 2), padding=(0, 0), layout="NCHW")
예제 #33
0
def relay_conv_transpose2d(c, input, weight, stride, padding, output_padding,
                           groups, dilation):
    """Implement conv2d_transpose using 10 relay calls including conv2d.

    Support all values for groups, dilation, strides, padding and
    output padding.
    Based on Theano implementation (2020/04/14):
    https://github.com/Theano/Theano/blob/master/theano/tensor/nnet/abstract_conv.py#L2927
    Need implementation of operation relay.nn.dilate
    in TVM relay backend
    """

    assert stride.is_constant(tuple)
    assert padding.is_constant(tuple)
    assert output_padding.is_constant(tuple)
    assert dilation.is_constant(tuple)
    assert groups.is_constant(int)

    data_shape = input.abstract.xshape()
    kern_shape = weight.abstract.xshape()
    h_in, w_in = data_shape[2:]
    filter_h, filter_w = kern_shape[2:]
    strides = stride.value
    padding = padding.value
    dilation = dilation.value
    output_padding = output_padding.value
    groups = groups.value
    data = c.ref(input)
    weight = c.ref(weight)

    h_out = ((h_in - 1) * strides[0] - 2 * padding[0] + dilation[0] *
             (filter_h - 1) + output_padding[0] + 1)
    w_out = ((w_in - 1) * strides[1] - 2 * padding[1] + dilation[1] *
             (filter_w - 1) + output_padding[1] + 1)

    data_dilated = relay.nn.dilate(data, (1, 1) + strides)
    data_padded = relay.nn.pad(
        data_dilated,
        (
            (0, 0),
            (0, 0),
            (0, output_padding[0]),
            (0, output_padding[1]),
        ),
    )

    # Pre-process kernel,
    # from (m0, m1, m2, m3) to (m1 * g, m0 // g, m2, m3).
    mshp0 = kern_shape[0] // groups
    c_out = kern_shape[1] * groups
    kern = relay.reshape(weight, (groups, mshp0) + kern_shape[1:])
    # => (g, m0 // g, m1, m2, m3)
    kern = relay.op.transpose(kern, axes=(1, 0, 2, 3, 4))
    # => (m0 // g, g, m1, m2, m3)
    kern = relay.reshape(kern, (mshp0, c_out, kern_shape[-2], kern_shape[-1]))
    # => (m0 // g, m1 * g, m2, m3)
    kern = relay.op.transpose(kern, (1, 0, 2, 3))
    # => (m1 * g, m0 // g, m2, m3)
    # Kernel 2 latest dimensions must be flipped
    kern = relay.op.transform.reverse(kern, 2)
    kern = relay.op.transform.reverse(kern, 3)
    # End pre-processing kernel.

    img = relay.nn.conv2d(
        data_padded,
        kern,
        groups=groups,
        channels=c_out,
        padding=[(kern_shape[2 + i] - 1) * dilation[i] for i in range(2)],
        dilation=dilation,
    )

    if any(p != 0 for p in padding):
        img = relay.op.transform.strided_slice(
            data=img,
            begin=[0, 0, padding[0], padding[1]],
            end=[None, None, h_out + padding[0], w_out + padding[1]],
        )

    return img
예제 #34
0
def _get_model(input_shape, output_shape, dtype, var_names):
    """Return a model and any parameters it may have."""
    a = relay.var(next(var_names), shape=input_shape, dtype=dtype)
    reshape = relay.reshape(a, output_shape)
    return reshape