parameters: (
      builder, node, graph, err
  )
docstring: Conversion
docstring_summary: Conversion
docstring_tokens: Conversion
function: def _convert_reduce(
      builder, node, graph, err
  ):  # type: (NeuralNetworkBuilder, Node, Graph, ErrorHandling) -> None
  
      # CoreML reduction supported along: C, H, W, CHW, HW
  
      def _add_reduce(input_names, output_names, **kwargs):
          input_name = input_names[0]
          output_name = output_names[0]
  
          if "add_log" in kwargs and kwargs["add_log"]:
              if kwargs["node"].op_type == "ReduceLogSum":
                  output_name = output_names[0] + "_before_log"
  
          kwargs["builder"].add_reduce(
              name=kwargs["node"].name + "_" + output_name,
              input_name=input_name,
              output_name=output_name,
              axis=kwargs["coreml_axis"],
              mode=kwargs["mode"],
          )
  
          if "add_log" in kwargs and kwargs["add_log"]:
              if node.op_type == "ReduceLogSum":
                  kwargs["builder"].add_unary(
                      name=kwargs["node"].name + "_log",
                      input_name=output_name,
                      output_name=output_names[0],
                      mode="log",
                  )
  
      """
      Conversion
      """
      input_name = node.inputs[0]
      output_name = node.outputs[0]
  
      axes = node.attrs.get("axes", None)
      keepdims = node.attrs.get("keepdims", 1)
  
      if axes is None:
          if node.inputs[0] in graph.onnx_coreml_shape_mapping:
              axes = range(0, len(graph.onnx_coreml_shape_mapping[node.inputs[0]]))
          elif node.inputs[0] in graph.shape_dict:
              axes = range(0, len(graph.shape_dict[node.inputs[0]]))
          else:
              return err.unsupported_op_configuration(
                  builder, node, graph, "Shape inference failed for reduce op"
              )
  
      if node.op_type == "ReduceMean":
          mode = "avg"
      elif node.op_type == "ReduceL1":
          mode = "L1"
      elif node.op_type == "ReduceL2":
          mode = "L2"
      elif node.op_type == "ReduceLogSum":
          mode = "sum"
      elif node.op_type == "ReduceMax":
          mode = "max"
      elif node.op_type == "ReduceMin":
          mode = "min"
      elif node.op_type == "ReduceProd":
          mode = "prod"
      elif node.op_type == "ReduceSum":
          mode = "sum"
      elif node.op_type == "ReduceSumSquare":
          mode = "sumsquare"
      else:
          return err.unsupported_op_configuration(builder, node, graph, "Unsupported op")
  
      if _is_input_shape_mapping_defined(node, graph):
          mapp = graph.onnx_coreml_shape_mapping[node.inputs[0]]
          coreml_axis = ""
          for ind in [["S", "B", "C", "H", "W"][mapp[i]] for i in axes]:
              coreml_axis += ind
          coreml_axis = "".join(sorted(coreml_axis))
      else:
          coreml_axis = _get_coreml_axis(axes, builder, node, graph, err)
  
      if coreml_axis in ["C", "H", "W", "HW", "CHW"]:
          _add_reduce(
              [input_name],
              [output_name],
              builder=builder,
              node=node,
              coreml_axis=coreml_axis,
              mode=mode,
              add_log=True,
          )
      else:
          if node.op_type in ["ReduceMean"]:
              return err.unsupported_op_configuration(
                  builder,
                  node,
                  graph,
                  "Unable to translate axes attribute to CoreML axis parameter for %s"
                  % axes,
              )
          n = len(coreml_axis)
          for i, ax in enumerate(coreml_axis):
              if ax not in ["C", "H", "W"]:
                  return err.unsupported_op_configuration(
                      builder,
                      node,
                      graph,
                      "Unable to translate axes attribute to CoreML axis parameter for %s"
                      % axes,
                  )
              else:
                  if i == 0:
                      iname = input_name
                  else:
                      iname = input_name + str(i)
                  if i == n - 1:
                      oname = output_name
                  else:
                      oname = input_name + str(i + 1)
                  if i < n - 1:
                      _add_reduce(
                          [iname],
                          [oname],
                          builder=builder,
                          node=node,
                          coreml_axis=ax,
                          mode=mode,
                          add_log=False,
                      )
                  else:
                      _add_reduce(
                          [iname],
                          [oname],
                          builder=builder,
                          node=node,
                          coreml_axis=ax,
                          mode=mode,
                          add_log=True,
                      )
  
      """
      update output shape map
      """
      if _is_input_shape_mapping_defined(node, graph):
          mapp = graph.onnx_coreml_shape_mapping[node.inputs[0]]
          if keepdims == 1:
              graph.onnx_coreml_shape_mapping[node.outputs[0]] = mapp
          else:
              out_mapp = []
              for i, m in enumerate(mapp):
                  if i not in axes:
                      out_mapp.append(m)
              if len(out_mapp) == 0:
                  out_mapp = [2]
              graph.onnx_coreml_shape_mapping[node.outputs[0]] = out_mapp
function_tokens: def _convert_reduce ( builder , node , graph , err ) : # type: (NeuralNetworkBuilder, Node, Graph, ErrorHandling) -> None # CoreML reduction supported along: C, H, W, CHW, HW def _add_reduce ( input_names , output_names , * * kwargs ) : input_name = input_names [ 0 ] output_name = output_names [ 0 ] if "add_log" in kwargs and kwargs [ "add_log" ] : if kwargs [ "node" ] . op_type == "ReduceLogSum" : output_name = output_names [ 0 ] + "_before_log" kwargs [ "builder" ] . add_reduce ( name = kwargs [ "node" ] . name + "_" + output_name , input_name = input_name , output_name = output_name , axis = kwargs [ "coreml_axis" ] , mode = kwargs [ "mode" ] , ) if "add_log" in kwargs and kwargs [ "add_log" ] : if node . op_type == "ReduceLogSum" : kwargs [ "builder" ] . add_unary ( name = kwargs [ "node" ] . name + "_log" , input_name = output_name , output_name = output_names [ 0 ] , mode = "log" , ) input_name = node . inputs [ 0 ] output_name = node . outputs [ 0 ] axes = node . attrs . get ( "axes" , None ) keepdims = node . attrs . get ( "keepdims" , 1 ) if axes is None : if node . inputs [ 0 ] in graph . onnx_coreml_shape_mapping : axes = range ( 0 , len ( graph . onnx_coreml_shape_mapping [ node . inputs [ 0 ] ] ) ) elif node . inputs [ 0 ] in graph . shape_dict : axes = range ( 0 , len ( graph . shape_dict [ node . inputs [ 0 ] ] ) ) else : return err . unsupported_op_configuration ( builder , node , graph , "Shape inference failed for reduce op" ) if node . op_type == "ReduceMean" : mode = "avg" elif node . op_type == "ReduceL1" : mode = "L1" elif node . op_type == "ReduceL2" : mode = "L2" elif node . op_type == "ReduceLogSum" : mode = "sum" elif node . op_type == "ReduceMax" : mode = "max" elif node . op_type == "ReduceMin" : mode = "min" elif node . op_type == "ReduceProd" : mode = "prod" elif node . op_type == "ReduceSum" : mode = "sum" elif node . op_type == "ReduceSumSquare" : mode = "sumsquare" else : return err . unsupported_op_configuration ( builder , node , graph , "Unsupported op" ) if _is_input_shape_mapping_defined ( node , graph ) : mapp = graph . onnx_coreml_shape_mapping [ node . inputs [ 0 ] ] coreml_axis = "" for ind in [ [ "S" , "B" , "C" , "H" , "W" ] [ mapp [ i ] ] for i in axes ] : coreml_axis += ind coreml_axis = "" . join ( sorted ( coreml_axis ) ) else : coreml_axis = _get_coreml_axis ( axes , builder , node , graph , err ) if coreml_axis in [ "C" , "H" , "W" , "HW" , "CHW" ] : _add_reduce ( [ input_name ] , [ output_name ] , builder = builder , node = node , coreml_axis = coreml_axis , mode = mode , add_log = True , ) else : if node . op_type in [ "ReduceMean" ] : return err . unsupported_op_configuration ( builder , node , graph , "Unable to translate axes attribute to CoreML axis parameter for %s" % axes , ) n = len ( coreml_axis ) for i , ax in enumerate ( coreml_axis ) : if ax not in [ "C" , "H" , "W" ] : return err . unsupported_op_configuration ( builder , node , graph , "Unable to translate axes attribute to CoreML axis parameter for %s" % axes , ) else : if i == 0 : iname = input_name else : iname = input_name + str ( i ) if i == n - 1 : oname = output_name else : oname = input_name + str ( i + 1 ) if i < n - 1 : _add_reduce ( [ iname ] , [ oname ] , builder = builder , node = node , coreml_axis = ax , mode = mode , add_log = False , ) else : _add_reduce ( [ iname ] , [ oname ] , builder = builder , node = node , coreml_axis = ax , mode = mode , add_log = True , ) """
      update output shape map
      """ if _is_input_shape_mapping_defined ( node , graph ) : mapp = graph . onnx_coreml_shape_mapping [ node . inputs [ 0 ] ] if keepdims == 1 : graph . onnx_coreml_shape_mapping [ node . outputs [ 0 ] ] = mapp else : out_mapp = [ ] for i , m in enumerate ( mapp ) : if i not in axes : out_mapp . append ( m ) if len ( out_mapp ) == 0 : out_mapp = [ 2 ] graph . onnx_coreml_shape_mapping [ node . outputs [ 0 ] ] = out_mapp