def test_negative(self): graph = build_graph(nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 15, 15])), **regular_op_with_empty_data( 'layer_norm', { 'op': 'LayerNorm', 'epsilon': 0.001, 'axis': -1, 'output_mean_var': True }), **shaped_const_with_data('gamma', None), **shaped_const_with_data('beta', None), **result('result'), **result('result_1'), **result('result_2') }, edges=[ *connect('input', '0:layer_norm'), *connect('gamma', '1:layer_norm'), *connect('beta', '2:layer_norm'), *connect('layer_norm:0', 'result'), *connect('layer_norm:1', 'result_1'), *connect('layer_norm:2', 'result_2') ]) with self.assertRaises(Error): LayerNormalization().find_and_replace_pattern(graph)
def test_run_with_const_input(self): inp_shape = (1, 3, 1000, 1000) nodes = { **shaped_const_with_data('input', int64_array(inp_shape)), **regular_op('sizes_const', {'op': 'Const'}), **{'sizes_const_d': {'kind': 'data', 'value': float32_array([1., 1., 1., 100.])}}, **regular_op_with_empty_data('interpolate', {'type': 'Interpolate', 'shape_calculation_model': 'scales'}), **result('res'), } nodes_ref = { **shaped_const_with_data('input', int64_array(inp_shape)), **regular_op('sizes_const', {'op': 'Const', 'returns_shape_value': True}), **{'sizes_const_d': {'kind': 'data', 'value': float32_array([1., 1., 1., 100.])}}, **regular_op_with_empty_data('interpolate', {'type': 'Interpolate', 'shape_calculation_model': 'scales'}), **result('res'), } edges = [ *connect('input', '0:interpolate'), *connect('sizes_const', '1:interpolate'), *connect('interpolate', 'res'), ] graph = build_graph(nodes, edges) interp_node = Node(graph, 'interpolate') interp_node.add_input_port(2) MarkNodesWithShapeValues().find_and_replace_pattern(graph) graph_ref = build_graph(nodes_ref, edges) (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True) self.assertTrue(flag, resp)
def test_negative(self): nodes = { **shaped_const_with_data('input_0', [1]), **shaped_const_with_data('input_1', [1]), **shaped_const_with_data('input_2', [1]), **shaped_const_with_data('input_3', [1]), **regular_op_with_shaped_data('concat', [4], {'type': 'Concat'}), **result(), } edges = [ *connect('input_0', '0:concat'), *connect('input_1', '1:concat'), *connect('input_2', '2:concat'), *connect('input_3', '3:concat'), *connect('concat', 'output'), ] graph = build_graph(nodes, edges, nodes_with_edges_only=True) ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph) graph_ref = build_graph(nodes, edges, nodes_with_edges_only=True) (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True) self.assertTrue(flag, resp)
def test_deletion_3(self): nodes = { **shaped_const_with_data('input_0', [5, 3]), **shaped_const_with_data('input_1', [5, 1]), **shaped_const_with_data('input_2', [5, 5]), **shaped_const_with_data('input_3', [5, 0]), **regular_op_with_shaped_data('concat', [5, 9], { 'type': 'Concat', 'axis': 1 }), **result(), } edges_before = [ *connect('input_0', '0:concat'), *connect('input_1', '1:concat'), *connect('input_2', '2:concat'), *connect('input_3', '3:concat'), *connect('concat', 'output'), ] edges_after = [ *connect('input_0', '0:concat'), *connect('input_1', '1:concat'), *connect('input_2', '2:concat'), *connect('concat', 'output'), ] graph = build_graph(nodes, edges_before, nodes_with_edges_only=True) ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph) graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True) (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True) self.assertTrue(flag, resp)
def test_1(self): graph = build_graph(nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 15, 15])), **regular_op_with_empty_data('div_sqrt_dim', { 'op': '_contrib_div_sqrt_dim' }), **result('result') }, edges=[ *connect('input', 'div_sqrt_dim'), *connect('div_sqrt_dim', 'result') ]) ref_graph = build_graph( nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 15, 15])), **regular_op_with_empty_data('div_sqrt_shape_of', { 'op': 'ShapeOf', 'type': 'ShapeOf' }), **shaped_const_with_data('gather_axis', None), **shaped_const_with_data('gather_indices', None), **regular_op_with_empty_data('gather', { 'op': 'Gather', 'type': 'Gather' }), **regular_op_with_empty_data('power', { 'op': 'AttributedPower', 'power': 0.5, 'type': 'Power' }), **regular_op_with_empty_data('cast', { 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32 }), **regular_op_with_empty_data('div', { 'op': 'Div', 'type': 'Divide' }), **result('result') }, edges=[ *connect('input', '0:div'), *connect_data('input', 'div_sqrt_shape_of'), *connect('div_sqrt_shape_of', '0:gather'), *connect('gather_axis', '1:gather'), *connect('gather_indices', '2:gather'), *connect('gather', 'cast'), *connect('cast', 'power'), *connect('power', '1:div'), *connect('div', 'result') ], ) DivSqrtDim().find_and_replace_pattern(graph) flag, resp = compare_graphs(graph, ref_graph, 'result', 'result', check_op_attrs=True) self.assertTrue(flag, resp)
def test_deletion_trailing_unconnected_ports(self): nodes = { **shaped_const_with_data('input_0', [5, 3]), **regular_op_with_shaped_data('concat', [5, 3], { 'type': 'Concat', 'axis': 1 }), **result(), } edges_before = [ *connect('input_0', '0:concat'), *connect('concat', 'output'), ] edges_after = [ *connect('input_0', '0:concat'), *connect('concat', 'output'), ] graph = build_graph(nodes, edges_before, nodes_with_edges_only=True) Node(graph, 'concat').add_input_port(1) ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph) graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True) (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True) self.assertTrue(flag, resp) self.assertTrue(1 not in Node(graph, 'concat').in_ports())
def nodes(self, input_shape, transpose_shape, fq_shape, is_input_const): nodes = { **valued_const_with_data('il', np.array([[[[0]]]])), **valued_const_with_data('ih', np.array([[[[255]]]])), **valued_const_with_data('ol', np.array([[[[0]]]])), **valued_const_with_data('oh', np.array([[[[255]]]])), **regular_op_with_shaped_data( 'FQ', fq_shape, dict(type='FakeQuantize', op='FakeQuantize', infer=FakeQuantize.infer)), **valued_const_with_data('order', int64_array([0, 2, 3, 1])), **regular_op_with_shaped_data( 'transpose', transpose_shape, dict(type='Transpose', op='Transpose', infer=Transpose.infer)), **regular_op_with_shaped_data('relu', fq_shape, dict(type='Relu', op='Relu')), **result(), } if is_input_const: input_node = shaped_const_with_data('input', input_shape) else: input_node = regular_op_with_shaped_data( 'input', input_shape, dict(type='Parameter', op='Parameter')) nodes.update(input_node) return nodes
def test_accuracy(self, data, in_low, in_high, out_low, out_high, levels): nodes = nodes_dict(np.float32, None, levels, data, in_low, in_high, out_low, out_high) graph = build_graph(nodes, [ *connect('weights:0', '0:FQ'), *connect('il:0', '1:FQ'), *connect('ih:0', '2:FQ'), *connect('ol:0', '3:FQ'), *connect('oh:0', '4:FQ'), *connect('FQ:0', 'output'), ], nodes_with_edges_only=True) graph_ref = graph.copy() CompressQuantizeWeights().find_and_replace_pattern(graph) for node in graph.get_op_nodes() + graph_ref.get_op_nodes(): node['stop_value_propagation'] = False node['need_shape_inference'] = node.soft_get( 'need_shape_inference', True) graph.clean_up() graph_ref.clean_up() const_result_graph = build_graph( { **shaped_const_with_data('weights', np.array(data).shape), **result() }, [*connect('weights', 'output')], nodes_with_edges_only=True) (flag, resp) = compare_graphs(graph, const_result_graph, 'output', check_op_attrs=True) self.assertTrue(flag, resp) (flag, resp) = compare_graphs(graph_ref, const_result_graph, 'output', check_op_attrs=True) self.assertTrue(flag, resp) # as this two graphs calculated the same data through different constant folding functions, they resulted in # constants of different data type since FakeQuantize always have f32 output dtype, but eltwises use numpy # for folding which doesn't have such restriction const_node = graph.get_op_nodes(type='Const') self.assertEqual(len(const_node), 1) if const_node[0].data_type == np.float64: const_node[0].data_type = np.float32 (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True) self.assertTrue(flag, resp)
def test_assertion_error(self): nodes = { **shaped_const_with_data('input_0', [0]), **shaped_const_with_data('input_1', [0]), **shaped_const_with_data('input_2', [0]), **shaped_const_with_data('input_3', [0]), **regular_op_with_shaped_data('concat', [0], {'type': 'Concat'}), **result(), } edges = [ *connect('input_0', '0:concat'), *connect('input_1', '1:concat'), *connect('input_2', '2:concat'), *connect('input_3', '3:concat'), *connect('concat', 'output'), ] graph = build_graph(nodes, edges, nodes_with_edges_only=True) self.assertRaises(AssertionError, ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern, graph)
def test_2(self): graph = build_graph( nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 15, 15])), **regular_op_with_empty_data('layer_norm', {'op': 'LayerNorm', 'epsilon': 0.001, 'axis': 1, 'output_mean_var': False}), **shaped_const_with_data('gamma', None), **shaped_const_with_data('beta', None), **result('result') }, edges=[ *connect('input', '0:layer_norm'), *connect('gamma', '1:layer_norm'), *connect('beta', '2:layer_norm'), *connect('layer_norm', 'result') ] ) ref_graph = build_graph( nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 15, 15])), **shaped_const_with_data('mvn_const', None), **regular_op_with_empty_data('mvn', {'eps': 0.001, 'across_channels': 1, 'normalize_variance': 1, 'eps_mode': 'inside_sqrt', 'op': 'MVN', 'type': 'MVN'}), **shaped_const_with_data('gamma', None), **regular_op_with_empty_data('gamma_unsqueeze', {'op': 'Unsqueeze', 'type': 'Unsqueeze'}), **shaped_const_with_data('gamma_unsqueeze_const', None), **regular_op_with_empty_data('beta_unsqueeze', {'op': 'Unsqueeze', 'type': 'Unsqueeze'}), **shaped_const_with_data('beta_unsqueeze_const', None), **regular_op_with_empty_data('mul', {'op': 'Mul', 'type': 'Multiply'}), **shaped_const_with_data('beta', None), **regular_op_with_empty_data('add', {'op': 'Add', 'type': 'Add'}), **result('result') }, edges=[ *connect('input', '0:mvn'), *connect('mvn_const', '1:mvn'), *connect('mvn', '0:mul'), *connect('gamma', 'gamma_unsqueeze'), *connect('gamma_unsqueeze_const', '1:gamma_unsqueeze'), *connect('gamma_unsqueeze', '1:mul'), *connect('mul', '0:add'), *connect('beta', 'beta_unsqueeze'), *connect('beta_unsqueeze_const', '1:beta_unsqueeze'), *connect('beta_unsqueeze', '1:add'), *connect('add', 'result') ], update_attributes={ 'mvn_const': {'value': int64_array([1]), 'shape': int64_array([1])}, 'gamma_unsqueeze_const': {'value': int64_array([0, 2, 3]), 'shape': int64_array([3])}, 'beta_unsqueeze_const': {'value': int64_array([0, 2, 3]), 'shape': int64_array([3])} } ) LayerNormalization().find_and_replace_pattern(graph) flag, resp = compare_graphs(graph, ref_graph, 'result', 'result', check_op_attrs=True) self.assertTrue(flag, resp)
def test_pool_v2_to_attributed_pool(self): nodes = { **shaped_const_with_data('input', int64_array([200, 200])), **valued_const_with_data('windows', int64_array([4, 4])), **valued_const_with_data('strides', int64_array([4, 4])), **regular_op_with_empty_data( 'pool_v2', { 'op': 'PoolingV2', 'pad': [2, 2], 'spatial_dims': [1, 2], 'auto_pad': 'same_upper', 'output_spatial_shape': [2, 3], 'pad_spatial_shape': [1, 2], 'pool_method': 'max', 'permute_attrs': None }), **regular_op_with_empty_data( 'pool_v1', { 'type': 'Pooling', 'pad': [2, 2], 'spatial_dims': [1, 2], 'auto_pad': 'same_upper', 'output_spatial_shape': [2, 3], 'pad_spatial_shape': [1, 2], 'pool_method': 'max' }), **result('output') } edges = [ *connect('input', 'pool_v2:0'), *connect('windows', 'pool_v2:1'), *connect('strides', 'pool_v2:2'), *connect('pool_v2', 'output'), ] graph = build_graph(nodes, edges, nodes_with_edges_only=True) PoolV2ToAttributedPool().find_and_replace_pattern(graph) ref_graph = build_graph( nodes, [*connect('input', 'pool_v1'), *connect('pool_v1', 'output')], nodes_with_edges_only=True) (flag, resp) = compare_graphs(graph, ref_graph, 'output') self.assertTrue(flag, resp)
def test_run_with_solitary_shapeof_in_shape_value_subgraph(self): # in this case MarkNodesWithShapeValues must leave graph unchanged # so reference nodes are exactly the same inp_shape_1 = int64_array((1, 3, 100, 100)) inp_shape_2 = int64_array((1, 3, 100, 50)) # inp_2 and const will be concatenated to (1, 3, 200, 50) const_shape = int64_array((1, 3, 100, 50)) nodes = { **regular_op_with_shaped_data('input_1', inp_shape_1, {'op': 'Parameter', 'type': 'Parameter'}), **regular_op_with_shaped_data('input_2', inp_shape_2, {'op': 'Parameter', 'type': 'Parameter', 'returns_shape_value': False}), **shaped_const_with_data('const', const_shape), **regular_op_with_empty_data('concat', {'op': 'Concat', 'type': 'Concat', 'axis': 2, 'returns_shape_value': False}), **regular_op_with_empty_data('shapeof', {'op': 'ShapeOf', 'type': 'ShapeOf'}), **regular_op_with_empty_data('reshape', {'op': 'Reshape', 'type': 'Reshape'}), **result('res'), } edges = [ *connect('input_1', '0:reshape'), *connect('input_2', '0:concat'), *connect('const', '1:concat'), *connect('concat', 'shapeof'), *connect('shapeof', '1:reshape'), *connect('reshape', 'res'), ] graph = build_graph(nodes, edges) MarkNodesWithShapeValues().find_and_replace_pattern(graph) graph_ref = build_graph(nodes, edges) (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True) self.assertTrue(flag, "'returns_shape_value' should be False or unset for ShapeOf input nodes" + ': ' + str(resp))
def test_axis_not_none_start_1_step_2(self): graph = build_graph(nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 5, 5])), **regular_op_with_empty_data( 'arange_like', { 'op': 'arange_like', 'type': None, 'axis': 3, 'repeat': 1, 'start': 1, 'step': 2 }), **result('result') }, edges=[ *connect('input', 'arange_like'), *connect('arange_like', 'result') ]) ref_graph = build_graph( nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 5, 5])), **regular_op_with_empty_data('shape_of', { 'op': 'ShapeOf', 'type': 'ShapeOf' }), **shaped_const_with_data('gather_axis', None), **shaped_const_with_data('gather_indices', None), **regular_op_with_empty_data('gather', { 'op': 'Gather', 'type': 'Gather' }), **regular_op_with_empty_data('mul', { 'op': 'Mul', 'type': 'Multiply' }), **shaped_const_with_data('mul_const', None), **shaped_const_with_data('range_start', None), **shaped_const_with_data('range_step', None), **shaped_const_with_data('add_const', None), **regular_op_with_empty_data('add', { 'op': 'Add', 'type': 'Add' }), **shaped_const_with_data('squeeze_const', None), **regular_op_with_empty_data('squeeze', { 'op': 'Squeeze', 'type': 'Squeeze' }), **regular_op_with_empty_data('range', { 'op': 'Range', 'type': 'Range' }), **regular_op_with_empty_data('slice', { 'op': 'Slice', 'type': None }), **shaped_const_with_data('slice_start', None), **shaped_const_with_data('slice_axes', None), **shaped_const_with_data('slice_step', None), **result('result') }, edges=[ *connect('input', 'shape_of'), *connect('shape_of', '0:gather'), *connect('gather_axis', '1:gather'), *connect('gather_indices', '2:gather'), *connect('range_start', '0:range'), *connect('gather', '0:mul'), *connect('mul_const', '1:mul'), *connect('mul', '0:add'), *connect('add_const', '1:add'), *connect('squeeze_const', '1:squeeze'), *connect('add', '0:squeeze'), *connect('squeeze', '1:range'), *connect('range_step', '2:range'), *connect('range', '0:slice'), *connect('slice_start', '1:slice'), *connect_data('gather', '2:slice'), *connect('slice_axes', '3:slice'), *connect('slice_step', '4:slice'), *connect('slice', 'result') ], update_attributes={ 'gather_axis': { 'value': 3 }, 'gather_indices': { 'value': 0 }, 'range_start': { 'value': 1 }, 'range_step': { 'value': 2 }, 'add_const': { 'value': 1 }, 'mul_const': { 'value': 2 }, 'slice_start': { 'value': int64_array([0]) }, 'slice_axes': { 'value': int64_array([0]) }, 'slice_step': { 'value': int64_array([1]) }, }) ArangeLikeReplacer().find_and_replace_pattern(graph) flag, resp = compare_graphs(graph, ref_graph, 'result', 'result', check_op_attrs=True) self.assertTrue(flag, resp)
'internal_layer_id': 5 }), } sub_graph_2_nodes = { **shaped_parameter('cond_2_int', [1, 4, 64, 54], {'internal_layer_id': 0}), **regular_op_with_empty_data( "cond_2_int_out", { 'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 8 }), **shaped_parameter('in_2_int', [1, 4, 64, 54], {'internal_layer_id': 1}), **shaped_const_with_data('ones', int64_array([1, 4, 64, 54]), { 'internal_layer_id': 9 }), **regular_op_with_shaped_data('OUT_2', int64_array([1, 4, 64, 54]), { 'op': "Add", 'infer': copy_shape_infer }), **regular_op_with_empty_data( 'OUT_2_out', { 'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 7 }), **regular_op_with_shaped_data( 'in_2_int_out', int64_array([1, 4, 64, 54]), { 'op': 'Result',
'internal_layer_id': 2 }), **regular_op_with_empty_data( "cond_1_int_out", { 'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 5 }), } sub_graph_2_nodes = { **shaped_parameter('cond_2_int', [1, 4, 64, 54], {'internal_layer_id': 0}), **result("cond_2_int_out"), **shaped_parameter('in_2_int', [1, 4, 64, 54], {'internal_layer_id': 1}), **shaped_const_with_data('ones', int64_array([1, 4, 64, 54])), **regular_op_with_shaped_data('OUT_2', int64_array([1, 4, 64, 54]), { 'op': "Add", 'infer': copy_shape_infer }), **regular_op_with_empty_data( 'OUT_2_out', { 'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 7 }), **regular_op_with_shaped_data( 'in_2_int_out', int64_array([1, 4, 64, 54]), { 'op': 'Result', 'type': 'Result',
def convert_args(val, name=''): if val is not None: return valued_const_with_data(name, int64_array(val)) else: return shaped_const_with_data(name, [0]) #fake shape
def test_axis_none_start_1(self): graph = build_graph(nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 5, 5])), **regular_op_with_empty_data( 'arange_like', { 'op': 'arange_like', 'type': None, 'axis': None, 'repeat': 1, 'start': 1, 'step': 1 }), **result('result') }, edges=[ *connect('input', 'arange_like'), *connect('arange_like', 'result') ]) ref_graph = build_graph( nodes_attrs={ **shaped_parameter('input', int64_array([1, 3, 5, 5])), **regular_op_with_empty_data('shape_of', { 'op': 'ShapeOf', 'type': 'ShapeOf' }), **regular_op_with_empty_data('reduce_prod', { 'op': 'ReduceProd', 'type': 'ReduceProd' }), **shaped_const_with_data('reduce_prod_const', None), **shaped_const_with_data('squeeze_const', None), **regular_op_with_empty_data('squeeze', { 'op': 'Squeeze', 'type': 'Squeeze' }), **shaped_const_with_data('add_const', None), **regular_op_with_empty_data('add', { 'op': 'Add', 'type': 'Add' }), **shaped_const_with_data('range_start', None), **shaped_const_with_data('range_step', None), **regular_op_with_empty_data('range', { 'op': 'Range', 'type': 'Range' }), **regular_op_with_empty_data('reshape_backward', { 'op': 'Reshape', 'type': 'Reshape' }), **result('result') }, edges=[ *connect('input', 'shape_of'), *connect('shape_of', '0:reduce_prod'), *connect('reduce_prod_const', '1:reduce_prod'), *connect('squeeze_const', '1:squeeze'), *connect('add_const', '1:add'), *connect('reduce_prod', '0:add'), *connect('add', '0:squeeze'), *connect('range_start', '0:range'), *connect('range_step', '2:range'), *connect('squeeze', '1:range'), *connect('range', '0:reshape_backward'), *connect_data('shape_of', '1:reshape_backward'), *connect('reshape_backward', 'result') ], update_attributes={ 'range_start': { 'value': 1 }, 'range_step': { 'value': 1 }, 'add_const': { 'value': 1 }, 'reduce_prod_const': { 'value': int64_array([0]) } }) ArangeLikeReplacer().find_and_replace_pattern(graph) flag, resp = compare_graphs(graph, ref_graph, 'result', 'result', check_op_attrs=True) self.assertTrue(flag, resp)
from unit_tests.utils.graph import regular_op_with_shaped_data, regular_op_with_empty_data, shaped_const_with_data, \ result, connect, build_graph nodes = { **regular_op_with_shaped_data('input', [1, 3, 5, 5], { 'type': 'Parameter', 'op': 'Parameter' }), **regular_op_with_empty_data( 'strided_slice', { 'type': 'StridedSlice', 'op': 'StridedSlice', 'begin_mask': [0, 0, 0, 0], 'end_mask': [0, 0, 0, 0] }), **shaped_const_with_data('begin', [4]), **shaped_const_with_data('end', [4]), **result('result'), **regular_op_with_empty_data('squeeze', { 'type': 'Squeeze', 'op': 'Squeeze' }), **shaped_const_with_data('squeeze_axes', None), **regular_op_with_empty_data('unsqueeze', { 'type': 'Unsqueeze', 'op': 'Unsqueeze' }), **shaped_const_with_data('unsqueeze_axes', None) } pattern_edges = [
nodes = { **regular_op_with_shaped_data('placeholder1', [1, 16, 10, 10], { 'type': 'Parameter' }), **valued_const_with_data('split_1_axis', int64_array(1), { 'type': 'Const' }), **regular_op('split_1', { 'type': 'Split', 'can_be_fused': True }), **shaped_data('split_1_data1', [1, 4, 10, 10]), **shaped_data('split_1_data2', [1, 4, 10, 10]), **shaped_data('split_1_data3', [1, 4, 10, 10]), **shaped_data('split_1_data4', [1, 4, 10, 10]), **shaped_const_with_data('split_2_in_const_weights', int64_array([3, 3, 4, 16]), {'type': 'Const'}), **regular_op('split_2', {'type': 'Split'}), **valued_data('split_2_data1', np.zeros([3, 3, 4, 4])), **valued_data('split_2_data2', np.zeros([3, 3, 4, 4])), **valued_data('split_2_data3', np.zeros([3, 3, 4, 4])), **valued_data('split_2_data4', np.zeros([3, 3, 4, 4])), **regular_op_with_shaped_data( 'conv2d_1', [1, 4, 8, 8], { 'type': 'Convolution', 'channel_dims': np.array([1]), 'pad': np.array([2, 2]), 'stride': np.array([2, 2]),