def test_dump_bn_fused(): class ConvBNReLU(M.Sequential): def __init__(self): super(ConvBNReLU, self).__init__( M.Conv2d(3, 4, 3, 1, 1, groups=1, bias=False), M.BatchNorm2d(4), M.ReLU(), ) net = ConvBNReLU() net.eval() @jit.trace(symbolic=True) def fun(data): return net(data) data = np.random.random([1, 3, 224, 224]).astype(np.float32) fun.trace(data) with mkstemp() as out: fun.dump(out, optimize_for_inference=True) cg, _, outputs = mgb.load_comp_graph_from_file(out) (out, ) = outputs inputs = mgb.cgtools.get_inputs(out) assert len(inputs) == 2 and ( mgb.cgtools.get_type(inputs[0]) == "MultipleDeviceTensorHolder" and mgb.cgtools.get_type(inputs[1]) == "ConvolutionForward")
def load_and_compile(fpath): cg, _, outputs = mgb.load_comp_graph_from_file(fpath) inputs = mgb.cgtools.get_dep_vars(outputs, "Host2DeviceCopy") inputs = sorted(inputs, key=lambda i: i.name) outputs = list(map(mgb.copy_output, outputs)) if len(outputs) == 1: (outputs, ) = outputs return cg.compile(inputs, outputs)
def load_comp_graph_from_file(path): if mge_version <= "0.6.0": cg, _, outputs = mgb.load_comp_graph_from_file(path) else: ret = G.load_graph(path) cg = ret.graph outputs = ret.output_vars_list return cg, outputs
def test_dump_volatile(): p = tensor(7) @jit.trace(symbolic=True) def f(x): return x * p f.trace(0) with mkstemp() as out: f.dump(out) cg, _, outputs = mgb.load_comp_graph_from_file(out) (out, ) = outputs assert mgb.cgtools.get_type( mgb.cgtools.get_inputs(out)[1]) == "SharedDeviceTensor"
def validate_megengine_model(platform, device_type, model_file, input_file, mace_out_file, input_names, input_shapes, input_data_formats, output_names, output_shapes, output_data_formats, validation_threshold, input_data_types, log_file): import megengine._internal as mgb if not os.path.isfile(model_file): common.MaceLogger.error( VALIDATION_MODULE, "Input graph file '" + model_file + "' does not exist!", ) feed_inputs = [] for i in range(len(input_names)): input_value = load_data( common.formatted_file_name(input_file, input_names[i]), input_data_types[i]) input_value = input_value.reshape(input_shapes[i]) if (input_data_formats[i] == common.DataFormat.NHWC and len(input_shapes[i]) == 4): input_value = input_value.transpose((0, 3, 1, 2)) feed_inputs.append(input_value) cg, _, outputs = mgb.load_comp_graph_from_file(model_file) inputs = mgb.cgtools.get_dep_vars(outputs, "Host2DeviceCopy") inputs = sorted(inputs, key=lambda i: i.name) outputs = list(map(mgb.copy_output, outputs)) if len(outputs) == 1: (outputs,) = outputs func = cg.compile(inputs, outputs) mge_output_value = func(*feed_inputs) for i in range(len(output_names)): output_file_name = \ common.formatted_file_name(mace_out_file, output_names[i]) mace_out_value = load_data(output_file_name) mace_out_value, real_output_shape, real_output_data_format = \ get_real_out_value_shape_df(platform, mace_out_value, output_shapes[i], output_data_formats[i]) compare_output(platform, device_type, output_names[i], mace_out_value, mge_output_value, validation_threshold, log_file, real_output_shape, real_output_data_format)
def test_network_visitor(): @jit.trace(symbolic=True) def f(x): # this line will produce shape_of, subtensor and concat op # after pruning, they will be deleted target_shape = (x.shape[0], -1) return x.reshape(*target_shape) f.trace(tensor(np.random.random([2, 3, 4, 5]).astype(np.float32))) with mkstemp() as out: f.dump(out) *_, outputs = mgb.load_comp_graph_from_file(out) all_oprs = mgb.cgtools.get_oprs_seq(outputs) pruned_oprs = mgb.cgtools.get_oprs_seq(outputs, prune_reshape=True) assert len(all_oprs) == len(pruned_oprs) + 3
def test_graph_traversal(): net = M.Conv2d(3, 4, 3, 1, 1, groups=1, bias=False) net.eval() @jit.trace(symbolic=True) def fun(data): return net(data) data = np.random.random([1, 3, 224, 224]).astype(np.float32) fun.trace(data) with mkstemp() as out: fun.dump(out) *_, outputs = mgb.load_comp_graph_from_file(out) _, map_vars, var2oprs, *_ = mgb.cgtools.graph_traversal(outputs) input_var = map_vars[1] _, var_idx = var2oprs[input_var.id][0] assert var_idx == 0
def __init__(self, option, src_model_file): self._op_converters = { MGEOpType.AxisAddRemove.name: self.convert_axisaddrm, MGEOpType.BatchNormForward.name: self.convert_batchnorm, MGEOpType.Concat.name: self.convert_concat, MGEOpType.ConvolutionForward.name: self.convert_conv2d, MGEOpType.ConvolutionBackwardData.name: self.convert_deconv2d, MGEOpType.Dimshuffle.name: self.convert_dimshuffle, MGEOpType.Elemwise.name: self.convert_elemwise, MGEOpType.GetVarShape.name: self.convert_shape, MGEOpType.Host2DeviceCopy.name: self.convert_nop, MGEOpType.Identity.name: self.convert_identity, MGEOpType.MarkNoBroadcastElemwise.name: self.convert_identity, MGEOpType.MatrixMul.name: self.convert_matmul, MGEOpType.PoolingForward.name: self.convert_pooling, MGEOpType.Reduce.name: self.convert_reduce, MGEOpType.Reshape.name: self.convert_reshape, MGEOpType.SharedDeviceTensor.name: self.convert_nop, MGEOpType.Subtensor.name: self.convert_subtensor, } self._option = option self._converter_info = dict() self._mace_net_def = mace_pb2.NetDef() ConverterUtil.set_filter_format(self._mace_net_def, DataFormat.OIHW) ConverterUtil.add_data_format_arg(self._mace_net_def, DataFormat.NCHW) cg, _, outputs = mgb.load_comp_graph_from_file(src_model_file) map_oprs, _, var2oprs, *_ = mgb.cgtools.graph_traversal(outputs) # prune second input of reshape # because it introduces several ops, may increase the overhead operators = mgb.cgtools.get_oprs_seq(outputs, prune_reshape=True) self._mge_cg = cg self._mge_operators = operators self._mge_map_oprs = map_oprs self._mge_var2oprs = var2oprs self._skip_tensors = set() self._bn_statistis_tensors = {}
def make_feeds(args): cg, _, outputs = mgb.load_comp_graph_from_file(args.input) inputs = mgb.cgtools.get_dep_vars(outputs, 'Host2DeviceCopy') inputs = {i.name: i for i in inputs} outputs_spec = list(map(mgb.copy_output, outputs)) if not args.no_assert: # FIXME! ExternCOprPlaceholder not done func = cg.compile(None, outputs_spec) def expect_name(var): return '{}:expect'.format(var.name) testcases = [] np.set_printoptions(precision=2, threshold=4, suppress=True) data_list = [] for item in args.data: if item.startswith('@'): with open(item[1:], 'r') as f: data_list.extend([line.rstrip() for line in f if line.rstrip() != '']) else: data_list.append(item) for inp_spec in data_list: cur_testcase = gen_one_testcase(args, inputs, inp_spec) assert len(cur_testcase) == len(inputs), ( 'required inputs: {}; given data: {}'.format( inputs.keys(), cur_testcase.keys() ) ) if not args.no_assert: outputs_get = func(**cur_testcase) for var, val in zip(outputs, outputs_get): cur_testcase[expect_name(var)] = val logger.info( 'generate test groundtruth: var={} shape={} range=({}, {})' ' mean={} var={}'.format( var, val.shape, val.min(), val.max(), np.mean(val), np.var(val) ) ) testcases.append(cur_testcase) logger.info( 'add testcase: \n {}'.format( '\n '.join( '{}: shape={} dtype={} range=({:.2f},{:.2f}) ' 'mean={:.2f} sd={:.2f}'.format( k, v.shape, v.dtype, v.min(), v.max(), np.mean(v), np.std(v) ) for k, v in sorted(cur_testcase.items()) ) ) ) if not args.no_assert: def expect_shp(var): ret = var.imm_shape if ret: return ret return testcases[0][expect_name(var)].shape verbose = not args.silent outputs_new = [] for i in outputs: get = mgb.make_arg( i.comp_node, cg, dtype=i.dtype, name=expect_name(i) ) outputs_new.append( mgb.opr.assert_equal(get, i, verbose=verbose, maxerr=args.maxerr) ) inputs[expect_name(i)] = get outputs = outputs_new return {'outputs': outputs, 'testcases': testcases}
def load_comp_graph_from_file(path): if mge_version <= "0.6.0": cg, _, outputs = mgb.load_comp_graph_from_file(path) else: cg, _, outputs = G.load_graph(path) return cg, outputs