(builder, node, graph, err)
Conversion
Conversion
Conversion
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
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