def test_move_scalar_add_past_matmul(): top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, [1, 2]) add_param = oh.make_tensor_value_info("add_param", TensorProto.FLOAT, [1, 1]) matmul_param = oh.make_tensor_value_info("matmul_param", TensorProto.FLOAT, [2, 2]) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, [1, 2]) modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=[add_param, matmul_param], nodes=[ oh.make_node("Add", ["top_in", "add_param"], ["middle"]), oh.make_node("MatMul", ["middle", "matmul_param"], ["top_out"]), ], ) ) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) model.set_initializer("add_param", np.asarray([[3]], dtype=np.float32)) model.set_initializer( "matmul_param", np.asarray([[2, 4], [-1, 1]], dtype=np.float32) ) new_model = model.transform(MoveScalarAddPastMatMul()) inp_dict = {"top_in": np.asarray([[-1.0, 1.0]], dtype=np.float32)} assert ox.compare_execution(model, new_model, inp_dict) assert new_model.graph.node[0].op_type == "MatMul" assert new_model.graph.node[1].op_type == "Add" assert new_model.graph.node[0].output[0] == new_model.graph.node[1].input[0]
def make_modelwrapper(C, pe, idt, odt, pdt, func, vecs): NumChannels = C.shape[0] inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, vecs + [NumChannels]) outp = helper.make_tensor_value_info( "outp", TensorProto.FLOAT, vecs + [NumChannels] ) node_inp_list = ["inp", "const"] node = helper.make_node( "ChannelwiseOp_Batch", node_inp_list, ["outp"], domain="finn.custom_op.fpgadataflow", backend="fpgadataflow", NumChannels=NumChannels, Func=func, PE=pe, inputDataType=idt.name, outputDataType=odt.name, paramDataType=pdt.name, numInputVectors=vecs, ) graph = helper.make_graph(nodes=[node], name="graph", inputs=[inp], outputs=[outp]) model = helper.make_model(graph, producer_name="model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("const", idt) model.set_initializer("const", C) return model
def test_xnorpopcountmatmul(): M = 1 K = 3 N = 3 x = helper.make_tensor_value_info("x", TensorProto.FLOAT, [M, K]) W = helper.make_tensor_value_info("W", TensorProto.FLOAT, [K, N]) out = helper.make_tensor_value_info("out", TensorProto.FLOAT, ["x", "y"]) node_def = helper.make_node("XnorPopcountMatMul", ["x", "W"], ["out"], domain="finn.custom_op.general") modelproto = helper.make_model( helper.make_graph([node_def], "test_model", [x], [out], value_info=[W])) model = ModelWrapper(modelproto) model.set_tensor_datatype("x", DataType.BINARY) model.set_tensor_datatype("W", DataType.BINARY) W_data = np.asarray([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32) model.set_initializer("W", W_data) # test shape inference model = model.transform(InferShapes()) assert model.get_tensor_shape("out") == [M, N] # test datatype inference assert model.get_tensor_datatype("out") is DataType.FLOAT32 model = model.transform(InferDataTypes()) assert model.get_tensor_datatype("out") is DataType.UINT32 # test execution x_data = np.asarray([[1, 0, 0]], dtype=np.float32) inp_dict = {"x": x_data} out_dict = oxe.execute_onnx(model, inp_dict) Wb = 2 * W_data - 1 xb = 2 * x_data - 1 rb = np.matmul(xb, Wb) assert (2 * out_dict["out"] - K == rb).all()
def _make_single_vvau_modelwrapper( W, pe, k_h, k_w, channels, dim_h, dim_w, wdt, idt, odt, T=None, tdt=None ): in_shape = [1, dim_h, dim_w, k_h * k_w * channels] # [N, H, W, K*K*CH] out_shape = [ 1, dim_h, dim_w, channels, ] # [N, H, W, OFM_CH] (OFM_CH=IFM_CH because depthwise convolution) inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, in_shape) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, out_shape) if T is not None: no_act = 0 node_inp_list = ["inp", "weights", "thresh"] actval = odt.min() else: no_act = 1 node_inp_list = ["inp", "weights"] actval = 0 VVAU_node = helper.make_node( "Vector_Vector_Activate_Batch", node_inp_list, ["outp"], domain="finn.custom_op.fpgadataflow", backend="fpgadataflow", PE=pe, Dim=[dim_h, dim_w], Channels=channels, Kernel=[k_h, k_w], resType="lut", ActVal=actval, inputDataType=idt.name, weightDataType=wdt.name, outputDataType=odt.name, noActivation=no_act, ) graph = helper.make_graph( nodes=[VVAU_node], name="vvau_graph", inputs=[inp], outputs=[outp] ) model = helper.make_model(graph, producer_name="vvau-model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("weights", wdt) model.set_initializer("weights", W) model.set_tensor_shape("weights", (channels, 1, k_h, k_w)) if T is not None: model.set_tensor_datatype("thresh", tdt) model.set_initializer("thresh", T) return model
def test_move_chw_add_past_conv(idim, k, s, ich, och): odim = compute_conv_output_dim(idim, k, s) ishape = [1, ich, idim, idim] oshape = [1, och, odim, odim] add_param_shape = [1, ich, 1, 1] conv_param_shape = [och, ich, k, k] inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, ishape) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, oshape) a0 = helper.make_tensor_value_info("a0", TensorProto.FLOAT, add_param_shape) a1 = helper.make_tensor_value_info("a1", TensorProto.FLOAT, conv_param_shape) conv_config = {} conv_config["dilations"] = [1, 1] conv_config["group"] = 1 conv_config["kernel_shape"] = [k, k] conv_config["pads"] = [0, 0, 0, 0] conv_config["strides"] = [s, s] add_node = helper.make_node("Add", ["inp", "a0"], ["add_out"]) conv_node = helper.make_node("Conv", ["add_out", "a1"], ["outp"], **conv_config) model = helper.make_model( helper.make_graph( nodes=[add_node, conv_node], name="move-add-graph", inputs=[inp], outputs=[outp], value_info=[a0, a1], )) model = ModelWrapper(model) # initialize model a0_values = np.random.uniform( low=0, high=1, size=tuple(add_param_shape)).astype(np.float32) model.set_initializer("a0", a0_values) a1_values = np.random.uniform( low=0, high=1, size=tuple(conv_param_shape)).astype(np.float32) model.set_initializer("a1", a1_values) model = model.transform(InferShapes()) # execution before transformation inp_values = np.random.uniform(low=0, high=1, size=tuple(ishape)).astype(np.float32) idict = {model.graph.input[0].name: inp_values} odict = oxe.execute_onnx(model, idict) y_before = odict[model.graph.output[0].name] model = model.transform(MoveAddPastConv()) odict = oxe.execute_onnx(model, idict) y_after = odict[model.graph.output[0].name] assert np.isclose(y_before, y_after).all() assert model.graph.node[0].op_type == "Conv" assert model.graph.node[1].op_type == "Add"
def test_modelwrapper(): lfc = get_test_model_trained("LFC", 1, 1) bo.export_finn_onnx(lfc, (1, 1, 28, 28), export_onnx_path) model = ModelWrapper(export_onnx_path) assert model.check_all_tensor_shapes_specified() is False inp_name = model.graph.input[0].name inp_shape = model.get_tensor_shape(inp_name) assert inp_shape == [1, 1, 28, 28] # find first matmul node l0_mat_tensor_name = "" l0_inp_tensor_name = "" for node in model.graph.node: if node.op_type == "MatMul": l0_inp_tensor_name = node.input[0] l0_mat_tensor_name = node.input[1] break assert l0_mat_tensor_name != "" l0_weights = model.get_initializer(l0_mat_tensor_name) assert l0_weights.shape == (784, 1024) l0_weights_hist = Counter(l0_weights.flatten()) assert (l0_weights_hist[1.0] + l0_weights_hist[-1.0]) == 784 * 1024 l0_weights_rand = np.random.randn(784, 1024) model.set_initializer(l0_mat_tensor_name, l0_weights_rand) assert (model.get_initializer(l0_mat_tensor_name) == l0_weights_rand).all() assert l0_inp_tensor_name != "" inp_cons = model.find_consumer(l0_inp_tensor_name) assert inp_cons.op_type == "MatMul" out_prod = model.find_producer(l0_inp_tensor_name) assert out_prod.op_type == "Sign" os.remove(export_onnx_path)
def make_lookup_model(embeddings, ishape, idt, edt): num_embeddings, embedding_dim = embeddings.shape class LookupModel(nn.Module): def __init__(self, num_embeddings, embedding_dim): super().__init__() self.lookup = nn.Embedding( num_embeddings=num_embeddings, embedding_dim=embedding_dim ) def forward(self, x): x = self.lookup(x) return x torch_model = LookupModel(num_embeddings, embedding_dim) input_t = torch.zeros(ishape, dtype=torch.int64) ret = FINNManager.export(torch_model, input_t=input_t, opset_version=11) model = ModelWrapper(ret) iname = model.graph.input[0].name ename = model.graph.node[0].input[0] model.set_tensor_datatype(iname, idt) eshape = model.get_tensor_shape(ename) assert tuple(eshape) == embeddings.shape model.set_initializer(ename, embeddings) model.set_tensor_datatype(ename, edt) model = model.transform(InferShapes()) model = model.transform(InferDataTypes()) return model
def test_round_thresholds(): v = helper.make_tensor_value_info("v", TensorProto.FLOAT, [1, 4]) thresholds = helper.make_tensor_value_info("thresholds", TensorProto.FLOAT, [4, 1]) out = helper.make_tensor_value_info("out", TensorProto.FLOAT, [1, 4]) node_def = helper.make_node("MultiThreshold", ["v", "thresholds"], ["out"], domain="finn") graph_def = helper.make_graph([node_def], "test_model", [v, thresholds], [out]) model_def = helper.make_model(graph_def) model = ModelWrapper(model_def) threshold_val = np.asarray([[-1.1], [0.7], [2.3], [5.1]], dtype=np.float32) model.set_initializer("thresholds", threshold_val) model.set_tensor_datatype("v", DataType.INT8) inp_dict_f = {"v": np.floor(threshold_val).T} inp_dict_n = {"v": np.round(threshold_val).T} inp_dict_c = {"v": np.ceil(threshold_val).T} orig_f = oxe.execute_onnx(model, inp_dict_f)["out"] orig_n = oxe.execute_onnx(model, inp_dict_n)["out"] orig_c = oxe.execute_onnx(model, inp_dict_c)["out"] assert model.get_tensor_datatype("thresholds") == DataType.FLOAT32 new_model = model.transform(RoundAndClipThresholds()) # rounded up thresholds should have same dtype as input assert new_model.get_tensor_datatype("thresholds") == DataType.INT8 new_f = oxe.execute_onnx(new_model, inp_dict_f)["out"] new_n = oxe.execute_onnx(new_model, inp_dict_n)["out"] new_c = oxe.execute_onnx(new_model, inp_dict_c)["out"] assert np.isclose(orig_f, new_f, atol=1e-3).all() assert np.isclose(orig_n, new_n, atol=1e-3).all() assert np.isclose(orig_c, new_c, atol=1e-3).all()
def test_move_add_past_mul_multi(): top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, [2]) add_param_0 = oh.make_tensor_value_info("add_param_0", TensorProto.FLOAT, [2]) mul_param_0 = oh.make_tensor_value_info("mul_param_0", TensorProto.FLOAT, [2]) add_param_1 = oh.make_tensor_value_info("add_param_1", TensorProto.FLOAT, [2]) mul_param_1 = oh.make_tensor_value_info("mul_param_1", TensorProto.FLOAT, [2]) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, [2]) modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=[add_param_0, mul_param_0, add_param_1, mul_param_1], nodes=[ oh.make_node("Add", ["top_in", "add_param_0"], ["middle_0"]), oh.make_node("Mul", ["middle_0", "mul_param_0"], ["middle_1"]), oh.make_node("Add", ["middle_1", "add_param_1"], ["middle_2"]), oh.make_node("Mul", ["middle_2", "mul_param_1"], ["top_out"]), ], ) ) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) model.set_initializer("add_param_0", np.asarray([1, 3], dtype=np.float32)) model.set_initializer("mul_param_0", np.asarray([2, 4], dtype=np.float32)) model.set_initializer("add_param_1", np.asarray([-1, 3], dtype=np.float32)) model.set_initializer("mul_param_1", np.asarray([2, -4], dtype=np.float32)) new_model = model.transform(MoveAddPastMul()) inp_dict = {"top_in": np.asarray([-1.0, 1.0], dtype=np.float32)} assert ox.compare_execution(model, new_model, inp_dict)
def test_conv_lowering_conv_1x1(): np.random.seed(0) in_feature_dim_h = 7 in_feature_dim_w = 7 in_chn = 3 kernel_size = 1 out_feature_dim_h = in_feature_dim_h out_feature_dim_w = in_feature_dim_w input_shape = [1, in_chn, in_feature_dim_h, in_feature_dim_w] output_shape = [1, in_chn, out_feature_dim_h, out_feature_dim_w] conv_param_shape = [in_chn, in_chn, kernel_size, kernel_size] conv_config = {} conv_config["dilations"] = [1, 1] conv_config["group"] = 1 conv_config["kernel_shape"] = [kernel_size, kernel_size] conv_config["pads"] = [0, 0, 0, 0] conv_config["strides"] = [1, 1] top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, input_shape) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, output_shape) value_info = [ oh.make_tensor_value_info("p1", TensorProto.FLOAT, conv_param_shape) ] modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=value_info, nodes=[ oh.make_node("Conv", ["top_in", "p1"], ["top_out"], **conv_config) ], )) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) model.set_initializer("p1", np.random.rand(*conv_param_shape).astype(np.float32)) new_model = model.transform(LowerConvsToMatMul()) inp_dict = {"top_in": np.random.rand(*input_shape).astype(np.float32)} assert oxe.compare_execution(model, new_model, inp_dict) assert new_model.graph.node[0].op_type == "Transpose" assert new_model.graph.node[1].op_type == "MatMul" assert new_model.graph.node[2].op_type == "Transpose" assert len(new_model.graph.node) == 3
def test_infer_shapes(): # load the onnx model raw_m = get_data("finn.data", "onnx/mnist-conv/model.onnx") model = ModelWrapper(raw_m) graph = model.graph # multi-thresholding node to be inserted between the first Relu and MaxPool node # get Relu node to use data Relu_node = graph.node[3] assert Relu_node.op_type == "Relu", "The wrong model was chosen for the check" # create thresholds tensor as constant mt_thresh0 = helper.make_tensor_value_info("mt_thresh0", TensorProto.FLOAT, [8, 7]) # random numbers for the thresholds # thresholds for one channel have to be sorted to guarantee the correct behavior mt_thresh0_values = np.empty([8, 7], dtype=np.float32) for i in range(len(mt_thresh0_values)): mt_thresh0_values[i] = np.sort(np.random.random_sample(7) * 10) model.set_initializer(mt_thresh0.name, mt_thresh0_values) # add multi-thresholding node and change Relu node mt_node = helper.make_node( "MultiThreshold", ["mt_v0", "mt_thresh0"], [Relu_node.output[0]], domain="finn.custom_op.general", ) Relu_node.output[0] = "mt_v0" # explicitly remove any present shape from ReLU and MultiThreshold outputs util.remove_by_name(model.graph.value_info, Relu_node.output[0]) util.remove_by_name(model.graph.value_info, mt_node.output[0]) graph.node.insert(4, mt_node) # first check routine # check if at least one shape is not specified assert not ( model.check_all_tensor_shapes_specified() ), "All tensors are already specified before the shape inference execution" # perform shape inference on mixed model model = model.transform(InferShapes()) # second check routine # now all shapes should be specified and mt_node output shape is (1,8,28,28) assert (model.check_all_tensor_shapes_specified() ), "There are still tensors that are not specified" assert (model.get_tensor_shape(mt_node.output[0])) == ([ 1, 8, 28, 28 ]), "output of multi-thresholding node has wrong shape"
def create_one_fc_model(mem_mode="const"): # create a model with a StreamingFCLayer instance with no activation # the wider range of the full accumulator makes debugging a bit easier wdt = DataType.INT2 idt = DataType.INT32 odt = DataType.INT32 m = 4 no_act = 1 binary_xnor_mode = 0 actval = 0 simd = 4 pe = 4 inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, [1, m]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, m]) fc0 = helper.make_node( "StreamingFCLayer_Batch", ["inp", "w0"], ["outp"], domain="finn", backend="fpgadataflow", resType="ap_resource_lut()", MW=m, MH=m, SIMD=simd, PE=pe, inputDataType=idt.name, weightDataType=wdt.name, outputDataType=odt.name, ActVal=actval, binaryXnorMode=binary_xnor_mode, noActivation=no_act, mem_mode=mem_mode, ) graph = helper.make_graph(nodes=[fc0], name="fclayer_graph", inputs=[inp], outputs=[outp]) model = helper.make_model(graph, producer_name="fclayer-model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("w0", wdt) # generate weights w0 = np.eye(m, dtype=np.float32) model.set_initializer("w0", w0) model = model.transform(CreateDataflowPartition()) return model
def test_depthwise_conv_lowering(idt, k, ifm_dim, ifm_ch, stride, padding): wdt = idt odt = DataType.INT32 ofm_ch = ifm_ch ofm_dim = compute_conv_output_dim(ifm_dim, k, stride, pad=padding[0]) # set up onnx model inp = oh.make_tensor_value_info("inp", TensorProto.FLOAT, [1, ifm_ch, ifm_dim, ifm_dim]) outp = oh.make_tensor_value_info("outp", TensorProto.FLOAT, [1, ofm_ch, ofm_dim, ofm_dim]) W = oh.make_tensor_value_info("W", TensorProto.FLOAT, [ofm_ch, 1, k, k]) dw_cnv = oh.make_node( "Conv", inputs=["inp", "W"], outputs=["outp"], kernel_shape=[k, k], pads=padding, strides=[stride, stride], group=ifm_ch, ) graph = oh.make_graph( nodes=[dw_cnv], name="dw_cnv_graph", inputs=[inp], outputs=[outp], value_info=[W], ) model = oh.make_model(graph, producer_name="dws_cnv-model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("W", wdt) w_tensor = gen_finn_dt_tensor(wdt, [ofm_ch, 1, k, k]) model.set_initializer("W", w_tensor) model = model.transform(InferShapes()) input_tensor = gen_finn_dt_tensor(idt, [1, ifm_ch, ifm_dim, ifm_dim]) input_dict = {"inp": input_tensor} output_dict = oxe.execute_onnx(model, input_dict) expected = output_dict["outp"] model = model.transform(LowerConvsToMatMul()) output_dict = oxe.execute_onnx(model, input_dict) produced = output_dict["outp"] assert (produced == expected).all() # check if created nodes have attributes that indicate depthwise conv assert model.get_tensor_sparsity("W") is not None im2col_node = getCustomOp(model.graph.node[1]) assert im2col_node.get_nodeattr("depthwise") == 1
def test_code_gen_trafo(): idt = wdt = odt = DataType.BIPOLAR mw = 8 mh = 8 pe = 4 simd = 4 inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, [1, mw]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, mh]) node_inp_list = ["inp", "weights", "thresh"] FCLayer_node = helper.make_node( "StreamingFCLayer_Batch", node_inp_list, ["outp"], domain="finn", backend="fpgadataflow", code_gen_dir="", executable_path="", resType="ap_resource_lut()", MW=mw, MH=mh, SIMD=simd, PE=pe, inputDataType=idt.name, weightDataType=wdt.name, outputDataType=odt.name, noActivation=1, ) graph = helper.make_graph(nodes=[FCLayer_node], name="fclayer_graph", inputs=[inp], outputs=[outp]) model = helper.make_model(graph, producer_name="fclayer-model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("weights", wdt) W = util.gen_finn_dt_tensor(wdt, (mw, mh)) model.set_initializer("weights", W) model = model.transform(CodeGen_npysim()) for node in model.graph.node: code_gen_attribute = util.get_by_name(node.attribute, "code_gen_dir_npysim") tmp_dir = code_gen_attribute.s.decode("UTF-8") assert os.path.isdir( tmp_dir), """Code generation directory of node with op type {} does not exist!""".format(node.op_type) assert (len(os.listdir(tmp_dir)) != 0), """Code generation directory of node with op type {} is empty!""".format(node.op_type)
def test_sort_nonlinear_graph(): ch = 2 ifmdim = 16 input_shape = (1, ch, ifmdim, ifmdim) top_in = helper.make_tensor_value_info("top_in", TensorProto.FLOAT, input_shape) top_out = helper.make_tensor_value_info("top_out", TensorProto.FLOAT, input_shape) num_of_params = 8 value_info = [] for i in range(num_of_params): value_info += [ helper.make_tensor_value_info("p" + str(i), TensorProto.FLOAT, input_shape) ] modelproto = helper.make_model( helper.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=value_info, nodes=[ # Not sorted nodes helper.make_node("Mul", ["fork1", "p2"], ["t3"]), helper.make_node("Add", ["t4", "p3"], ["t5"]), helper.make_node("Add", ["t2", "t3"], ["t4"]), helper.make_node("Add", ["t6", "t7"], ["t8"]), helper.make_node("Add", ["fork3", "fork3"], ["top_out"]), helper.make_node("Mul", ["t5", "p4"], ["fork2"]), helper.make_node("Add", ["top_in", "p0"], ["fork1"]), helper.make_node("Mul", ["fork1", "p1"], ["t2"]), helper.make_node("Add", ["fork2", "p5"], ["t6"]), helper.make_node("Add", ["fork2", "p6"], ["t7"]), helper.make_node("Mul", ["t8", "p7"], ["fork3"]), ], )) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) np.random.seed(0) for i in range(num_of_params): model.set_initializer("p" + str(i), np.random.rand(*input_shape).astype(np.float32)) new_model = model.transform(SortGraph()) # Test ret = new_model.analysis(ta.nodes_topologically_sorted) assert ret[ "nodes_topologically_sorted"], "Nodes are not topologically sorted."
def test_compilation_trafo(): idt = wdt = odt = DataType.BIPOLAR mw = 8 mh = 8 pe = 4 simd = 4 inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, [1, mw]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, mh]) node_inp_list = ["inp", "weights", "thresh"] FCLayer_node = helper.make_node( "StreamingFCLayer_Batch", node_inp_list, ["outp"], domain="finn.custom_op.fpgadataflow", backend="fpgadataflow", code_gen_dir="", executable_path="", MW=mw, MH=mh, SIMD=simd, PE=pe, inputDataType=idt.name, weightDataType=wdt.name, outputDataType=odt.name, noActivation=1, ) graph = helper.make_graph(nodes=[FCLayer_node], name="fclayer_graph", inputs=[inp], outputs=[outp]) model = helper.make_model(graph, producer_name="fclayer-model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("weights", wdt) W = util.gen_finn_dt_tensor(wdt, (mw, mh)) model.set_initializer("weights", W) model = model.transform(PrepareCppSim()) model = model.transform(CompileCppSim()) for node in model.graph.node: compilation_attribute = util.get_by_name(node.attribute, "executable_path") executable = compilation_attribute.s.decode("UTF-8") print(executable) assert os.path.isfile(executable), """Executable of node with op type {} does not exist!""".format(node.op_type)
def test_collapse_repeated_op(): top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, [2]) add_param_0 = oh.make_tensor_value_info("add_param_0", TensorProto.FLOAT, [2]) mul_param_0 = oh.make_tensor_value_info("mul_param_0", TensorProto.FLOAT, [2]) add_param_1 = oh.make_tensor_value_info("add_param_1", TensorProto.FLOAT, [2]) mul_param_1 = oh.make_tensor_value_info("mul_param_1", TensorProto.FLOAT, [2]) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, [2]) modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=[add_param_0, mul_param_0, add_param_1, mul_param_1], nodes=[ oh.make_node("Add", ["top_in", "add_param_0"], ["middle_0"]), oh.make_node("Add", ["middle_0", "add_param_1"], ["middle_1"]), oh.make_node("Mul", ["middle_1", "mul_param_0"], ["middle_2"]), oh.make_node("Mul", ["middle_2", "mul_param_1"], ["top_out"]), ], ) ) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) model.set_initializer("add_param_0", np.asarray([1, 3], dtype=np.float32)) model.set_initializer("add_param_1", np.asarray([-1, 3], dtype=np.float32)) model.set_initializer("mul_param_0", np.asarray([2, 4], dtype=np.float32)) model.set_initializer("mul_param_1", np.asarray([2, -4], dtype=np.float32)) new_model = model.transform(CollapseRepeatedAdd()) new_model = new_model.transform(CollapseRepeatedMul()) inp_dict = {"top_in": np.asarray([-1.0, 1.0], dtype=np.float32)} assert ox.compare_execution(model, new_model, inp_dict) assert len(new_model.graph.node) == 2 assert new_model.graph.node[0].op_type == "Add" assert new_model.graph.node[1].op_type == "Mul"
def make_model(shape): inp1 = helper.make_tensor_value_info("inp1", TensorProto.FLOAT, shape) inp2 = helper.make_tensor_value_info("inp2", TensorProto.FLOAT, shape) inp1_add = helper.make_tensor_value_info("inp1_add", TensorProto.FLOAT, shape) inp1_add_ct = helper.make_tensor_value_info("inp1_add_ct", TensorProto.FLOAT, [1]) inp2_add = helper.make_tensor_value_info("inp2_add", TensorProto.FLOAT, shape) inp2_add_ct = helper.make_tensor_value_info("inp2_add_ct", TensorProto.FLOAT, [1]) inp1_mul = helper.make_tensor_value_info("inp1_mul", TensorProto.FLOAT, shape) inp1_mul_ct = helper.make_tensor_value_info("inp1_mul_ct", TensorProto.FLOAT, [1]) inp2_mul = helper.make_tensor_value_info("inp2_mul", TensorProto.FLOAT, shape) inp2_mul_ct = helper.make_tensor_value_info("inp2_mul_ct", TensorProto.FLOAT, [1]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, shape) add1_node = helper.make_node("Add", [inp1.name, inp1_add_ct.name], [inp1_add.name]) add2_node = helper.make_node("Add", [inp2.name, inp2_add_ct.name], [inp2_add.name]) mul1_node = helper.make_node("Mul", [inp1_add.name, inp1_mul_ct.name], [inp1_mul.name]) mul2_node = helper.make_node("Mul", [inp2_add.name, inp2_mul_ct.name], [inp2_mul.name]) eltwise_add_node = helper.make_node("Add", [inp1_mul.name, inp2_mul.name], [outp.name]) graph = helper.make_graph( nodes=[add1_node, add2_node, mul1_node, mul2_node, eltwise_add_node], name="graph", inputs=[inp1, inp2], outputs=[outp], ) model = helper.make_model(graph, producer_name="add-model") model = ModelWrapper(model) # set initializers for scalar add/mul nodes model.set_initializer(add1_node.input[1], np.array([7.0])) model.set_initializer(add2_node.input[1], np.array([8.0])) model.set_initializer(mul1_node.input[1], np.array([3.0])) model.set_initializer(mul2_node.input[1], np.array([3.0])) return model
def test_move_add_past_mul_only_if_linear(): top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, [2]) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, [2]) value_info = [ oh.make_tensor_value_info("add1_param", TensorProto.FLOAT, [1]) ] value_info += [ oh.make_tensor_value_info("mul1_param", TensorProto.FLOAT, [1]) ] value_info += [ oh.make_tensor_value_info("mul2_param", TensorProto.FLOAT, [1]) ] value_info += [ oh.make_tensor_value_info("mul3_param", TensorProto.FLOAT, [1]) ] modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=value_info, nodes=[ oh.make_node("Add", ["top_in", "add1_param"], ["t1"]), oh.make_node("Mul", ["t1", "mul1_param"], ["fork"]), oh.make_node("Mul", ["fork", "mul2_param"], ["t3"]), oh.make_node("Add", ["t3", "fork"], ["t4"]), oh.make_node("Mul", ["t4", "mul3_param"], ["top_out"]), ], )) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) np.random.seed(0) model.set_initializer("add1_param", np.random.rand(2).astype(np.float32)) model.set_initializer("mul1_param", np.random.rand(2).astype(np.float32)) model.set_initializer("mul2_param", np.random.rand(2).astype(np.float32)) model.set_initializer("mul3_param", np.random.rand(2).astype(np.float32)) new_model = model.transform(MoveAddPastMul()) inp_dict = {"top_in": np.random.rand(2).astype(np.float32)} assert ox.compare_execution(model, new_model, inp_dict) assert new_model.graph.node[0].op_type == "Mul" assert new_model.graph.node[1].op_type == "Add" assert new_model.graph.node[2].op_type == "Mul" assert new_model.graph.node[3].op_type == "Add" assert new_model.graph.node[4].op_type == "Mul"
def test_absorb_opposite_transposes(): np.random.seed(0) input_shape = [1, 3, 4, 2] top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, input_shape) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, input_shape) value_info = [ oh.make_tensor_value_info("add_param_0", TensorProto.FLOAT, [1]) ] value_info += [ oh.make_tensor_value_info("add_param_1", TensorProto.FLOAT, [1]) ] value_info += [ oh.make_tensor_value_info("mul_param_0", TensorProto.FLOAT, [1]) ] modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=value_info, nodes=[ oh.make_node("Add", ["top_in", "add_param_0"], ["t0"]), oh.make_node("Transpose", ["t0"], ["t1"], perm=[0, 2, 3, 1]), oh.make_node("Transpose", ["t1"], ["t2"], perm=[0, 3, 1, 2]), oh.make_node("Add", ["t2", "add_param_1"], ["t3"]), oh.make_node("Transpose", ["t3"], ["t4"], perm=[0, 2, 3, 1]), oh.make_node("Transpose", ["t4"], ["t5"], perm=[0, 3, 1, 2]), oh.make_node("Add", ["t5", "t2"], ["t6"]), oh.make_node("Mul", ["t6", "mul_param_0"], ["top_out"]), ], )) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) model.set_initializer("add_param_0", np.asarray([1], dtype=np.float32)) model.set_initializer("add_param_1", np.asarray([3], dtype=np.float32)) model.set_initializer("mul_param_0", np.asarray([2], dtype=np.float32)) new_model = model.transform(AbsorbConsecutiveTransposes()) new_model = new_model.transform(InferShapes()) inp_dict = {"top_in": np.random.rand(*input_shape).astype(np.float32)} assert ox.compare_execution(model, model, inp_dict) assert len(new_model.graph.node) == 4 for n in new_model.graph.node: assert new_model.graph.node[0].op_type != "Transpose"
def make_randomly_sorted_linear_model(num_of_nodes, seed=None): if seed is not None: np.random.seed(seed) ch = 2 ifmdim = 16 input_shape = (1, ch, ifmdim, ifmdim) top_in = helper.make_tensor_value_info("t0", TensorProto.FLOAT, input_shape) top_out = helper.make_tensor_value_info( "t" + str(num_of_nodes), TensorProto.FLOAT, input_shape ) value_info = [] nodes = [] for i in range(num_of_nodes): nodes += [ helper.make_node("Add", ["t" + str(i), "p" + str(i)], ["t" + str(i + 1)]) ] value_info += [ helper.make_tensor_value_info("p" + str(i), TensorProto.FLOAT, input_shape) ] nodes = np.random.permutation(nodes) modelproto = helper.make_model( helper.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=value_info, nodes=nodes, ) ) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) for i in range(num_of_nodes): model.set_initializer( "p" + str(i), np.random.rand(*input_shape).astype(np.float32) ) return model
def test_factor_out_mul_sign_magnitude(): top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, [1, 2]) mul_param = oh.make_tensor_value_info("mul_param", TensorProto.FLOAT, [1, 2]) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, [1, 2]) modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=[mul_param], nodes=[oh.make_node("Mul", ["top_in", "mul_param"], ["top_out"])], )) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) model.set_initializer("mul_param", np.asarray([[-1, 4]], dtype=np.float32)) new_model = model.transform(FactorOutMulSignMagnitude()) inp_dict = {"top_in": np.asarray([[-1.0, 1.0]], dtype=np.float32)} assert ox.compare_execution(model, new_model, inp_dict)
def make_single_thresholding_modelwrapper(T, pe, idt, odt, actval, mem_mode): NumChannels = T.shape[0] inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, [1, NumChannels]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, NumChannels]) node_inp_list = ["inp", "thresh"] Thresholding_node = helper.make_node( "Thresholding_Batch", node_inp_list, ["outp"], domain="finn.custom_op.fpgadataflow", backend="fpgadataflow", NumChannels=NumChannels, PE=pe, numSteps=T.shape[1], inputDataType=idt.name, weightDataType=idt.name, # will be set by MinimizeAccumulatorWidth outputDataType=odt.name, ActVal=actval, mem_mode=mem_mode, ) graph = helper.make_graph( nodes=[Thresholding_node], name="thresholding_graph", inputs=[inp], outputs=[outp], ) model = helper.make_model(graph, producer_name="thresholding-model") model = ModelWrapper(model) model.set_tensor_datatype("inp", idt) model.set_tensor_datatype("outp", odt) model.set_tensor_datatype("thresh", idt) model.set_initializer("thresh", T) return model
def test_move_scalar_past_matmul_only_if_linear(test_args): scalar_op = test_args[0] transf_fxn = test_args[1] input_shape = [1, 2] matmul_shape = [2, 2] top_in = oh.make_tensor_value_info("top_in", TensorProto.FLOAT, input_shape) top_out = oh.make_tensor_value_info("top_out", TensorProto.FLOAT, input_shape) p1 = oh.make_tensor_value_info("p1", TensorProto.FLOAT, [1, 1]) p2 = oh.make_tensor_value_info("p2", TensorProto.FLOAT, matmul_shape) p3 = oh.make_tensor_value_info("p3", TensorProto.FLOAT, matmul_shape) p4 = oh.make_tensor_value_info("p4", TensorProto.FLOAT, matmul_shape) modelproto = oh.make_model( oh.make_graph( name="test", inputs=[top_in], outputs=[top_out], value_info=[p1, p2, p3, p4], nodes=[ oh.make_node(scalar_op, ["top_in", "p1"], ["t1"]), oh.make_node("MatMul", ["t1", "p2"], ["fork"]), oh.make_node("MatMul", ["fork", "p3"], ["t3"]), oh.make_node(scalar_op, ["t3", "fork"], ["t4"]), oh.make_node("MatMul", ["t4", "p4"], ["top_out"]), ], )) model = ModelWrapper(modelproto) model = model.transform(InferShapes()) np.random.seed(0) model.set_initializer("p1", np.random.rand(1, 1).astype(np.float32)) model.set_initializer("p2", np.random.rand(*matmul_shape).astype(np.float32)) model.set_initializer("p3", np.random.rand(*matmul_shape).astype(np.float32)) model.set_initializer("p4", np.random.rand(*matmul_shape).astype(np.float32)) # Transform new_model = model.transform(transf_fxn) # Test inp_dict = {"top_in": np.random.rand(*input_shape).astype(np.float32)} assert ox.compare_execution(model, new_model, inp_dict) assert new_model.graph.node[0].op_type == "MatMul" assert new_model.graph.node[1].op_type == scalar_op assert new_model.graph.node[2].op_type == "MatMul" assert new_model.graph.node[3].op_type == scalar_op assert new_model.graph.node[4].op_type == "MatMul"
def test_modelwrapper(): lfc = get_test_model_trained("LFC", 1, 1) bo.export_finn_onnx(lfc, (1, 1, 28, 28), export_onnx_path) model = ModelWrapper(export_onnx_path) assert model.check_all_tensor_shapes_specified() is False inp_shape = model.get_tensor_shape("0") assert inp_shape == [1, 1, 28, 28] l0_mat_tensor_name = "33" l0_weights = model.get_initializer(l0_mat_tensor_name) assert l0_weights.shape == (784, 1024) l0_weights_hist = Counter(l0_weights.flatten()) assert l0_weights_hist[1.0] == 401311 and l0_weights_hist[-1.0] == 401505 l0_weights_rand = np.random.randn(784, 1024) model.set_initializer(l0_mat_tensor_name, l0_weights_rand) assert (model.get_initializer(l0_mat_tensor_name) == l0_weights_rand).all() l0_inp_tensor_name = "32" inp_cons = model.find_consumer(l0_inp_tensor_name) assert inp_cons.op_type == "MatMul" out_prod = model.find_producer(l0_inp_tensor_name) assert out_prod.op_type == "Sign" os.remove(export_onnx_path)
def make_single_maxpool_modelwrapper(onnx_op_name, ishape, idt, pdt, pshape): inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, ishape) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, ishape) p0 = helper.make_tensor_value_info("p0", TensorProto.FLOAT, pshape) model = helper.make_model( helper.make_graph( name="test", inputs=[inp], outputs=[outp], value_info=[p0], nodes=[helper.make_node(onnx_op_name, ["inp", "p0"], ["outp"])], )) model = ModelWrapper(model) model.set_initializer("p0", gen_finn_dt_tensor(pdt, pshape)) model.set_tensor_datatype("inp", idt) model.transform(InferDataLayouts(), make_deepcopy=False) model.transform(InferShapes(), make_deepcopy=False) return model
def test_move_flatten_past_affine(data_layout, batch_size): if data_layout == DataLayout.NHWC: ishape = [batch_size, 1, 1, 1024] oshape = [batch_size, 1000] else: ishape = [batch_size, 1024, 1, 1] oshape = [batch_size, 1000] inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, ishape) a0 = helper.make_tensor_value_info("a1", TensorProto.FLOAT, [1024, 1000]) a1 = helper.make_tensor_value_info("a2", TensorProto.FLOAT, []) a2 = helper.make_tensor_value_info("a3", TensorProto.FLOAT, [1000]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, oshape) flatten_node = helper.make_node("Flatten", ["inp"], ["flatten_out"]) matmul_node = helper.make_node("MatMul", ["flatten_out", "a0"], ["matmul_out"]) mul_node = helper.make_node("Mul", ["matmul_out", "a1"], ["mul_out"]) add_node = helper.make_node("Add", ["mul_out", "a2"], ["outp"]) graph = helper.make_graph( nodes=[flatten_node, matmul_node, mul_node, add_node], name="move-reshape-graph", inputs=[inp], outputs=[outp], value_info=[a0, a1, a2], ) model = helper.make_model(graph, producer_name="move_reshape_model") model = ModelWrapper(model) # initialize values a0_values = gen_finn_dt_tensor(DataType["TERNARY"], [1024, 1000]) model.set_initializer("a0", a0_values) a1_values = np.random.uniform(low=0.1, high=0.99, size=(1)).astype(np.float32) model.set_initializer("a1", a1_values) a2_values = np.random.uniform(low=-1, high=1, size=(1000)).astype(np.float32) model.set_initializer("a2", a2_values) model.set_tensor_datatype("inp", DataType["INT2"]) model.set_tensor_layout("inp", data_layout) model = model.transform(InferShapes()) model = model.transform(InferDataTypes()) model = model.transform(InferDataLayouts()) model = model.transform(GiveUniqueNodeNames()) model = model.transform(GiveReadableTensorNames()) # compare execution before and after transformation inp_values = gen_finn_dt_tensor(DataType["INT2"], ishape) idict = {model.graph.input[0].name: inp_values} model_transformed = model.transform(MoveFlattenPastAffine()) assert oxe.compare_execution(model, model_transformed, idict) # depending on data layout check if graph is transformed or not if data_layout == DataLayout.NHWC: # check if nodes have new order in transformed graph assert model.graph != model_transformed.graph assert model_transformed.graph.node[-1].op_type == "Flatten" else: assert model.graph == model_transformed.graph
def test_remove_identity_ops(op, as_first_node, approx): # set up onnx model inp = helper.make_tensor_value_info("inp", TensorProto.FLOAT, [1, 4, 1, 1]) mul = helper.make_tensor_value_info("mul", TensorProto.FLOAT, []) shape = helper.make_tensor_value_info("shape", TensorProto.FLOAT, [2]) div = helper.make_tensor_value_info("div", TensorProto.FLOAT, []) matmul = helper.make_tensor_value_info("matmul", TensorProto.FLOAT, [4, 2]) outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, 2]) mul_node = helper.make_node("Mul", ["inp", "mul"], ["mul_out"]) reshape_node = helper.make_node("Reshape", ["mul_out", "shape"], ["reshape_out"]) div_node = helper.make_node("Div", ["reshape_out", "div"], ["div_out"]) matmul_node = helper.make_node("MatMul", ["div_out", "matmul"], ["outp"]) graph = helper.make_graph( nodes=[mul_node, reshape_node, div_node, matmul_node], name="identity-graph", inputs=[inp], outputs=[outp], value_info=[mul, shape, div, matmul], ) model = helper.make_model(graph, producer_name="mulpastconv-model") model = ModelWrapper(model) inp_values = gen_finn_dt_tensor(DataType["INT2"], [1, 4, 1, 1]) mul_values = np.random.uniform(low=0.1, high=0.99, size=(1)).astype(np.float32) shape_values = np.asarray([1, -1], dtype=np.int64) div_values = np.random.uniform(low=0.1, high=0.99, size=(1)).astype(np.float32) matmul_values = gen_finn_dt_tensor(DataType["INT2"], [4, 2]) model.set_initializer("mul", mul_values) model.set_initializer("shape", shape_values) model.set_initializer("div", div_values) model.set_initializer("matmul", matmul_values) insert_identity_op(model, op, as_first_node, approx) model = model.transform(InferShapes()) model = model.transform(InferDataTypes()) idict = {"inp": inp_values} odict = oxe.execute_onnx(model, idict) out_before = odict["outp"] num_of_nodes_before = len(model.graph.node) model = model.transform(RemoveIdentityOps()) num_of_nodes_after = len(model.graph.node) assert num_of_nodes_before - 1 == num_of_nodes_after odict = oxe.execute_onnx(model, idict) out_after = odict["outp"] assert np.isclose(out_before, out_after, atol=1e-3).all()
def test_modelwrapper(): raw_m = get_data("finn.data", "onnx/mnist-conv/model.onnx") model = ModelWrapper(raw_m) assert model.check_all_tensor_shapes_specified() is True inp_name = model.graph.input[0].name inp_shape = model.get_tensor_shape(inp_name) assert inp_shape == [1, 1, 28, 28] conv_nodes = model.get_nodes_by_op_type("Conv") matmul_nodes = model.get_nodes_by_op_type("MatMul") assert len(conv_nodes) == 2 assert len(matmul_nodes) == 1 first_conv = conv_nodes[0] first_conv_iname = first_conv.input[0] first_conv_wname = first_conv.input[1] first_conv_oname = first_conv.output[0] assert first_conv_iname != "" and (first_conv_iname is not None) assert first_conv_wname != "" and (first_conv_wname is not None) assert first_conv_oname != "" and (first_conv_oname is not None) first_conv_weights = model.get_initializer(first_conv_wname) assert first_conv_weights.shape == (8, 1, 5, 5) first_conv_weights_rand = np.random.randn(8, 1, 5, 5) model.set_initializer(first_conv_wname, first_conv_weights_rand) assert (model.get_initializer(first_conv_wname) == first_conv_weights_rand ).all() inp_cons = model.find_consumer(first_conv_iname) assert inp_cons == first_conv out_prod = model.find_producer(first_conv_oname) assert out_prod == first_conv inp_layout = model.get_tensor_layout(first_conv_iname) assert inp_layout is None inp_layout = DataLayout.NCHW model.set_tensor_layout(first_conv_iname, inp_layout) assert model.get_tensor_layout(first_conv_iname) == inp_layout inp_sparsity = model.get_tensor_sparsity(first_conv_iname) assert inp_sparsity is None inp_sparsity = {"dw": {"kernel_shape": [3, 3]}} model.set_tensor_sparsity(first_conv_iname, inp_sparsity) assert model.get_tensor_sparsity(first_conv_iname) == inp_sparsity
def test_batchnorm_to_affine_epsilon(epsilon): """Dummy batchnorm node to test out the epsilon attribute.""" batchnorm_node = onnx.helper.make_node( "BatchNormalization", inputs=["x", "s", "bias", "mean", "var"], outputs=["y"], epsilon=epsilon, ) x = onnx.helper.make_tensor_value_info("x", onnx.TensorProto.FLOAT, [1, 3, 5, 5]) s = onnx.helper.make_tensor_value_info("s", onnx.TensorProto.FLOAT, [3]) bias = onnx.helper.make_tensor_value_info("bias", onnx.TensorProto.FLOAT, [3]) mean = onnx.helper.make_tensor_value_info("mean", onnx.TensorProto.FLOAT, [3]) var = onnx.helper.make_tensor_value_info("var", onnx.TensorProto.FLOAT, [3]) y = onnx.helper.make_tensor_value_info("y", onnx.TensorProto.FLOAT, [1, 3, 5, 5]) # Graph graph = onnx.helper.make_graph( nodes=[batchnorm_node], name="test_batchnorm_graph", inputs=[x], outputs=[y], value_info=[s, bias, mean, var], ) onnx_model = onnx.helper.make_model(graph, producer_name="test_batchnorm-model") model = ModelWrapper(onnx_model) model.set_initializer("s", np.array([1, 2, 3]).astype(np.float32)) model.set_initializer("bias", np.array([1, 2, 3]).astype(np.float32)) model.set_initializer("mean", np.array([3, 4, 5]).astype(np.float32)) model.set_initializer("var", np.array([0.5, 0.7, 0.3]).astype(np.float32)) i_val = np.arange(0, 3 * 5 * 5, dtype=np.float32) i_val = np.reshape(i_val, [1, 3, 5, 5]) input_dict = {"x": i_val} output_node_name = "y" output_dict = oxe.execute_onnx(model, input_dict, return_full_exec_context=True) output_original = output_dict[output_node_name] model_lowered = model.transform(BatchNormToAffine()) output_dict = oxe.execute_onnx(model_lowered, input_dict, return_full_exec_context=True) output_lowered = output_dict[output_node_name] assert (output_original == output_lowered).all()