def parse_cfg()

in tools/importers/darknet/darknet_to_ell.py [0:0]


def parse_cfg(filename):
    """Parses a Darknet .cfg file and returns a list of layers. Each layer has
       properties denoting type, shape of input and outputs, padding requirements
       and anything else needed to construct up the relevant ELL layers"""
    with open(filename) as f:
        content = f.read()

    class DarknetConfigDict(OrderedDict):
        def __init__(self, **kwargs):
            OrderedDict.__init__(self, **kwargs)
            self.__keysuffixes = {}

        def __setitem__(self, key, value):
            if isinstance(value, dict):
                suffix = self.__keysuffixes.setdefault(key, 0)
                self.__keysuffixes[key] += 1
                key += "_" + str(suffix)
            OrderedDict.__setitem__(self, key, value)

    config = ConfigParser(dict_type=DarknetConfigDict, strict=False)
    config.read_string(content)
    network = []
    for section in config._sections:
        layer_desc = {'type': section[:section.rfind('_')]}
        layer_desc.update(config._sections[section])
        network.append(layer_desc)

    def print_layer(layer):
        _logger = logger.get()
        PRETTY_TYPE_MAP = {
            "convolutional": "BinaryConvolution" if layer.get("xnor") == 1 else
                             "Convolution",
            "connected": "FullyConnected",
            "maxpool": "MaxPooling",
            "avgpool": "AveragePooling",
            "softmax": "Softmax",
            "region": "RegionDetection"
        }
        pretty_type = PRETTY_TYPE_MAP.get(layer.get("type"))
        if not pretty_type:
            return
        _logger.info(("{} :  {h}x{w}x{c}  ->  {out_h}x{out_w}x{out_c}"
                     " | input padding {inputPadding}  output padding {outputPadding}"
                      ).format(pretty_type, **layer))

    # add extra information needed, size calculations and properties like padding
    for i, layer in enumerate(network):
        if layer['type'] == 'net':
            layer['h'] = int(layer['height'])
            layer['w'] = int(layer['width'])
            layer['c'] = int(layer['channels'])
            layer['out_h'] = int(layer['height'])
            layer['out_w'] = int(layer['width'])
            layer['out_c'] = int(layer['channels'])
        elif layer['type'] == 'crop':
            layer['c'] = network[i - 1]['out_c']
            layer['h'] = network[i - 1]['out_h']
            layer['w'] = network[i - 1]['out_w']
            layer['out_h'] = layer['crop_height']
            layer['out_w'] = layer['crop_width']
            layer['out_c'] = network[i - 1]['out_c']
        elif layer['type'] == 'convolutional':
            if 'pad' not in layer:
                layer['pad'] = 0
                layer['padding'] = 0
            elif 'padding' not in layer:
                if ('pad' in layer):
                    if (int(layer['pad']) == 0):
                        layer['padding'] = 0
                    else:
                        layer['padding'] = int((int(layer['size']) - 1) / 2)
                else:
                    layer['padding'] = int((int(layer['size']) - 1) / 2)
            layer['h'] = int(network[i - 1]['out_h'])
            layer['w'] = int(network[i - 1]['out_w'])
            layer['c'] = int(network[i - 1]['out_c'])
            layer['out_h'] = int(convolutional_out_height(layer))
            layer['out_w'] = int(convolutional_out_width(layer))
            layer['out_c'] = int(layer['filters'])
        elif layer['type'] == 'connected':
            layer['h'] = network[i - 1]['out_h']
            layer['w'] = network[i - 1]['out_w']
            layer['c'] = network[i - 1]['out_c']
            layer['inputs'] = int(layer['h']) * int(layer['w']) * int(layer['c'])
            layer['out_w'] = 1
            layer['out_h'] = 1
            layer['out_c'] = int(layer['output'])
        elif layer['type'] == 'maxpool':
            if 'padding' not in layer:
                layer['padding'] = int((int(layer['size']) - 1) / 2)
            layer['h'] = int(network[i - 1]['out_h'])
            layer['w'] = int(network[i - 1]['out_w'])
            layer['c'] = int(network[i - 1]['out_c'])
            layer['out_h'] = int(((int(layer['h'])) + 2 * int(layer['padding'])) / int(layer['stride']))
            layer['out_w'] = int(((int(layer['w'])) + 2 * int(layer['padding'])) / int(layer['stride']))
            layer['out_c'] = layer['c']
        elif layer['type'] == 'avgpool':
            layer['c'] = network[i - 1]['out_c']
            layer['out_c'] = layer['c']
            layer['out_h'] = 1
            layer['out_w'] = 1
            layer['h'] = network[i - 1]['out_h']
            layer['w'] = network[i - 1]['out_w']
            layer['padding'] = 0
            # Darknet's average pooling is across an entire layer. Fix up stride and size so ELL can behave that way.
            layer['size'] = layer["w"]
            layer['stride'] = layer["w"]
        elif layer['type'] == 'softmax':
            layer['c'] = network[i - 1]['out_c']
            layer['h'] = network[i - 1]['out_h']
            layer['w'] = network[i - 1]['out_w']
            layer['out_c'] = layer['c']
            layer['out_h'] = layer['h']
            layer['out_w'] = layer['w']
        elif layer['type'] == 'region':
            layer['c'] = network[i - 1]['out_c']
            layer['h'] = network[i - 1]['out_h']
            layer['w'] = network[i - 1]['out_w']
            layer['out_c'] = network[i - 1]['out_c']
            layer['out_h'] = network[i - 1]['out_h']
            layer['out_w'] = network[i - 1]['out_w']
        else:
            layer['c'] = network[i - 1]['out_c']
            layer['h'] = network[i - 1]['out_h']
            layer['w'] = network[i - 1]['out_w']
            layer['out_c'] = network[i - 1]['out_c']
            layer['out_h'] = network[i - 1]['out_h']
            layer['out_w'] = network[i - 1]['out_w']

    # Do another pass, setting input/output shape and outpadding to next layer's padding
    # Set the ELL padding scheme and shape parameters
    for i, layer in enumerate(network):
        if 'padding' not in layer:
            layer['inputPadding'] = 0
            if layer['type'] == 'maxpool':
                layer['inputPaddingScheme'] = ell.neural.PaddingScheme.min
            else:
                layer['inputPaddingScheme'] = ell.neural.PaddingScheme.zeros
        else:
            layer['inputPadding'] = int(layer['padding'])
            if layer['type'] == 'maxpool':
                layer['inputPaddingScheme'] = ell.neural.PaddingScheme.min
            else:
                layer['inputPaddingScheme'] = ell.neural.PaddingScheme.zeros
        layer['inputShape'] = ell.math.TensorShape(
            int(layer['h']) + 2 * int(layer['inputPadding']),
            int(layer['w']) + 2 * int(layer['inputPadding']),
            int(layer['c']))

        if i < (len(network) - 1):
            nextLayer = network[i + 1]
            if 'padding' not in nextLayer:
                layer['outputPadding'] = 0
            else:
                layer['outputPadding'] = int(nextLayer['padding'])

            if nextLayer['type'] == 'maxpool':
                layer['outputPaddingScheme'] = ell.neural.PaddingScheme.min
            else:
                layer['outputPaddingScheme'] = ell.neural.PaddingScheme.zeros

            layer['outputShape'] = ell.math.TensorShape(
                int(layer['out_h']) + 2 * int(layer['outputPadding']),
                int(layer['out_w']) + 2 * int(layer['outputPadding']),
                int(layer['out_c']))
            layer['outputShapeMinusPadding'] = ell.math.TensorShape(
                int(layer['out_h']),
                int(layer['out_w']),
                int(layer['out_c']))
        else:
            layer['outputPadding'] = 0
            layer['outputPaddingScheme'] = ell.neural.PaddingScheme.zeros
            layer['outputShape'] = ell.math.TensorShape(int(layer['out_h']), int(layer['out_w']), int(layer['out_c']))
            layer['outputShapeMinusPadding'] = ell.math.TensorShape(
                int(layer['out_h']),
                int(layer['out_w']),
                int(layer['out_c']))

        print_layer(layer)

    return network