def read_node(file_descr, graph, component_layer_map, layer_node_map):
    s = file_descr.readline()
    if (s == b'\n'):
        return False
    tokens = s.split(b' ')
    if (tokens[0] == b'input-node'):
        in_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        in_name = str(in_name).strip('b').replace("'", '')
        in_shape = mo_array([1, s[(s.find(b'dim=') + len(b'dim=')):].split(b' ')[0]], dtype=np.int)
        if (in_name not in layer_node_map):
            graph.add_node(in_name, name=in_name, kind='op', op='Parameter', parameters=None, shape=in_shape)
            layer_node_map[in_name] = in_name
        else:
            Node(graph, in_name)['op'] = 'Parameter'
            Node(graph, in_name)['shape'] = in_shape
    elif (tokens[0] == b'component-node'):
        layer_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        layer_name = str(layer_name).strip('b').replace("'", '')
        component_name = s[(s.find(b'component=') + len(b'component=')):].split(b' ')[0]
        if (layer_name not in layer_node_map):
            node_name = graph.unique_id(prefix=layer_name)
            graph.add_node(node_name, parameters=None, op=None, kind='op')
            layer_node_map[layer_name] = node_name
        else:
            node_name = layer_node_map[layer_name]
        if (component_name in component_layer_map):
            component_layer_map[component_name].append(node_name)
        else:
            component_layer_map[component_name] = [node_name]
        in_node_id = parse_input_for_node(s[(s.find(b'input=') + 6):], graph, layer_node_map)
        if (in_node_id != node_name):
            out_port = len(Node(graph, in_node_id).out_nodes())
            in_port = len(Node(graph, node_name).in_nodes())
            Node(graph, node_name).add_input_port(in_port)
            Node(graph, in_node_id).add_output_port(out_port, skip_if_exist=True)
            graph.add_edge(in_node_id, node_name, **create_edge_attrs(in_node_id, node_name, in_node_id, in_port, out_port))
    elif (tokens[0] == b'output-node'):
        layer_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        layer_name = str(layer_name).strip('b').replace("'", '')
        node_name = graph.unique_id(prefix=layer_name)
        graph.add_node(node_name, parameters=None, op='Identity', kind='op')
        out_name = graph.unique_id(prefix=(node_name + '_out'))
        graph.add_node(out_name, parameters=None, op='Result', kind='op')
        Node(graph, node_name).add_input_port(0)
        Node(graph, node_name).add_output_port(0)
        Node(graph, out_name).add_input_port(0)
        graph.add_edge(node_name, out_name, **create_edge_attrs(node_name, out_name, node_name))
        in_node_id = parse_input_for_node(s[(s.find(b'input=') + len(b'input=')):], graph, layer_node_map)
        out_port = len(Node(graph, in_node_id).out_nodes())
        Node(graph, in_node_id).add_output_port(out_port)
        graph.create_edge(Node(graph, in_node_id), Node(graph, node_name), out_port, 0, create_edge_attrs(in_node_id, node_name, in_node_id, 0, out_port))
        objective_type = s[(s.find(b'objective=') + 10):].split(b' ')[0].split(b'\n')[0]
        if (objective_type != b'linear'):
            raise Error('Unsupported objective-type for output {}'.format(node_name))
    elif (tokens[0] == b'dim-range-node'):
        layer_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        layer_name = str(layer_name).strip('b').replace("'", '')
        offset = int(s[(s.find(b'dim-offset=') + len(b'dim-offset=')):].split(b' ')[0])
        dim = int(s[(s.find(b'dim=') + len(b'dim=')):].split(b' ')[0])
        if (layer_name in layer_node_map):
            node_name = layer_node_map[layer_name]
            node = Node(graph, node_name)
            node['parameters'] = {'offset': mo_array([offset]), 'dim': mo_array([dim]), 'axis': mo_array([1])}
            node['op'] = 'Crop'
        else:
            node_name = graph.unique_id(prefix=layer_name)
            graph.add_node(node_name, parameters={'offset': mo_array([offset]), 'dim': mo_array([dim]), 'axis': mo_array([1])}, op='Crop', kind='op')
            layer_node_map[layer_name] = node_name
            node = Node(graph, node_name)
        in_node_id = parse_input_for_node(s[(s.find(b'input-node=') + len(b'input-node=')):], graph, layer_node_map)
        out_port = len(Node(graph, in_node_id).out_nodes())
        in_port = len(Node(graph, node_name).in_nodes())
        node.add_input_port(in_port)
        Node(graph, in_node_id).add_output_port(out_port)
        graph.create_edge(Node(graph, in_node_id), node, out_port, in_port, create_edge_attrs(in_node_id, node_name, in_node_id, in_port, out_port))
        for (o_n_name, params) in node.get_outputs():
            o_n = Node(graph, o_n_name)
            if (o_n['op'] == 'MemoryOffset'):
                o_n['parameters']['element_size'] = int64_array([1, dim])
    else:
        raise Error('Unsupported node specifier {}'.format(tokens[0]))
    return True
def read_node(file_descr, graph, component_layer_map, layer_node_map):
    s = file_descr.readline()
    if (s == b'\n'):
        return False
    tokens = s.split(b' ')
    if (tokens[0] == b'input-node'):
        in_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        in_name = str(in_name).strip('b').replace("'", )
        in_shape = mo_array([1, s[(s.find(b'dim=') + len(b'dim=')):].split(b' ')[0]], dtype=np.int)
        if (in_name not in layer_node_map):
            graph.add_node(in_name, name=in_name, kind='op', op='Parameter', parameters=None, shape=in_shape)
            layer_node_map[in_name] = in_name
        else:
            Node(graph, in_name)['op'] = 'Parameter'
            Node(graph, in_name)['shape'] = in_shape
    elif (tokens[0] == b'component-node'):
        layer_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        layer_name = str(layer_name).strip('b').replace("'", )
        component_name = s[(s.find(b'component=') + len(b'component=')):].split(b' ')[0]
        if (layer_name not in layer_node_map):
            node_name = graph.unique_id(prefix=layer_name)
            graph.add_node(node_name, parameters=None, op=None, kind='op')
            layer_node_map[layer_name] = node_name
        else:
            node_name = layer_node_map[layer_name]
        if (component_name in component_layer_map):
            component_layer_map[component_name].append(node_name)
        else:
            component_layer_map[component_name] = [node_name]
        in_node_id = parse_input_for_node(s[(s.find(b'input=') + 6):], graph, layer_node_map)
        if (in_node_id != node_name):
            out_port = len(Node(graph, in_node_id).out_nodes())
            in_port = len(Node(graph, node_name).in_nodes())
            Node(graph, node_name).add_input_port(in_port)
            Node(graph, in_node_id).add_output_port(out_port, skip_if_exist=True)
            graph.add_edge(in_node_id, node_name, **create_edge_attrs(in_node_id, node_name, in_node_id, in_port, out_port))
    elif (tokens[0] == b'output-node'):
        layer_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        layer_name = str(layer_name).strip('b').replace("'", )
        node_name = graph.unique_id(prefix=layer_name)
        graph.add_node(node_name, parameters=None, op='Identity', kind='op')
        out_name = graph.unique_id(prefix=(node_name + '_out'))
        graph.add_node(out_name, parameters=None, op='Result', kind='op')
        Node(graph, node_name).add_input_port(0)
        Node(graph, node_name).add_output_port(0)
        Node(graph, out_name).add_input_port(0)
        graph.add_edge(node_name, out_name, **create_edge_attrs(node_name, out_name, node_name))
        in_node_id = parse_input_for_node(s[(s.find(b'input=') + len(b'input=')):], graph, layer_node_map)
        out_port = len(Node(graph, in_node_id).out_nodes())
        Node(graph, in_node_id).add_output_port(out_port)
        graph.create_edge(Node(graph, in_node_id), Node(graph, node_name), out_port, 0, create_edge_attrs(in_node_id, node_name, in_node_id, 0, out_port))
        objective_type = s[(s.find(b'objective=') + 10):].split(b' ')[0].split(b'\n')[0]
        if (objective_type != b'linear'):
            raise Error('Unsupported objective-type for output {}'.format(node_name))
    elif (tokens[0] == b'dim-range-node'):
        layer_name = s[(s.find(b'name=') + len(b'name=')):].split(b' ')[0]
        layer_name = str(layer_name).strip('b').replace("'", )
        offset = int(s[(s.find(b'dim-offset=') + len(b'dim-offset=')):].split(b' ')[0])
        dim = int(s[(s.find(b'dim=') + len(b'dim=')):].split(b' ')[0])
        if (layer_name in layer_node_map):
            node_name = layer_node_map[layer_name]
            node = Node(graph, node_name)
            node['parameters'] = {'offset': mo_array([offset]), 'dim': mo_array([dim]), 'axis': mo_array([1])}
            node['op'] = 'Crop'
        else:
            node_name = graph.unique_id(prefix=layer_name)
            graph.add_node(node_name, parameters={'offset': mo_array([offset]), 'dim': mo_array([dim]), 'axis': mo_array([1])}, op='Crop', kind='op')
            layer_node_map[layer_name] = node_name
            node = Node(graph, node_name)
        in_node_id = parse_input_for_node(s[(s.find(b'input-node=') + len(b'input-node=')):], graph, layer_node_map)
        out_port = len(Node(graph, in_node_id).out_nodes())
        in_port = len(Node(graph, node_name).in_nodes())
        node.add_input_port(in_port)
        Node(graph, in_node_id).add_output_port(out_port)
        graph.create_edge(Node(graph, in_node_id), node, out_port, in_port, create_edge_attrs(in_node_id, node_name, in_node_id, in_port, out_port))
        for (o_n_name, params) in node.get_outputs():
            o_n = Node(graph, o_n_name)
            if (o_n['op'] == 'MemoryOffset'):
                o_n['parameters']['element_size'] = int64_array([1, dim])
    else:
        raise Error('Unsupported node specifier {}'.format(tokens[0]))
    return True