parameters: (builder, node, graph, err)
docstring: convert to CoreML Reshape Static Layer:
      https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4844
docstring_summary: convert to CoreML Reshape Static Layer:
      https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4844
docstring_tokens: convert to CoreML Reshape Static Layer : https : // github . com / apple / coremltools / blob / 655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492 / mlmodel / format / NeuralNetwork . proto#L4844
function: def _convert_reshape(builder, node, graph, err):
      """
      convert to CoreML Reshape Static Layer:
      https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4844
      """
      shape_node = node.inputs[1]
      if shape_node in node.input_tensors:
          output_shape = node.input_tensors[shape_node].astype(np.int64)
  
          # if rank is same, then call rank preserving reshape
          if node.inputs[0] not in graph.shape_dict:
              # If Input shape is not present and output shape is known
              # add reshape static as
              # TODO: ONNX should be able to infer the shape
              builder.add_reshape_static(
                  name=node.name,
                  input_name=node.inputs[0],
                  output_name=node.outputs[0],
                  output_shape=output_shape,
              )
              return
  
          len_of_input_shape = builder._get_rank(node.inputs[0])
          if len(output_shape) == len_of_input_shape:
              builder.add_rank_preserving_reshape(
                  name=node.name,
                  input_name=node.inputs[0],
                  output_name=node.outputs[0],
                  output_shape=output_shape,
              )
          else:
              add_static_reshape = True
              if len_of_input_shape > len(output_shape):
                  # Output rank is less than input rank
                  # Case when most of the dims size is unchanged
                  num_zeros = 0
                  num_neg_ones = 0
                  for i in output_shape:
                      if i == 0:
                          num_zeros += 1
                      elif i == -1:
                          num_neg_ones += 1
  
                  if num_neg_ones > 1:
                      err.unsupported_op_configuration(
                          builder,
                          node,
                          graph,
                          "Error in ONNX model: At most one dimension of new shape can be -1, found {}".format(
                              num_neg_ones
                          ),
                      )
  
                  if num_neg_ones + num_zeros == len(output_shape):
                      # Rank of output is less than input
                      # Make Rank equivalent for reshape and then squeeze
                      add_static_reshape = False
                      new_shape = []
                      i = 0
                      for i in range(len(output_shape)):
                          new_shape.append(output_shape[i])
                          if output_shape[i] == -1:
                              break
                      while i < len_of_input_shape - 1:
                          new_shape.append(1)
                          i += 1
  
                      builder.add_rank_preserving_reshape(
                          name=node.name + "_reshape_preserving",
                          input_name=node.inputs[0],
                          output_name=node.outputs[0] + "_reshape_dim_preserved",
                          output_shape=new_shape,
                      )
  
                      squeeze_axes = list(
                          range(len(output_shape) - len_of_input_shape, 0)
                      )
                      squeeze_axes.reverse()
  
                      builder.add_squeeze(
                          name=node.name,
                          input_name=node.outputs[0] + "_reshape_dim_preserved",
                          output_name=node.outputs[0],
                          axes=squeeze_axes,
                      )
  
              if add_static_reshape:
                  builder.add_reshape_static(
                      name=node.name,
                      input_name=node.inputs[0],
                      output_name=node.outputs[0],
                      output_shape=output_shape,
                  )
      else:
          builder.add_reshape_dynamic(
              name=node.name, input_names=node.inputs, output_name=node.outputs[0],
          )
function_tokens: def _convert_reshape ( builder , node , graph , err ) : shape_node = node . inputs [ 1 ] if shape_node in node . input_tensors : output_shape = node . input_tensors [ shape_node ] . astype ( np . int64 ) # if rank is same, then call rank preserving reshape if node . inputs [ 0 ] not in graph . shape_dict : # If Input shape is not present and output shape is known # add reshape static as # TODO: ONNX should be able to infer the shape builder . add_reshape_static ( name = node . name , input_name = node . inputs [ 0 ] , output_name = node . outputs [ 0 ] , output_shape = output_shape , ) return len_of_input_shape = builder . _get_rank ( node . inputs [ 0 ] ) if len ( output_shape ) == len_of_input_shape : builder . add_rank_preserving_reshape ( name = node . name , input_name = node . inputs [ 0 ] , output_name = node . outputs [ 0 ] , output_shape = output_shape , ) else : add_static_reshape = True if len_of_input_shape > len ( output_shape ) : # Output rank is less than input rank # Case when most of the dims size is unchanged num_zeros = 0 num_neg_ones = 0 for i in output_shape : if i == 0 : num_zeros += 1 elif i == - 1 : num_neg_ones += 1 if num_neg_ones > 1 : err . unsupported_op_configuration ( builder , node , graph , "Error in ONNX model: At most one dimension of new shape can be -1, found {}" . format ( num_neg_ones ) , ) if num_neg_ones + num_zeros == len ( output_shape ) : # Rank of output is less than input # Make Rank equivalent for reshape and then squeeze add_static_reshape = False new_shape = [ ] i = 0 for i in range ( len ( output_shape ) ) : new_shape . append ( output_shape [ i ] ) if output_shape [ i ] == - 1 : break while i < len_of_input_shape - 1 : new_shape . append ( 1 ) i += 1 builder . add_rank_preserving_reshape ( name = node . name + "_reshape_preserving" , input_name = node . inputs [ 0 ] , output_name = node . outputs [ 0 ] + "_reshape_dim_preserved" , output_shape = new_shape , ) squeeze_axes = list ( range ( len ( output_shape ) - len_of_input_shape , 0 ) ) squeeze_axes . reverse ( ) builder . add_squeeze ( name = node . name , input_name = node . outputs [ 0 ] + "_reshape_dim_preserved" , output_name = node . outputs [ 0 ] , axes = squeeze_axes , ) if add_static_reshape : builder . add_reshape_static ( name = node . name , input_name = node . inputs [ 0 ] , output_name = node . outputs [ 0 ] , output_shape = output_shape , ) else : builder . add_reshape_dynamic ( name = node . name , input_names = node . inputs , output_name = node . outputs [ 0 ] , )