def do_astats(self, args: argparse.Namespace): """ Calculate activation statistics on one or more input files.""" self._check_graph() input_args = self._get_input_args(args) stats_collector = ActivationStatsCollector() step_idx = args.step if step_idx is not None: if len(step_idx) == 1: step_idx = step_idx[0] else: step_idx = tuple(step_idx) if len(args.input_files) == 0: self.perror("You must enter some files to process") return for file_per_input in glob_input_files(args.input_files, self.G.num_inputs): LOG.info("input file %s", file_per_input) data = [ import_data(input_file, **input_args) for input_file in file_per_input ] stats_collector.collect_stats(self.G, data) fmt = ('tab' if args.output is None else args.output['fmt']) tab = ActivationReporter(do_totals=(fmt != "csv"), threshold=args.qsnr, yield_fusions=args.detail or isinstance(step_idx, tuple)).report( self.G, stats_collector.reduce_stats()) output_table(tab, args)
def test_activation_report(mnist_graph, mnist_images): G = create_graph(mnist_graph, opts={"load_tensors": True}) G.add_dimensions() input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) stats_collector = ActivationStatsCollector() stats_collector.collect_stats(G, [input_tensor]) report = ActivationReporter().report(G, stats_collector.reduce_stats()) renderer = TextTableRenderer(maxwidth=200) print(report.render(renderer))
def test_fake_values_concat(concat_test_graph): G = create_graph(concat_test_graph, opts={"load_tensors": True}) G.add_dimensions() G.adjust_order() matcher = get_std_match_group() matcher.match(G) G.add_dimensions() G.constant_store.fake = True stats_collector = ActivationStatsCollector() stats_collector.collect_stats( G, [np.random.rand(*node.dims.shape) for node in G.inputs()]) astats = stats_collector.reduce_stats() stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(G) quantizer = SimpleQuantizer(astats, fstats, force_width=8) qrecs = quantizer.quantize(G) G.quantization = qrecs with tempfile.TemporaryDirectory() as tempdir: opts = { 'default_input_location': 'ARG_LOC_L2', 'default_output_location': 'ARG_LOC_L2', 'default_global_location': 'ARG_LOC_L3_HFLASH', 'default_local_location': '0', 'at_ver': 3, 'tensor_directory': tempdir } code_gen = CodeGenerator(G, DefaultNamingConvension(G), opts) print(default_template(G, code_generator=code_gen)) code_gen.write_constants()
def test_graph_calc(mnist_graph, mnist_images): temp_graph = create_temporary_copy(mnist_graph) G = create_graph(temp_graph, opts={"load_tensors":True}) G.add_dimensions() input_tensor = import_data(mnist_images[0], height=28, width=28, divisor=128, offset=-1) input_tensor = input_tensor.reshape(28, 28, 1) # import data always returns C, H, W. We need H, W, C. stats_collector = ActivationStatsCollector() stats_collector.collect_stats(G, [input_tensor]) astats = stats_collector.reduce_stats() stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(G) quantizer = SimpleQuantizer(astats, fstats, force_width=8) qrecs = quantizer.quantize(G) G.quantization = qrecs dump_state(G) G = load_state(temp_graph) for k, v in G.quantization.items(): assert v == qrecs[k], "problem with " + str(k) assert G.quantization == qrecs
def test_graph_imu_auto_quant_and_execute_quant(): G = create_graph("tests/graph/imu.tflite", opts={"load_tensors": True}) G.add_dimensions() G.adjust_order() get_pow2_match_group().match(G) G.add_dimensions() stats_collector = ActivationStatsCollector() for input_file in ['tests/images/imu0.pgm']: input_tensor = import_data(input_file, offset=0, divisor=256, nptype='int16') stats_collector.collect_stats(G, [input_tensor]) astats = stats_collector.reduce_stats() stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(G) quantizer = SymmetricQuantizer(astats, fstats, force_width=16) qrecs = quantizer.quantize(G) G.quantization = qrecs executer = GraphExecuter(G, qrecs=qrecs) for input_file in ['tests/images/imu0.pgm']: input_tensor = import_data(input_file, offset=0, divisor=256, nptype='int16') output_ = executer.execute([input_tensor], qmode=QuantizationMode.all())
def test_activatiofusion(actfusion_graph): G = actfusion_graph matcher = get_fusion('scale8_match_group') matcher.match(G) G.add_dimensions() astat_col = ActivationStatsCollector() astats = astat_col.collect_stats( G, [np.full([10, 10, 2], 1), np.full([10, 10, 2], 1)]) astats = astat_col.reduce_stats() quantizer = MultQuantizer(astats, force_width=8, quantized_dimension="channel") G.quantization = quantizer.quantize(G) with tempfile.TemporaryDirectory() as tempdir: opts = { 'default_input_location': 'ARG_LOC_L2', 'default_output_location': 'ARG_LOC_L2', 'default_global_location': 'ARG_LOC_L3_HFLASH', 'default_local_location': 'AT_MEM_UNDEF', 'tensor_directory': tempdir } code_gen = CodeGenerator(G, DefaultNamingConvension(G), opts) ATModel_code = default_template(G, code_generator=code_gen)
def test_graph_kws_auto_quant(kws_graph, kws_sounds): G = create_graph(kws_graph, opts={"load_tensors": True}) G.add_dimensions() G.adjust_order() get_std_match_group().match(G) G.add_dimensions() stats_collector = ActivationStatsCollector() for input_file in kws_sounds: data = import_data(input_file, offset=0, divisor=256, nptype='int16') stats_collector.collect_stats(G, [data]) astats = stats_collector.reduce_stats() stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(G) quantizer = SimpleQuantizer(astats, fstats, force_width=16) qrecs = quantizer.quantize(G) G.quantization = qrecs
def test_simple_quantization(mnist_graph, mnist_images): G = create_graph(mnist_graph, opts={"load_tensors": True}) G.add_dimensions() input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) stats_collector = ActivationStatsCollector() stats_collector.collect_stats(G, [input_tensor]) astats = stats_collector.reduce_stats() stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(G) quantizer = SymmetricQuantizer(astats, fstats, force_width=8) qrecs = quantizer.quantize(G) assert len(qrecs) == 11 # One more for saved quantizer report = QuantizationReporter().report(G, qrecs) renderer = TextTableRenderer(maxwidth=200) print(report.render(renderer))
def do_aquant(self, args: argparse.Namespace): """ Attempt to calculate quantization for graph using one or more sample imput files.""" self._check_graph() input_args = self._get_input_args(args) processed_input = False stats_collector = ActivationStatsCollector() for file_per_input in glob_input_files(args.input_files, self.G.num_inputs): LOG.info("input file %s", file_per_input) processed_input = True data = [ import_data(input_file, **input_args) for input_file in file_per_input ] stats_collector.collect_stats(self.G, data) if not processed_input: self.perror("No imput files found") return astats = stats_collector.reduce_stats() if args.scheme == 'SQ8': quantizer = MultQuantizer( astats, 8, quantized_dimension=args.quant_dimension, narrow_weights=not args.no_narrow_weights) else: stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(self.G) quantizer = SymmetricQuantizer(astats, fstats, force_width=args.force_width, min_qsnr=args.qsnr) qrecs = quantizer.quantize(self.G) self.G.quantization = qrecs if args.scheme == 'SQ8': concats_matcher = EqualizeSymmetricMultiplicativeQuantivedConcats() concats_matcher.match(self.G, set_identity=False) softmax_qrec_matcher = PropagateSoftmaxSymQrec() softmax_qrec_matcher.match(self.G, set_identity=False) LOG.info("Quantization set. Use qshow command to see it.")
def save_state(temp_dir, width, fusions=False, adjust=False): file_name = os.path.join(temp_dir, "state_file") G = create_graph(MNIST_GRAPH, opts={"load_tensors":True}) G.add_dimensions() if adjust: G.adjust_order() if fusions: get_std_match_group().match(G) G.add_dimensions() stats_collector = ActivationStatsCollector() for input_file in MNIST_IMAGES: data = import_data(input_file, offset=0, divisor=255) if not adjust: data = data.reshape((28, 28, 1)) stats_collector.collect_stats(G, [data]) astats = stats_collector.reduce_stats() stats_collector = FilterStatsCollector() fstats = stats_collector.collect_stats(G) quantizer = SimpleQuantizer(astats, fstats, force_width=width) qrecs = quantizer.quantize(G) G.quantization = qrecs dump_state(G, include_parameters=True, state_path=file_name) return file_name
def do_fquant(self, args: argparse.Namespace): """ Attempt to calculate a fake quantization for graph using random tensors and parameters. This is intended to allow code generation for performance testing even if no real weights and input data are avalaible.""" self._check_graph() self.G.constant_store.fake = True stats_collector = ActivationStatsCollector() input_tensors = [ np.random.normal(0, 0.2, input.dims.shape) for input in self.G.input_nodes() ] stats_collector.collect_stats(self.G, input_tensors) astats = stats_collector.reduce_stats() stats_collector = FakeFilterStatsCollector() fstats = stats_collector.collect_stats(self.G) quantizer = SymmetricQuantizer(astats, fstats, force_width=args.force_width) qrecs = quantizer.quantize(self.G) self.G.quantization = qrecs tab = QuantizationReporter().report(self.G, qrecs) output_table(tab, args) self.G.constant_store.fake = False