class_docstr: Tracks the current if/else scope with the path that we took. Captures the used and produced
  data nodes, applying the necessary splits based on the scope level where they were produced
  and where they are used.
docstr: The data_node was produced (or last accessed as via split) in scope earlier than the
  current one, traverse the scopes between that level and current one, and insert split nodes.
  
  Parameters
  ----------
  data_node : DataNode
      The data node that we want to use in the current scope.
  stack_level : int
      Stack level where the data_node was last "seen".
  
  Returns
  -------
  DataNode
      New node that can be used in current branch and scope.
docstr_tok: ["The","data_node","was","produced","(","or","last","accessed","as","via","split",")","in","scope","earlier","than","the","current","one",",","traverse","the","scopes","between","that","level","and","current","one",",","and","insert","split","nodes",".","Parameters","--","--","--","--","--","data_node",":","DataNode","The","data","node","that","we","want","to","use","in","the","current","scope",".","stack_level",":","int","Stack","level","where","the","data_node","was","last","``","seen","''",".","Returns","--","--","--","-","DataNode","New","node","that","can","be","used","in","current","branch","and","scope","."]
code: def _realize_split(self, data_node, stack_level):
      """The data_node was produced (or last accessed as via split) in scope earlier than the
      current one, traverse the scopes between that level and current one, and insert split nodes.
  
      Parameters
      ----------
      data_node : DataNode
          The data node that we want to use in the current scope.
      stack_level : int
          Stack level where the data_node was last "seen".
  
      Returns
      -------
      DataNode
          New node that can be used in current branch and scope.
      """
      assert 0 <= stack_level and stack_level < self.stack_depth() - 1
      produced_data_node = self._stack[stack_level].get(data_node)
      bottom = self._stack[: stack_level + 1]
      top = self._stack[stack_level + 1 :]
      self._stack = bottom
      while top:
          current_entry = top.pop(0)
          predicate = current_entry.predicate
  
          # Do not automatically register the outputs in the current scope, we track them below
          # in their respective branches.
          logging.log(
              9,
              (
                  f"{self._indent()}[IF] Inserting split"
                  f" at {self.stack_depth() -1}:"
                  f" split({produced_data_node}, predicate={predicate}."
              ),
          )
          self._is_registration_allowed = False
          true_node, false_node = fn._conditional.split(
              produced_data_node, predicate=predicate, _if_stmt=True
          )
          self._is_registration_allowed = True
  
          # Record the result of splitting the `data_node` that we are trying to look up
          # (short-cut for consecutive lookups)
          current_entry.add_split(
              data_node, produced_data_node, true_node, false_node
          )
          if current_entry.branch == _Branch.TrueBranch:
              produced_data_node = true_node
          else:
              produced_data_node = false_node
          self._stack.append(current_entry)
      return produced_data_node
  
imports: from nvidia.dali import _autograph
  from nvidia.dali.data_node import DataNode
  from nvidia.dali import fn
  from nvidia.dali._autograph.utils import ag_logging
  from nvidia.dali._autograph.operators import variables
  from contextlib import contextmanager
  from enum import Enum
  import tree
label_desc: Use image node_id 7 for calling the _ConditionStack obj's underlying member method code with example usage: obj._realize_split(data_node, stack_level) and returns: produced_data_node