Exemple #1
0
def _pack_batch_channel(data, dshape, bfactor, cfactor):
    """Pack the data channel dimension.
    """
    assert int(dshape[0]) % bfactor == 0
    assert int(dshape[1]) % cfactor == 0
    data = op.reshape(data,
                      newshape=(int(dshape[0]) // bfactor, bfactor,
                                int(dshape[1]) // cfactor, cfactor,
                                int(dshape[2]), int(dshape[3])))
    data = op.transpose(data, axes=(0, 2, 4, 5, 1, 3))
    return data
Exemple #2
0
def _pack_weight(data, dshape, cfactor):
    """Pack the weight into packed format.
    """
    assert len(dshape) == 4
    assert int(dshape[0]) % cfactor == 0
    assert int(dshape[1]) % cfactor == 0
    data = op.reshape(data,
                      newshape=(int(dshape[0]) // cfactor, cfactor,
                                int(dshape[1]) // cfactor, cfactor,
                                int(dshape[2]), int(dshape[3])))
    data = op.transpose(data, axes=(0, 2, 4, 5, 1, 3))
    return data
Exemple #3
0
def _pack_weight_conv2d_transpose(data, dshape, cfactor):
    """Pack the weight into packed format.
    """
    dshape = _to_shape(dshape)
    assert len(dshape) == 4
    assert dshape[0] % cfactor == 0
    assert dshape[1] % cfactor == 0
    data = op.reshape(data,
                      newshape=(dshape[0] // cfactor, cfactor,
                                dshape[1] // cfactor, cfactor, dshape[2],
                                dshape[3]))
    data = op.transpose(data, axes=(2, 0, 4, 5, 3, 1))
    return data
Exemple #4
0
def _pack_const(data, dshape, dtype, bfactor, cfactor):
    """Pack a constant parameter."""
    dshape = _to_shape(dshape)
    assert len(dshape) == 3
    assert dshape[0] % cfactor == 0
    data = op.reshape(data, newshape=(dshape[0] // cfactor, cfactor, dshape[1], dshape[2], 1))
    data = op.transpose(data, axes=(0, 2, 3, 4, 1))

    # broadcast batch dimension to bfactor
    data = op.broadcast_to(
        data, shape=(dshape[0] // cfactor, dshape[1], dshape[2], bfactor, cfactor)
    )
    return data
Exemple #5
0
    def _impl(inputs, _):
        weight = inputs[1][0]
        weight_scale = inputs[1][1]
        weight_zero_point = inputs[1][2]

        inp = inputs[0]

        input_scale, input_zero_point = _calculate_qparam(inp)
        qinp = relay.qnn.op.quantize(inp,
                                     input_scale,
                                     input_zero_point,
                                     out_dtype="uint8")

        data_shape = infer_shape(inp)

        if len(data_shape) > 2:
            qinp = _op.reverse_reshape(qinp, [-1, 0])

        weight_shape = infer_shape(weight)
        units = weight_shape[0]
        dense = relay.qnn.op.dense(
            qinp,
            weight,
            input_zero_point,
            weight_zero_point,
            input_scale,
            weight_scale,
            units=units,
        )
        bias_var = inputs[1][3]

        dequant_scale = input_scale * weight_scale
        dense_out = relay.qnn.op.dequantize(dense,
                                            dequant_scale,
                                            input_zero_point=relay.const(
                                                0, "int32"),
                                            axis=1)

        if len(data_shape) > 2:
            new_shape = list(data_shape[:-1])
            new_shape.append(units)
            dense_out = _op.reshape(dense_out, new_shape)

        if bias_var is not None:
            return dense_out + bias_var

        return dense_out
Exemple #6
0
def aten_view(inputs, attributes, scope):
    assert len(inputs) == 2
    ctx = current_context()
    net = current_context().network
    if ctx.is_tensorrt and has_trt_tensor(inputs):
        shape = inputs[1][1:]
        # trt tensor shape don't include batch axis
        # TODO add batch size check
        if len(shape) == 1:
            shape += [1, 1]
        # elif len(shape) == 2:
        #     shape += [1]
        layer = net.add_shuffle(inputs[0])
        layer.reshape_dims = shape
        output = layer.get_output(0)
        layer.name = scope
        output.name = scope
        return [output]
    elif ctx.is_tvm and has_tvm_tensor(inputs):
        return [_op.reshape(inputs[0], newshape=inputs[1])]
    return [inputs[0].view(*inputs[1])]
Exemple #7
0
def _reshape(children, attrs, odtype='float32'):
    data = children[0]
    shape = attrs.get_int_list('shape')
    return op.reshape(data, shape)
Exemple #8
0
def _unpack_batch_channel(data, old_shape):
    """Unpack the data channel dimension.
    """
    data = op.transpose(data, axes=(0, 4, 1, 5, 2, 3))
    data = op.reshape(data, newshape=old_shape)
    return data
Exemple #9
0
    def visit_call(self, call):
        """ Visit the children. """
        # First visit the children.
        oshape = _get_tensor_shape(call)
        odtype = _get_tensor_type(call)
        input_types = [arg.checked_type for arg in call.args]
        args = [self.visit(arg) for arg in call.args]

        # Start and stop cases.
        if call.op == self.bitpack_start:
            assert not self.start_pack
            self.start_pack = True
            return _pack_batch_channel(args[0], oshape, self.bfactor,
                                       self.cfactor)
        if call.op == self.bitpack_end:
            if self.start_pack:
                self.start_pack = False
                data = args[0]
                data_shape = _get_tensor_shape(call.args[0])
                return _unpack_batch_channel(data, data_shape)
        if self.start_pack:
            # Operator cases
            if call.op == self.conv2d and odtype == 'int32':
                self.number_of_conv2d += 1
                assert 8 % self.weight_bits == 0
                w_lanes = 8 // self.weight_bits
                data_layout = "NCHW%dn%dc" % (self.bfactor, self.cfactor)
                kernel_layout = "OIHW%do%di" % (self.cfactor, self.cfactor)
                data, weight = args
                data_shape = _to_shape(input_types[0].shape)
                kernel_shape = _to_shape(input_types[1].shape)
                channels = call.attrs.channels
                weight, kernel_shape, channels = _weight_shape_match(
                    weight, kernel_shape, channels, self.cfactor)
                kernel = _pack_weight(weight, kernel_shape, self.cfactor)
                # insert bit packing when necessary
                if w_lanes != 1:
                    assert 8 % w_lanes == 0
                    kernel = op.bitpack(kernel, lanes=w_lanes)

                conv2d = op.nn.conv2d(data,
                                      kernel,
                                      strides=call.attrs.strides,
                                      padding=call.attrs.padding,
                                      dilation=call.attrs.dilation,
                                      groups=call.attrs.groups,
                                      channels=channels,
                                      kernel_size=call.attrs.kernel_size,
                                      data_layout=data_layout,
                                      kernel_layout=kernel_layout,
                                      out_dtype=call.attrs.out_dtype)
                return conv2d

            if call.op == self.conv2d_transpose and odtype == 'int32':
                self.number_of_conv2d += 1
                assert 8 % self.weight_bits == 0
                w_lanes = 8 // self.weight_bits
                if self.start_pack:
                    data_layout = "NCHW%dn%dc" % (self.bfactor, self.cfactor)
                    kernel_layout = "IOHW%di%do" % (self.cfactor, self.cfactor)
                    data, weight = args
                    data_shape = _to_shape(input_types[0].shape)
                    kernel_shape = _to_shape(input_types[1].shape)
                    channels = call.attrs.channels
                    weight, kernel_shape, channels = _weight_shape_match_transpose(
                        weight, kernel_shape, channels, self.cfactor)
                    kernel = _pack_weight_conv2d_transpose(
                        weight, kernel_shape, self.cfactor)
                    conv2d = op.nn.conv2d_transpose(
                        data,
                        kernel,
                        strides=call.attrs.strides,
                        padding=call.attrs.padding,
                        dilation=call.attrs.dilation,
                        groups=call.attrs.groups,
                        channels=call.attrs.channels,
                        kernel_size=call.attrs.kernel_size,
                        data_layout=data_layout,
                        kernel_layout=kernel_layout,
                        output_padding=call.attrs.output_padding,
                        out_dtype=call.attrs.out_dtype)
                return conv2d
            if call.op == self.add and \
                    tuple(input_types[0].shape) == tuple(input_types[1].shape):
                pass
            elif call.op == self.add and len(input_types[1].shape) == 3:
                data, const = args
                const, input_shape = _const_shape_match(
                    const, input_types[1].shape, self.cfactor)
                const = _pack_const(const, _to_shape(input_shape),
                                    input_types[1].dtype, self.bfactor,
                                    self.cfactor)
                return relay.Call(self.add, [data, const])
            elif call.op == self.multiply and \
                    tuple(input_types[0].shape) == tuple(input_types[1].shape):
                pass
            elif call.op == self.multiply and len(input_types[1].shape) == 3:
                data, const = args
                const = _pack_const(const, _to_shape(input_types[1].shape),
                                    input_types[1].dtype, self.bfactor,
                                    self.cfactor)
                return relay.Call(self.multiply, [data, const])
            elif self.start_pack and call.op == self.bias_add:
                data, bias = args
                bias = _pack_const(bias, _to_shape(input_types[1].shape),
                                   input_types[1].dtype, self.bfactor,
                                   self.cfactor)
                return relay.Call(self.add, [data, bias])
            elif self.start_pack and call.op == op.op.get('cast') and \
                    input_types[0].dtype == 'int32':
                cast = relay.Call(op.op.get('cast'), [args[0]], call.attrs)
                return relay.Call(op.op.get('copy'), [cast])
            elif call.op == self.pad:
                pad_width = call.attrs.pad_width
                if len(pad_width) == 6:
                    pass
                elif len(pad_width) == 4:
                    data, = args
                    new_pad_width = []
                    new_pad_width.extend(pad_width)
                    for _ in range(2):
                        new_pad_width.append([0, 0])
                    return op.nn.pad(data,
                                     pad_value=call.attrs.pad_value,
                                     pad_width=new_pad_width)
            elif call.op == self.upsampling:
                data, = args
                scale_h = call.attrs.scale_h
                scale_w = call.attrs.scale_w
                data_layout = "NCHW%dn%dc" % (self.bfactor, self.cfactor)
                method = call.attrs.method
                align_corners = call.attrs.align_corners
                return op.nn.upsampling(data, scale_h, scale_w, data_layout,
                                        method, align_corners)
            elif call.op == self.reshape and len(input_types[0].shape) == 4:
                data, _ = args
                data = op.transpose(data, axes=(0, 4, 1, 5, 2, 3))
                return op.reshape(data, [int(x) for x in input_types[0].shape])

        return relay.Call(self.visit(call.op), args, call.attrs)
Exemple #10
0
def _tvm_reshape(inp, shape, name):
    return _op.reshape(inp, newshape=shape)
Exemple #11
0
def _tvm_unsqueeze(inp, dim, name):
    inp_shape = infer_shape(inp)
    inp_shape = list(inp_shape)
    inp_shape.insert(dim, 1)
    return _op.reshape(inp, newshape=inp_shape)