def test_conv_pool_relu_kernel_gen(mnist_unfused_8bit_state): G = load_state(mnist_unfused_8bit_state) conv_params = G.graph_state.steps[1]['node'] relu_params = G.graph_state.steps[2]['node'] pool_params = G.graph_state.steps[3]['node'] conv_q = G.quantization[NodeId(conv_params)] pool_q = G.quantization[NodeId(pool_params)] relu_q = G.quantization[NodeId(relu_params)] code_block = gen_conv_pool_relu("Test", conv_params, conv_q, None, None, None, None) assert str(code_block) ==\ 'CNN_ConvolutionPoolReLU("Test", 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 28, 28,\n KOP_CONV, 5, 5, 1, 1, 1, 1, 0,\n KOP_NONE, 0, 0, 0, 0, 0, 0, 0, KOP_NONE);' code_block = gen_conv_pool_relu("Test", conv_params, conv_q, pool_params, pool_q, relu_params, relu_q) assert str(code_block) ==\ 'CNN_ConvolutionPoolReLU("Test", 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 28, 28,\n KOP_CONV, 5, 5, 1, 1, 1, 1, 0,\n KOP_MAXPOOL, 2, 2, 1, 1, 2, 2, 0, KOP_RELU);' code_block = gen_conv_pool_relu("Test", conv_params, conv_q, None, None, relu_params, relu_q) assert str(code_block) ==\ 'CNN_ConvolutionPoolReLU("Test", 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 28, 28,\n KOP_CONV, 5, 5, 1, 1, 1, 1, 0,\n KOP_NONE, 0, 0, 0, 0, 0, 0, 0, KOP_RELU);' code_block = gen_conv_pool_relu("Test", conv_params, conv_q, pool_params, pool_q, None, None) assert str(code_block) ==\ 'CNN_ConvolutionPoolReLU("Test", 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 28, 28,\n KOP_CONV, 5, 5, 1, 1, 1, 1, 0,\n KOP_MAXPOOL, 2, 2, 1, 1, 2, 2, 0, KOP_NONE);' code_block = gen_conv_pool_relu("Test", None, None, pool_params, pool_q, relu_params, relu_q) assert str(code_block) ==\ 'CNN_PoolReLU("Test", 0, 1, 1, 1, 1, 32, 32, 24, 24,\n KOP_MAXPOOL, 2, 2, 1, 1, 2, 2, 0, KOP_RELU);' code_block = gen_conv_pool_relu("Test", None, None, None, None, relu_params, relu_q) assert str(code_block) ==\ 'CNN_PoolReLU("Test", 0, 1, 1, 1, 1, 32, 32, 24, 24,\n KOP_NONE, 0, 0, 0, 0, 0, 0, 0, KOP_RELU);'
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_temps_report_quantized(mnist_unfused_8bit_state): G = load_state(mnist_unfused_8bit_state) G.add_dimensions() stats_collector = TempsStatsCollector(qrecs=G.quantization) stats = stats_collector.collect_stats(G) report = TempsReporter().report(G, stats) renderer = TextTableRenderer(maxwidth=200) print(report.render(renderer))
def test_fused_operational(caplog, mnist_fused_8bit_state): caplog.set_level(logging.INFO) G = load_state(mnist_fused_8bit_state) opts = { 'default_input_location': 'ARG_LOC_L2', 'default_output_location': 'ARG_LOC_L2', 'default_global_location': 'ARG_LOC_L3_HFLASH', 'default_local_location': '0', } code_gen = CodeGenerator(G, DefaultNamingConvension(G), opts) default_template(G, code_generator=code_gen)
def test_graph_calc_quantize_one_2(value_cache, mnist_unfused_16bit_state, mnist_images): G = load_state(mnist_unfused_16bit_state, value_cache=value_cache) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) output1 = execute(G, [input_tensor]) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) output2 = execute(G, [input_tensor], qmode=QuantizationMode.step(4), qrecs=G.quantization) diffs = [] for i, out1 in enumerate(output1): diffs.append(out1[0] - output2[i][0]) assert np.min(diffs[7]) > -2 and np.max(diffs[7]) < 2
def test_graph_calc_quantized8(value_cache, mnist_unfused_8bit_state, mnist_images): G = load_state(mnist_unfused_8bit_state, value_cache=value_cache) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) output1 = execute(G, [input_tensor], limit=7) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) output2 = execute(G, [input_tensor], qrecs=G.quantization, limit=7, dequantize=True) diffs = [] for i in range(8): diffs.append(output1[i][0] - output2[i][0]) assert np.max(np.abs(diffs[7])) < 9
def generate_code(args): LOG.propagate = False handler = GeneratorShellLogHandler() formatter = logging.Formatter('%(module)s - %(message)s') handler.setFormatter(formatter) LOG.addHandler(handler) if args.log_level: LOG.setLevel(args.log_level.upper()) else: LOG.setLevel('WARN') LOG.info("Loading %s", args.graph_file) G, opts = load_state(args.graph_file, return_extra=True) if args.model_file: opts['model_file'] = args.model_file if args.model_directory: opts['model_directory'] = args.model_directory if args.tensor_directory: opts['tensor_directory'] = args.tensor_directory opts['basic_kernel_header_file'] = args.model_file opts['basic_kernel_source_file'] = args.model_file os.makedirs(os.path.abspath(opts['model_directory']), mode=0o750, exist_ok=True) os.makedirs(os.path.abspath(opts['tensor_directory']), mode=0o750, exist_ok=True) code_gen = CodeGenerator(G, DefaultNamingConvension(G), opts) if args.template_file: code_template = dynamic_template(args.template_file) else: code_template = default_template write_template(G, code_gen, opts['model_directory'], opts['model_file'], code_template, "model") if G.has_expressions: write_template(G, code_gen, opts['model_directory'], opts['basic_kernel_header_file'], basic_kernel_header_template, "kernel headers") write_template(G, code_gen, opts['model_directory'], opts['basic_kernel_source_file'], basic_kernel_source_template, "kernel source") if args.header_file: with open(os.path.join(opts['model_directory'], args.header_file), "w") as output_fp: output_fp.write(header_template(G, code_generator=code_gen)) if not args.dont_dump_tensors: LOG.info("Writing constants to %s", opts['model_directory']) code_gen.write_constants()
def test_error_report(mnist_unfused_8bit_state, mnist_images): G = load_state(mnist_unfused_8bit_state) 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 = ErrorStatsCollector() stats_collector.collect_stats(G, [input_tensor]) stats_collector.collect_stats(G, [input_tensor]) report = ErrorReporter().report(G, stats_collector.reduce_stats()) renderer = TextTableRenderer(maxwidth=200) print(report.render(renderer))
def test_graph_calc_quantized8_qnoq(mnist_unfused_8bit_state, mnist_images): G = load_state(mnist_unfused_8bit_state) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) executer = GraphExecuter(G, qrecs=G.quantization) diffs = [] for step_idx, pnode, output, details, qoutput, qdetails, fnode in\ executer.execute_qnoq_iterator([input_tensor]): del step_idx, pnode, details, qdetails, fnode diffs.append(output[0] - qoutput[0]) assert np.max(np.abs(diffs[7])) < 9
def generate_code(args): LOG.propagate = False handler = GeneratorShellLogHandler() formatter = logging.Formatter('%(module)s - %(message)s') handler.setFormatter(formatter) LOG.addHandler(handler) if args.log_level: LOG.setLevel(args.log_level.upper()) else: LOG.setLevel('WARN') LOG.info("Loading %s", args.graph_file) G, opts = load_state(args.graph_file, return_extra=True) if args.model_file: opts['model_file'] = args.model_file if args.model_directory: opts['model_directory'] = args.model_directory if args.tensor_directory: opts['tensor_directory'] = args.tensor_directory os.makedirs(os.path.abspath(opts['model_directory']), mode=0o750, exist_ok=True) os.makedirs(os.path.abspath(opts['tensor_directory']), mode=0o750, exist_ok=True) model_path = os.path.join(opts['model_directory'], opts['model_file']) LOG.info("Saving model to %s", model_path) code_gen = CodeGenerator(G, DefaultNamingConvension(G), opts) if args.template_file: code_template = dynamic_template(args.template_file) else: code_template = default_template model = code_template(G, code_generator=code_gen) if not model: LOG.error("error generating model code") sys.exit(1) with open(model_path, "w") as output_fp: output_fp.write(model) if args.header_file: with open(os.path.join(opts['model_directory'], args.header_file), "w") as output_fp: output_fp.write(header_template(G, code_generator=code_gen)) if not args.dont_dump_tensors: LOG.info("Writing constants to %s", opts['model_directory']) code_gen.write_constants()
def test_tensor_dump(mnist_fused_8bit_state): with tempfile.TemporaryDirectory() as tempdir: G = load_state(mnist_fused_8bit_state) opts = { 'default_input_location': 'ARG_LOC_L2', 'default_output_location': 'ARG_LOC_L2', 'default_global_location': 'ARG_LOC_L3_HFLASH', 'default_local_location': '0', 'tensor_directory': tempdir } code_gen = CodeGenerator(G, DefaultNamingConvension(G), opts) default_template(G, code_generator=code_gen) code_gen.write_constants() files_list = [ f for f in os.listdir(tempdir) if os.path.isfile(os.path.join(tempdir, f)) ] assert set(files_list) == set([ 'Step2Weights.tensor', 'Step1Weights.tensor', 'Step1Biases.tensor', 'Step3Weights.tensor', 'Step2Biases.tensor', 'Step3Biases.tensor' ])
def test_graph_calc_quantized8(mnist_unfused_8bit_state, mnist_images): G = load_state(mnist_unfused_8bit_state) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) executer = GraphExecuter(G, qrecs=G.quantization) output1 = executer.execute([input_tensor], step_idx_limit=7) input_tensor = import_data(mnist_images[0], height=28, width=28, offset=0, divisor=255) input_tensor = input_tensor.reshape((28, 28, 1)) output2 = executer.execute([input_tensor], qmode=QuantizationMode.all_dequantize(), step_idx_limit=7) diffs = [] for i in range(8): diffs.append(output1[i][0] - output2[i][0]) assert np.max(np.abs(diffs[7])) < 9
def __open_graph(self, graph_file, tensor_file, load_quantization, load_dequantized): graph_file = os.path.expanduser(graph_file) _, ext = os.path.splitext(graph_file) if ext == STATE_EXTENSION: LOG.info("opening state file %s", graph_file) self.graph_file = graph_file self.G, extra = load_state(graph_file, return_extra=True) self.settings.update(extra) else: LOG.info("opening graph file %s", graph_file) opts = { 'load_tensors': True, 'load_quantization': load_quantization, 'load_dequantized': load_dequantized } G = create_graph(graph_file, opts=opts) G.add_dimensions() if tensor_file: G.load_tensors(tensor_file) self.G = G self.graph_file = graph_file if tensor_file is not None: self.tensor_file = tensor_file self.settings['load_quantization'] = bool(load_quantization) if self.settings['adjust_order']: LOG.info("adjusting order") self.execute_adjust_order() if self.settings['weight_equalization']: LOG.info("equalizing weights") weight_equalization(self.G, self.settings['equalization_threshold'])
def test_tune_state(mnist_unfused_16bit_state): G = load_state(mnist_unfused_16bit_state) tuneq(G, G.quantization, 1, 'acc', 3, 13)
def test_fused_operational(caplog, mnist_fused_8bit_state): caplog.set_level(logging.INFO) G = load_state(mnist_fused_8bit_state) default_template(G)