class_docstr: An inference block combining multiple perception blocks into one prediction module.
          Conditions on using the InferenceBlock object:
              1. All keys of the perception_blocks dictionary have to be unique
              2. All out_keys used when creating the blocks have to be unique
              3. All block keys in the perception_blocks dict have to sub-strings of all their corresponding out_keys
              4. The given in_keys should be a subset of the inputs of the computational graph
              5. The given out_keys should be a subset of the outputs of the computational graph
  
  :param in_keys: Keys identifying the input tensors.
  :param out_keys: Keys identifying the output tensors.
  :param in_shapes: List of input shapes.
  :param perception_blocks: Dictionary of perception blocks.
class_docstr_tok: ["An","inference","block","combining","multiple","perception","blocks","into","one","prediction","module",".","Conditions","on","using","the","InferenceBlock","object",":","1",".","All","keys","of","the","perception_blocks","dictionary","have","to","be","unique","2",".","All","out_keys","used","when","creating","the","blocks","have","to","be","unique","3",".","All","block","keys","in","the","perception_blocks","dict","have","to","sub-strings","of","all","their","corresponding","out_keys","4",".","The","given","in_keys","should","be","a","subset","of","the","inputs","of","the","computational","graph","5",".","The","given","out_keys","should","be","a","subset","of","the","outputs","of","the","computational","graph",":","param","in_keys",":","Keys","identifying","the","input","tensors",".",":","param","out_keys",":","Keys","identifying","the","output","tensors",".",":","param","in_shapes",":","List","of","input","shapes",".",":","param","perception_blocks",":","Dictionary","of","perception","blocks","."]
docstr: Build the execution graph for computing the forward path through the network.
  
  :param computed_keys: The named tensors computed up until this point.
  :param execution_plan: The order in which to process the blocks in the forward pass
  :return: The order in which to process the blocks in the forward pass
docstr_tok: ["Build","the","execution","graph","for","computing","the","forward","path","through","the","network",".",":","param","computed_keys",":","The","named","tensors","computed","up","until","this","point",".",":","param","execution_plan",":","The","order","in","which","to","process","the","blocks","in","the","forward","pass",":","return",":","The","order","in","which","to","process","the","blocks","in","the","forward","pass"]
code: def _build_execution_graph(
      self,
      computed_keys: List[str],
      execution_plan: Dict[int, List[str]],
  ) -> Dict[int, List[str]]:
      """Build the execution graph for computing the forward path through the network.
  
      :param computed_keys: The named tensors computed up until this point.
      :param execution_plan: The order in which to process the blocks in the forward pass
      :return: The order in which to process the blocks in the forward pass
      """
      computed_blocks = sum(execution_plan.values(), [])
      current_step_blocks = []
      current_step_out_keys = []
      for block_key, block in self.perception_blocks.items():
          if block_key not in computed_blocks:
              if all(
                  [in_key in computed_keys for in_key in block.in_keys]
              ):
                  current_step_blocks.append(block_key)
                  current_step_out_keys += block.out_keys
  
      execution_plan[len(execution_plan.keys())] = current_step_blocks
      computed_keys += current_step_out_keys
  
      if all([out_key in computed_keys for out_key in self.out_keys]):
          return execution_plan
      else:
          return self._build_execution_graph(
              computed_keys, execution_plan
          )
  
imports: import os
  import pickle
  from typing import Union, List, Dict, Optional, Sequence, Tuple
  import networkx
  import torch
  from matplotlib import pyplot
  from torch import nn
  from maze.core.annotations import override
  from maze.perception.blocks.base import PerceptionBlock
label_desc: Use image node_id 4 for calling the InferenceBlock obj's underlying member method code with example usage: obj._build_execution_graph(computed_keys, execution_plan) and returns: execution_plan, self