コード例 #1
0
    def _common(cls, node, **kwargs):
        all_nodes = kwargs['all_nodes']
        G = kwargs['G']
        valid_name = kwargs['valid_name']
        inputs = [all_nodes[inp] for inp in node.input]
        x = inputs[0]
        x_shape = cls._get_real_dim(x[2].shape)
        y = inputs[1]
        y_shape = cls._get_real_dim(y[2].shape)
        if cls.is_linear(y, x_shape, y_shape):
            filt_dim = FcFilterDim(y_shape[1], x_shape[0])
            weights = np.transpose(cls.get_constant(y), [1, 0])
            params = FcParameters(valid_name,
                                  filt=filt_dim,
                                  has_bias=False,
                                  in_dims_hint=SparseList([['c']]),
                                  out_dims_hint=SparseList([['c']]),
                                  constant_store=G.constant_store)
            params.weights = weights
            out_dims = params.get_output_size([Dim.unnamed(x_shape)])
        else:
            params = MatMulOpParameters(valid_name)
            out_dims = params.get_output_size(
                [Dim.unnamed(x_shape),
                 Dim.unnamed(y_shape)])
            G.add_edge(
                NNEdge(from_node=y[0], to_node=params, from_idx=y[1],
                       to_idx=1))
        G.add_edge(
            NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))

        pout_dims = x[2].infer_mapping(out_dims[0].shape)
        all_nodes[node.output[0]] = (params, 0, pout_dims)
        return params
コード例 #2
0
ファイル: test_operations.py プロジェクト: hasetz/gap_sdk
def test_fc():
    filt = FcFilterDim(3, 3, 3, 1)
    params = FcParameters("test", filt=filt)
    weights_q = QType(16, 2, True)
    in_q = QType(16, 2, True)
    acc_q = QType(16, 4, True)
    calc_q = QType(16, 4, True)
    qrec = FilterQuantizationRecord(in_qs=[in_q],
                                    out_qs=[in_q],
                                    calc_q=calc_q,
                                    acc_q=acc_q,
                                    biases_q=None,
                                    weights_q=weights_q)
    weights = weights_q.quantize(np.full([3, 1, 3, 3], 1.0))
    input_ = in_q.quantize(np.arange(9)).reshape([1, 3, 3])
    in_dims = Dim.named(c=1, h=3, w=3).impose_order(['c', 'h', 'w'])
    out_dims = params.get_output_size([in_dims])

    output_ = linear(params,
                     in_dims,
                     out_dims[0],
                     input_,
                     weights,
                     None,
                     qrec=qrec)
    output_ = in_q.dequantize(output_)
    assert np.array_equal(output_, [[[36]], [[36]], [[36]]])
コード例 #3
0
ファイル: gemm.py プロジェクト: bot-motion/gap_sdk
    def _common(cls, node, **kwargs):
        all_nodes = kwargs['all_nodes']
        G = kwargs['G']
        valid_name = kwargs['valid_name']

        trans_a = node.attrs.get('transA', 0)
        trans_b = node.attrs.get('transB', 0)
        alpha = node.attrs.get('alpha', 1.0)
        beta = node.attrs.get('beta', 1.0)

        inputs = [all_nodes[inp] for inp in node.input]

        x = inputs[0]
        x_shape = x[2].shape
        y = inputs[1]
        y_shape = y[2].shape

        real_x_shape = cls._get_real_dim(x_shape)
        real_y_shape = cls._get_real_dim(y_shape)

        real_x_shape = [
            real_x_shape[1], real_x_shape[0]
        ] if len(real_x_shape) == 2 and trans_a else real_x_shape
        real_y_shape = [
            real_y_shape[1], real_y_shape[0]
        ] if len(real_y_shape) == 2 and trans_b else real_y_shape

        if not cls.is_linear(y, real_x_shape, real_y_shape) or trans_a:
            raise ValueError(
                "GEMM is only currently supported for operations that map onto a linear kernel"
            )

        if len(inputs) > 2:
            has_bias = True
            biases = cls.get_constant(inputs[2])
        else:
            biases = None
            has_bias = False

        filt_dim = FcFilterDim(real_y_shape[1], real_x_shape[0])
        weights = cls.get_constant(y) * alpha
        if not trans_b:
            weights = np.transpose(weights, [1, 0])
        params = FcParameters(valid_name,
                              filt=filt_dim,
                              has_bias=has_bias,
                              in_dims_hint=SparseList([['c']]),
                              out_dims_hint=SparseList([['c']]),
                              constant_store=G.constant_store)
        params.weights = weights
        params.biases = biases * beta
        out_dims = params.get_output_size([Dim.unnamed(real_x_shape)])
        G.add_edge(
            NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))
        if isinstance(x[2], ProvisionalDim):
            out_dim = x[2].infer_mapping(out_dims[0].shape)
        else:
            out_dim = out_dims[0]
        all_nodes[node.output[0]] = (params, 0, out_dim)
        return params
コード例 #4
0
    def _common(cls, node, **kwargs):
        all_nodes = kwargs['all_nodes']
        G = kwargs['G']
        valid_name = kwargs['valid_name']
        inputs = [all_nodes[inp] for inp in node.input]
        x = inputs[0]
        x_shape = cls._get_real_dim(x[2].shape)
        y = inputs[1]
        y_shape = cls._get_real_dim(y[2].shape)
        if cls.is_linear(y, x_shape, y_shape):
            filt_dim = FcFilterDim(y_shape[1], x_shape[0])
            weights = np.transpose(cls.get_constant(y), [1, 0])
            weights_params = ConstantInputParameters(f'{valid_name}_weights',
                                                     dims=Dim.unnamed(
                                                         [y_shape[1], x_shape[0]]),
                                                     value=weights)
            params = FcParameters(valid_name, filt=filt_dim, has_bias=True,
                                #   in_dims_hint=[
                                #       ['c'], ['out_c', 'in_c'], ['out_c']],
                                  in_dims_hint=[
                                      None, ['out_c', 'in_c'], ['out_c']],
                                  out_dims_hint=[['c']],
                                  constant_store=G.constant_store)
            out_dims = params.get_output_size([Dim.unnamed(x_shape)])
            biases_params = ConstantInputParameters(f'{valid_name}_biases', dims=Dim.unnamed([y_shape[1]]),
                                                    value=np.zeros((y_shape[1]), dtype=np.float32))
            G.add_edge(NNEdge(from_node=weights_params,
                              to_node=params, to_idx=1))
            G.add_edge(NNEdge(from_node=biases_params,
                              to_node=params, to_idx=2))
        else:
            params = MatMulOpParameters(valid_name)
            out_dims = params.get_output_size(
                [Dim.unnamed(x_shape), Dim.unnamed(y_shape)])
            G.add_edge(
                NNEdge(from_node=y[0], to_node=params, from_idx=y[1], to_idx=1))
        G.add_edge(
            NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))

        pout_dims = x[2].infer_mapping(out_dims[0].shape)
        all_nodes[node.output[0]] = (params, 0, pout_dims)
        return params
コード例 #5
0
    def _handle(cls, node, quantized=False, **kwargs):
        all_nodes = kwargs['all_nodes']
        G = kwargs['G']
        valid_name = kwargs['valid_name']
        inputs = [all_nodes[inp] for inp in node.input]
        x = inputs[0]
        x_shape = cls._get_real_dim(x[2].shape)
        y_idx = 3 if quantized else 1
        y = inputs[y_idx]
        y_shape = cls._get_real_dim(y[2].shape)

        if quantized:
            qrecs = kwargs['qrecs']
            x_zp = cls.get_constant(inputs[2])
            x_scale = cls.get_constant(inputs[1])
            if len(x_scale) > 1:
                raise NotImplementedError('QMatMul scales must be scalar')
            x_qtype = QType(dtype=x_zp.dtype, scale=x_scale, zero_point=x_zp)
            y_zp = cls.get_constant(inputs[5])
            y_scale = cls.get_constant(inputs[4])
            if len(y_scale) > 1:
                raise NotImplementedError('QMatMul scales must be scalar')
            y_qtype = QType(dtype=y_zp.dtype, scale=y_scale, zero_point=y_zp)
            o_zp = cls.get_constant(inputs[7])
            o_scale = cls.get_constant(inputs[6])
            o_qtype = QType(dtype=o_zp.dtype, scale=o_scale, zero_point=o_zp)
        else:
            o_qtype = None

        if cls.is_linear(y, x_shape, y_shape):
            filt_dim = FcFilterDim(y_shape[1], x_shape[0])
            weights = np.transpose(cls.get_constant(y), [1, 0])
            weights_params = ConstantInputParameters(
                f'{valid_name}_weights',
                dims=Dim.unnamed([y_shape[1], x_shape[0]]),
                value=weights)
            cls.record_constant_qrec(y, weights_params, **kwargs)
            params = FcParameters(
                valid_name,
                filt=filt_dim,
                has_bias=True,
                #   in_dims_hint=[
                #       ['c'], ['out_c', 'in_c'], ['out_c']],
                in_dims_hint=[None, ['out_c', 'in_c'], ['out_c']],
                out_dims_hint=[['c']])

            out_dims = params.get_output_size([Dim.unnamed(x_shape)])
            biases_params = ConstantInputParameters(
                f'{valid_name}_biases',
                dims=Dim.unnamed([y_shape[1]]),
                value=np.zeros((y_shape[1]), dtype=np.float32))
            G.add_edge(
                NNEdge(from_node=weights_params, to_node=params, to_idx=1))
            G.add_edge(
                NNEdge(from_node=biases_params, to_node=params, to_idx=2))
            if quantized:
                weights_params.qtype = y_qtype
                qrecs[NodeId(params)] = QRec.scaled(
                    in_qs=[x_qtype, y_qtype, None],
                    out_qs=[o_qtype],
                )
        else:
            params = MatMulTransposedParameters(valid_name)
            trans_shape = [i for i in range(len(y_shape))]
            temp = trans_shape[-1]
            trans_shape[-1] = trans_shape[-2]
            trans_shape[-2] = temp
            trans2 = TransposeParameters(f'{valid_name}_tin2',
                                         transpose=tuple(trans_shape))
            out_dims = params.get_output_size([
                Dim.unnamed(x_shape),
                Dim.unnamed(y_shape[:-2] + y_shape[-2:][::-1])
            ])
            G.add_edge(
                NNEdge(from_node=y[0], to_node=trans2, from_idx=y[1],
                       to_idx=0))
            G.add_edge(
                NNEdge(from_node=trans2, to_node=params, from_idx=0, to_idx=1))
            biases_params = ConstantInputParameters(
                f'{valid_name}_biases',
                dims=Dim.unnamed([out_dims[0].shape[1]]),
                value=np.zeros((out_dims[0].shape[1]), dtype=np.float32))
            G.add_edge(
                NNEdge(from_node=biases_params, to_node=params, to_idx=2))

            if quantized:
                qrecs[NodeId(trans2)] = QRec.scaled(
                    in_qs=[y_qtype],
                    out_qs=[y_qtype],
                )
                qrecs[NodeId(params)] = QRec.scaled(
                    in_qs=[x_qtype, y_qtype],
                    out_qs=[o_qtype],
                )

        G.add_edge(
            NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))

        pout_dims = x[2].infer_mapping(out_dims[0].shape)
        all_nodes[node.output[0]] = (params, 0, pout_dims, o_qtype)
        return params
コード例 #6
0
ファイル: gemm.py プロジェクト: mfkiwl/gap_sdk
    def _common(cls, node, **kwargs):
        all_nodes = kwargs['all_nodes']
        G = kwargs['G']
        valid_name = kwargs['valid_name']

        trans_a = node.attrs.get('transA', 0)
        trans_b = node.attrs.get('transB', 0)
        alpha = node.attrs.get('alpha', 1.0)
        beta = node.attrs.get('beta', 1.0)

        inputs = [all_nodes[inp] for inp in node.input]

        x = inputs[0]
        x_shape = x[2].shape
        y = inputs[1]
        y_shape = y[2].shape

        real_x_shape = cls._get_real_dim(x_shape)
        real_y_shape = cls._get_real_dim(y_shape)

        real_x_shape = [
            real_x_shape[1], real_x_shape[0]
        ] if len(real_x_shape) == 2 and trans_a else real_x_shape
        real_y_shape = [
            real_y_shape[1], real_y_shape[0]
        ] if len(real_y_shape) == 2 and trans_b else real_y_shape

        if not cls.is_linear(y, real_x_shape, real_y_shape) or trans_a:
            raise ValueError(
                "GEMM is only currently supported for operations that map onto a linear kernel"
            )

        if len(inputs) > 2:
            biases = cls.get_constant(inputs[2])
        else:
            biases = np.zeros([real_y_shape[1]], dtype=np.float32)

        filt_dim = FcFilterDim(real_y_shape[1], real_x_shape[0])

        # always create new constants since they may be modified by this not and could be linked elsewhere
        weights = cls.get_constant(y) * alpha
        if not trans_b:
            weights = np.transpose(weights, [1, 0])
        weights_params = ConstantInputParameters(f'{valid_name}_weights',
                                                 dims=Dim.unnamed(
                                                     weights.shape),
                                                 value=weights)
        biases = biases * beta
        biases_params = ConstantInputParameters(f'{valid_name}_biases',
                                                dims=Dim.unnamed(biases.shape),
                                                value=biases)

        params = FcParameters(
            valid_name,
            filt=filt_dim,
            has_bias=True,
            #   in_dims_hint=[['c']],
            in_dims_hint=[None, ['out_c', 'in_c'], ['out_c']],
            out_dims_hint=[['c']],
            constant_store=G.constant_store)

        G.add_edge(NNEdge(from_node=weights_params, to_node=params, to_idx=1))
        G.add_edge(NNEdge(from_node=biases_params, to_node=params, to_idx=2))

        out_dims = params.get_output_size([Dim.unnamed(real_x_shape)])
        G.add_edge(
            NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))
        if isinstance(x[2], ProvisionalDim):
            out_dim = x[2].infer_mapping(out_dims[0].shape)
        else:
            out_dim = out_dims[0]
        all_nodes[node.output[0]] = (params, 0, out_dim)
        return params
コード例 #7
0
    def _common(cls, node, **kwargs):

        all_nodes = kwargs['all_nodes']
        trans_a = node.attrs.get('transA', 0)
        trans_b = node.attrs.get('transB', 0)
        alpha = node.attrs.get('alpha', 1.0)
        beta = node.attrs.get('beta', 1.0)

        inputs = [all_nodes[inp] for inp in node.input]

        x = inputs[0]
        x_shape = x[2].shape
        y = inputs[1]
        y_shape = y[2].shape

        real_x_shape = cls._get_real_dim(x_shape)
        real_y_shape = cls._get_real_dim(y_shape)

        real_x_shape = [real_x_shape[1], real_x_shape[0]] if len(
            real_x_shape) == 2 and trans_a else real_x_shape
        real_y_shape = [real_y_shape[1], real_y_shape[0]] if len(
            real_y_shape) == 2 and trans_b else real_y_shape

        if not cls.is_linear(y, real_x_shape, real_y_shape) or trans_a:
            if alpha != 1.0 or beta != 1.0:
                raise NotImplementedError('Alpha and Beta not implemented on pure matmul GEMM')
            return cls._import_as_matmul(node, inputs, x, y, real_x_shape, real_y_shape,
                                         trans_a, trans_b, alpha, beta, **kwargs)

        G = kwargs['G']
        valid_name = kwargs['valid_name']
        if len(inputs) > 2:
            biases = cls.get_constant(inputs[2])
        else:
            biases = np.zeros([real_y_shape[1]], dtype=np.float32)

        filt_dim = FcFilterDim(real_y_shape[1], real_x_shape[0])

        # always create new constants since they may be modified by this not and could be linked elsewhere
        weights = cls.get_constant(y) * alpha
        if not trans_b:
            weights = np.transpose(weights, [1, 0])
        weights_params = ConstantInputParameters(
            f'{valid_name}_weights', dims=Dim.unnamed(weights.shape), value=weights)
        if y[3]:
            if alpha == 1.0:
                cls.record_constant_qrec(y, weights_params, **kwargs)
            else:
                raise NotImplementedError("qtype on Gemm with alpha != 1.0")

        biases = biases * beta
        biases_params = ConstantInputParameters(
            f'{valid_name}_biases', dims=Dim.unnamed(biases.shape), value=biases)
        if len(inputs) > 2 and inputs[2][3]:
            if beta == 1.0:
                cls.record_constant_qrec(inputs[2], biases_params, **kwargs)
            else:
                raise NotImplementedError("qtype on Gemm with beta != 1.0")

        params = FcParameters(valid_name, filt=filt_dim, has_bias=True,
                              #   in_dims_hint=[['c']],
                              in_dims_hint=[
                                  None, ['out_c', 'in_c'], ['out_c']],
                              out_dims_hint=[['c']])

        G.add_edge(NNEdge(from_node=weights_params, to_node=params, to_idx=1))
        G.add_edge(NNEdge(from_node=biases_params, to_node=params, to_idx=2))

        out_dims = params.get_output_size([Dim.unnamed(real_x_shape)])
        G.add_edge(
            NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))
        if isinstance(x[2], ProvisionalDim):
            out_dim = x[2].infer_mapping(out_dims[0].shape)
        else:
            out_dim = out_dims[0]
        all_nodes[node.output[0]] = (params, 0, out_dim, None)
        return params