(self, graph, nodes)
return [reshape_1, transpose_1, reshape_2, transpose_2, final_reshape]
Pixel shuffle is implemented using 3 operators:
            - Reshape --> rank 6 (1, x1, x2, x3, x4, x5)
            - Transpose(0, 1, 4, 2, 5, 3) --> (1, x1, x4, x2, x5, x3)
            - Reshape ---> rank 4
        CoreML Reshape and Transpose layers don't support tensors with more
        than 4 dimensions. Thus we change above sequence of operators to the
        following equivalent sequence:
            - Reshape --> (x1, x2, x3, x4 * x5)
            - Transpose(0, 3, 1, 2) --> (x1, x4 * x5, x2, x3)
            - Reshape --> (x1 * x4, x5, x2, x3)
            - Transpose(0, 2, 1, 3) --> (x1 * x4, x2, x5, x3)
            - Reshape --> rank 4
Pixel shuffle is implemented using 3 operators:
            - Reshape --> rank 6 (1, x1, x2, x3, x4, x5)
            - Transpose(0, 1, 4, 2, 5, 3) --> (1, x1, x4, x2, x5, x3)
            - Reshape ---> rank 4
        CoreML Reshape and Transpose layers don't support tensors with more
        than 4 dimensions. Thus we change above sequence of operators to the
        following equivalent sequence:
            - Reshape --> (x1, x2, x3, x4 * x5)
            - Transpose(0, 3, 1, 2) --> (x1, x4 * x5, x2, x3)
            - Reshape --> (x1 * x4, x5, x2, x3)
            - Transpose(0, 2, 1, 3) --> (x1 * x4, x2, x5, x3)
            - Reshape --> rank 4
Pixel shuffle is implemented using 3 operators : - Reshape -- > rank 6 ( 1 x1 x2 x3 x4 x5 ) - Transpose ( 0 1 4 2 5 3 ) -- > ( 1 x1 x4 x2 x5 x3 ) - Reshape --- > rank 4 CoreML Reshape and Transpose layers don t support tensors with more than 4 dimensions . Thus we change above sequence of operators to the following equivalent sequence : - Reshape -- > ( x1 x2 x3 x4 * x5 ) - Transpose ( 0 3 1 2 ) -- > ( x1 x4 * x5 x2 x3 ) - Reshape -- > ( x1 * x4 x5 x2 x3 ) - Transpose ( 0 2 1 3 ) -- > ( x1 * x4 x2 x5 x3 ) - Reshape -- > rank 4
def merge(self, graph, nodes):  # type: (Graph, Sequence[Node]) -> Sequence[Node]
        '''
        Pixel shuffle is implemented using 3 operators:
            - Reshape --> rank 6 (1, x1, x2, x3, x4, x5)
            - Transpose(0, 1, 4, 2, 5, 3) --> (1, x1, x4, x2, x5, x3)
            - Reshape ---> rank 4
        CoreML Reshape and Transpose layers don't support tensors with more
        than 4 dimensions. Thus we change above sequence of operators to the
        following equivalent sequence:
            - Reshape --> (x1, x2, x3, x4 * x5)
            - Transpose(0, 3, 1, 2) --> (x1, x4 * x5, x2, x3)
            - Reshape --> (x1 * x4, x5, x2, x3)
            - Transpose(0, 2, 1, 3) --> (x1 * x4, x2, x5, x3)
            - Reshape --> rank 4
        '''
        reshape_1 = nodes[0]
        transpose_1 = nodes[1]
        final_reshape = nodes[2]

        # first reshape
        shape_1 = reshape_1.input_tensors[reshape_1.inputs[1]]
        shape_1 = _get_fully_defined_shape(shape_1, nodes[0].outputs[0], graph)
        x1 = shape_1[1]
        x2 = shape_1[2]
        x3 = shape_1[3]
        x4 = shape_1[4]
        x5 = shape_1[5]
        reshape_1.input_tensors[reshape_1.inputs[1]] = np.asarray([x1, x2, x3, x4 * x5])

        # first transpose
        transpose_1.children = []
        transpose_1.attrs['perm'] = [0, 3, 1, 2]

        reshape_output_name = final_reshape.name + '_pixel_shuffle_reshape'
        transpose_output_name = final_reshape.name + '_pixel_shuffle_transpose'

        transpose_1.outputs = [
            self.get_unique_edge_name(graph, transpose_output_name)
        ]

        shape_name_second_reshape = self.get_unique_edge_name(graph, reshape_output_name)
        output_name_second_reshape = self.get_unique_edge_name(graph, reshape_output_name)

        # second reshape
        reshape_2 = Node(
            reshape_output_name,
            'Reshape',
            {},
            [transpose_1.outputs[0], shape_name_second_reshape],
            [output_name_second_reshape]
        )
        reshape_2.input_tensors[shape_name_second_reshape] = np.asarray([x1 * x4, x5, x2, x3])
        transpose_1.add_child(reshape_2)

        # second transpose
        transpose_2 = Node(
            transpose_output_name,
            'Transpose',
            {'perm': [0, 2, 1, 3]},
            reshape_2.outputs,
            [self.get_unique_edge_name(graph, transpose_output_name)]
        )
        reshape_2.add_child(transpose_2)

        # third reshape
        final_reshape.inputs = [transpose_2.outputs[0], nodes[2].inputs[1]]
        final_reshape.parents = []
        transpose_2.add_child(final_reshape)

        return [reshape_1, transpose_1, reshape_2, transpose_2, final_reshape]
def merge ( self , graph , nodes ) : # type: (Graph, Sequence[Node]) -> Sequence[Node] reshape_1 = nodes [ 0 ] transpose_1 = nodes [ 1 ] final_reshape = nodes [ 2 ] # first reshape shape_1 = reshape_1 . input_tensors [ reshape_1 . inputs [ 1 ] ] shape_1 = _get_fully_defined_shape ( shape_1 , nodes [ 0 ] . outputs [ 0 ] , graph ) x1 = shape_1 [ 1 ] x2 = shape_1 [ 2 ] x3 = shape_1 [ 3 ] x4 = shape_1 [ 4 ] x5 = shape_1 [ 5 ] reshape_1 . input_tensors [ reshape_1 . inputs [ 1 ] ] = np . asarray ( [ x1 , x2 , x3 , x4 * x5 ] ) # first transpose transpose_1 . children = [ ] transpose_1 . attrs [ 'perm' ] = [ 0 , 3 , 1 , 2 ] reshape_output_name = final_reshape . name + '_pixel_shuffle_reshape' transpose_output_name = final_reshape . name + '_pixel_shuffle_transpose' transpose_1 . outputs = [ self . get_unique_edge_name ( graph , transpose_output_name ) ] shape_name_second_reshape = self . get_unique_edge_name ( graph , reshape_output_name ) output_name_second_reshape = self . get_unique_edge_name ( graph , reshape_output_name ) # second reshape reshape_2 = Node ( reshape_output_name , 'Reshape' , { } , [ transpose_1 . outputs [ 0 ] , shape_name_second_reshape ] , [ output_name_second_reshape ] ) reshape_2 . input_tensors [ shape_name_second_reshape ] = np . asarray ( [ x1 * x4 , x5 , x2 , x3 ] ) transpose_1 . add_child ( reshape_2 ) # second transpose transpose_2 = Node ( transpose_output_name , 'Transpose' , { 'perm' : [ 0 , 2 , 1 , 3 ] } , reshape_2 . outputs , [ self . get_unique_edge_name ( graph , transpose_output_name ) ] ) reshape_2 . add_child ( transpose_2 ) # third reshape final_reshape . inputs = [ transpose_2 . outputs [ 0 ] , nodes [ 2 ] . inputs [ 1 ] ] final_reshape . parents = [ ] transpose_2 . add_child ( final_reshape ) return [ reshape_1 , transpose_1 , reshape_2 , transpose_2 , final_reshape ]