def _compile_blocks()

in tensorflow_fold/blocks/block_compiler.py [0:0]


  def _compile_blocks(self):
    """Compiles all blocks reachable via root."""
    # Input type must be PyObject or VoidType.
    if not isinstance(self.root.input_type, tdt.VoidType):
      self.root.set_input_type(tdt.PyObjectType())

    visited = set()
    stack = [self.root]

    def traverse_blocks(block):
      """Returns blocks and its descendants in post order."""
      # Check for cycles as an internal consistency check; it should
      # not be possible to create a cycle via the public API.
      if block in visited:
        raise ValueError('internal error; block %s forms a cycle; please file '
                         'a bug' % (block,))
      visited.add(block)
      post_order_blocks = []
      # These blocks appear in post-order (not counting links created by
      # forward declarations).
      for child in block.children:
        post_order_blocks += traverse_blocks(child)
      post_order_blocks.append(block)
      if block.is_forward_declaration_ref: stack.append(block.target_block)
      return post_order_blocks

    while stack:
      block = stack.pop()
      if block not in visited:
        block._validate(self._ctx)  # pylint: disable=protected-access
        for b in traverse_blocks(block):
          b._compile(self._ctx)  # pylint: disable=protected-access
          # Ensure that loom recognizes all necessary type shapes.
          for t in b.output_type.terminal_types():
            if isinstance(t, tdt.TensorType): self._ctx.register_tensor_type(t)