def create_sample_graph(data1: np.ndarray) -> Graph: graph = Graph() # input x = Input('placeholder', [1, 5, 5, 3], Float32()) # Conv1 w1 = Constant('weight1', Float32(), data1) conv1 = Conv('conv1', [1, 4, 4, 3], QUANTIZED_PACKED(), { 'X': x, 'W': w1 }, kernel_shape=[2, 2]) conv1.is_quantized = True pool1 = SpaceToDepth('s2d', [1, 2, 2, 12], Float32(), {'input': conv1}) # One output y = Output('output', [1, 2, 2, 12], Float32(), {'input': pool1}) # add ops to the graph graph.add_op_and_inputs(y) return graph
def create_sample_graph(data1: np.ndarray, data2: np.ndarray) -> Graph: graph = Graph() # input x = Input('placeholder', [1, 5, 5, 3], Float32()) # Conv1 w1 = Constant('weight1', Float32(), data1) conv1 = Conv('conv1', [1, 4, 4, 3], Float32(), {'X': x, 'W': w1}, kernel_shape=[2, 2]) # activation quantizer s1 = Constant('aq_const1', Int32(), np.array([2], dtype=np.int32)) s2 = Constant('aq_const2', Float32(), np.array([2.0], dtype=np.float32)) aq1 = QTZ_linear_mid_tread_half('aqtz1', [1, 4, 4, 3], Float32(), {'X': conv1, 'Y': s1, 'Z': s2}) # Conv2 w2 = Constant('weight2', Float32(), data2) kq = QTZ_binary_mean_scaling('kqtz1', [1, 2, 2, 3], Float32(), {'input': w2}) conv2 = Conv('conv2', [1, 3, 3, 3], Float32(), {'X': aq1, 'W': kq}, kernel_shape=[2, 2]) conv2.a_quantizer = [aq1] conv2.quantizer = kq conv2.is_quantized = True sc = Constant('bn_scale', Float32(), np.random.rand(3)) be = Constant('bn_b', Float32(), np.random.rand(3)) mu = Constant('bn_mu', Float32(), np.random.rand(3)) va = Constant('bn_var', Float32(), np.random.rand(3)) bn = BatchNormalization('bn', [1, 3, 3, 3], Float32(), {'X': conv2, 'scale': sc, 'B': be, 'mean': mu, 'var': va}) # activation quantizer s3 = Constant('aq_const3', Int32(), np.array([2], dtype=np.int32)) s4 = Constant('aq_const4', Float32(), np.array([2.0], dtype=np.float32)) aq2 = QTZ_linear_mid_tread_half('aqtz2', [1, 3, 3, 3], Float32(), {'X': bn, 'Y': s3, 'Z': s4}) # One output y = Output('output', [1, 3, 3, 3], Float32(), {'input': aq2}) # add ops to the graph graph.add_op_and_inputs(y) return graph
def run_forward_conv(self, node: Conv, **kwargs: Any) -> None: ops: List[Operator] = [ node.input_ops[i] for i in node.input_names if node.input_ops.get(i) ] if self._hard_quantized and node in kwargs['qconv']: # data is to be packed ops_have_precomp_values = list( map(lambda x: self._has_precompute_value(x), ops)) ops_are_prunable = list(map(lambda x: self._is_prunable(x), ops)) # check which input node can be pruned if reduce( lambda x, y: x and y, ops_have_precomp_values): # all input has concrete values node.run_forward() self._precomp_dic[node.name] = True # this node can be pruned quantizers = { op.name: self._quantizers[op.name] for op in ops if self._quantizers.get(op.name) } if len(quantizers) > 1: ValueError( f'{node.name}: multiple quantized inputs with {node.op_type} are not supported.' ) self._quantizers[node.name] = list(quantizers.values())[0] else: # an input (must be weight) is to be quantized and packed self._precomp_dic[node.name] = False node.is_quantized = True packer = Packer(self._quantized_bitwidth, self._wordsize) quantizers = { op.name: self._quantizers[op.name] for op in ops if self._quantizers.get(op.name) } if len(quantizers) > 1: ValueError( f'{node.name}: multiple quantized inputs with {node.op_type} are not supported.' ) node.quantizer = list(quantizers.values())[0] for key, op in zip(node.input_names, ops): if self._is_prunable(op): shape = op.shape op_data = node.quantizer.binarizer(op.data) data = packer.run(op_data.astype(np.float32), op.dimension) dtype = op.dtype new_op = Constant(op.name + '_new', dtype, data, packed=True, actual_shape=shape) node.add_input(key, new_op) self._graph.add_op(new_op) self._prune(op) else: self._precompute_or_prune_inputs(node)