parameters: (file_descr, graph: Graph, prev_layer_id)
return_statement: return concat_id
docstring: Load ParallelComponent of the Kaldi model.
      ParallelComponent contains parallel nested networks.
      VariadicSplit is inserted before nested networks.
      Outputs of nested networks concatenate with layer Concat.
  
      :param file_descr: descriptor of the model file
      :param graph: graph with the topology.
      :param prev_layer_id: id of the input layers for parallel component layer
      :return: id of the concat layer - last layer of the parallel component layers
docstring_summary: Load ParallelComponent of the Kaldi model.
      ParallelComponent contains parallel nested networks.
      VariadicSplit is inserted before nested networks.
      Outputs of nested networks concatenate with layer Concat.
docstring_tokens: Load ParallelComponent of the Kaldi model . ParallelComponent contains parallel nested networks . VariadicSplit is inserted before nested networks . Outputs of nested networks concatenate with layer Concat .
function: def load_parallel_component(file_descr, graph: Graph, prev_layer_id):
      """
      Load ParallelComponent of the Kaldi model.
      ParallelComponent contains parallel nested networks.
      VariadicSplit is inserted before nested networks.
      Outputs of nested networks concatenate with layer Concat.
  
      :param file_descr: descriptor of the model file
      :param graph: graph with the topology.
      :param prev_layer_id: id of the input layers for parallel component layer
      :return: id of the concat layer - last layer of the parallel component layers
      """
      nnet_count = read_token_value(file_descr, b'<NestedNnetCount>')
      log.debug('Model contains parallel component with {} nested networks'.format(nnet_count))
  
      split_points = []
      outputs = []
      inputs = []
  
      for i in range(nnet_count):
          read_token_value(file_descr, b'<NestedNnet>')
          collect_until_token(file_descr, b'<Nnet>')
          g = Graph()
          load_kalid_nnet1_model(g, file_descr, 'Nested_net_{}'.format(i))
  
          # input to nnet1 models is of a rank 1 but we also insert batch_size to 0th axis
          # 1st axis contains input_size of the nested subnetwork
          # we split input from the main network to subnetworks
          input_node = Node(g, 'Parameter')
          split_points.append(input_node['shape'][1])
          g.remove_node(input_node.id)
  
          mapping = {node: graph.unique_id(node) for node in g.nodes(data=False) if node in graph}
          g = nx.relabel_nodes(g, mapping)
          for val in mapping.values():
              g.node[val]['name'] = val
          graph.add_nodes_from(g.nodes(data=True))
          graph.add_edges_from(g.edges(data=True))
          sorted_nodes = tuple(nx.topological_sort(g))
  
          outputs.append(Node(graph, sorted_nodes[-1]))
          inputs.append(Node(graph, sorted_nodes[0]))
  
      split_id = graph.unique_id(prefix='NestedNets/VariadicSplit')
      attrs = {'out_ports_count': nnet_count, 'size_splits': split_points, 'axis': 1, 'name': split_id}
      variadic_split_node = AttributedVariadicSplit(graph, attrs).create_node()
      prev_layer_node = Node(graph, prev_layer_id)
      prev_layer_node.add_output_port(0)
      graph.create_edge(prev_layer_node, variadic_split_node, 0, 0, create_edge_attrs(prev_layer_id, variadic_split_node.id, prev_layer_id))
  
      concat_id = graph.unique_id(prefix='Concat')
      graph.add_node(concat_id, parameters=None, op='concat', kind='op')
      concat_node = Node(graph, concat_id)
  
      # Connect each output of variadic_split_node to each subnetwork's inputs in ParallelComponent
      # and each subnetwork's output to concat_node
      for i, (input_node, output_node) in enumerate(zip(inputs, outputs)):
          output_node.add_output_port(0)
          concat_node.add_input_port(i)
          graph.create_edge(output_node, concat_node, 0, i, create_edge_attrs(output_node.id, concat_id, output_node.id, i, 0))
          graph.create_edge(variadic_split_node, input_node, i, 0, create_edge_attrs(variadic_split_node.id, input_node.id, variadic_split_node.id, 0, i))
      return concat_id
function_tokens: def load_parallel_component ( file_descr , graph : Graph , prev_layer_id ) : nnet_count = read_token_value ( file_descr , b'<NestedNnetCount>' ) log . debug ( 'Model contains parallel component with {} nested networks' . format ( nnet_count ) ) split_points = [ ] outputs = [ ] inputs = [ ] for i in range ( nnet_count ) : read_token_value ( file_descr , b'<NestedNnet>' ) collect_until_token ( file_descr , b'<Nnet>' ) g = Graph ( ) load_kalid_nnet1_model ( g , file_descr , 'Nested_net_{}' . format ( i ) ) # input to nnet1 models is of a rank 1 but we also insert batch_size to 0th axis # 1st axis contains input_size of the nested subnetwork # we split input from the main network to subnetworks input_node = Node ( g , 'Parameter' ) split_points . append ( input_node [ 'shape' ] [ 1 ] ) g . remove_node ( input_node . id ) mapping = { node : graph . unique_id ( node ) for node in g . nodes ( data = False ) if node in graph } g = nx . relabel_nodes ( g , mapping ) for val in mapping . values ( ) : g . node [ val ] [ 'name' ] = val graph . add_nodes_from ( g . nodes ( data = True ) ) graph . add_edges_from ( g . edges ( data = True ) ) sorted_nodes = tuple ( nx . topological_sort ( g ) ) outputs . append ( Node ( graph , sorted_nodes [ - 1 ] ) ) inputs . append ( Node ( graph , sorted_nodes [ 0 ] ) ) split_id = graph . unique_id ( prefix = 'NestedNets/VariadicSplit' ) attrs = { 'out_ports_count' : nnet_count , 'size_splits' : split_points , 'axis' : 1 , 'name' : split_id } variadic_split_node = AttributedVariadicSplit ( graph , attrs ) . create_node ( ) prev_layer_node = Node ( graph , prev_layer_id ) prev_layer_node . add_output_port ( 0 ) graph . create_edge ( prev_layer_node , variadic_split_node , 0 , 0 , create_edge_attrs ( prev_layer_id , variadic_split_node . id , prev_layer_id ) ) concat_id = graph . unique_id ( prefix = 'Concat' ) graph . add_node ( concat_id , parameters = None , op = 'concat' , kind = 'op' ) concat_node = Node ( graph , concat_id ) # Connect each output of variadic_split_node to each subnetwork's inputs in ParallelComponent # and each subnetwork's output to concat_node for i , ( input_node , output_node ) in enumerate ( zip ( inputs , outputs ) ) : output_node . add_output_port ( 0 ) concat_node . add_input_port ( i ) graph . create_edge ( output_node , concat_node , 0 , i , create_edge_attrs ( output_node . id , concat_id , output_node . id , i , 0 ) ) graph . create_edge ( variadic_split_node , input_node , i , 0 , create_edge_attrs ( variadic_split_node . id , input_node . id , variadic_split_node . id , 0 , i ) ) return concat_id