code: def bisect(shape_env):
      from torch.fx.experimental.symbolic_shapes import (
          ShapeEnv,
          SHAPEENV_EVENT_KEY,
          CURRENT_NODE_KEY,
      )
      from torch.fx.experimental.recording import (
          FakeTensorMeta,
          ShapeEnvEvent,
          replay_shape_env_events,
      )
  
      events = shape_env.events
  
      # Retrieves the ShapeEnvEvent associated with node.
      def get_node_event(node: torch.fx.Node) -> ShapeEnvEvent:
          assert SHAPEENV_EVENT_KEY in node.meta
          return events[node.meta[SHAPEENV_EVENT_KEY]]
  
      # Creates a new instance of fake, but updating every symbolic value's ShapeEnv
      # reference to the one given as argument.
      #
      # This is needed so as not to simplify a symbolic expression using a ShapeEnv
      # "from the future", where it may have a different set of replacements.
      def new_with_shape_env(shape_env: ShapeEnv, fake) -> Any:
          if isinstance(fake, int):
              return fake
          if isinstance(fake, torch.SymInt):
              return torch.SymInt(fake.node.with_shape_env(shape_env))
          assert isinstance(fake, FakeTensorMeta)
          return FakeTensorMeta(
              tuple(
                  new_with_shape_env(shape_env, s) for s in fake.size()
              ),
              tuple(
                  new_with_shape_env(shape_env, s)
                  for s in fake.stride()
              ),
              new_with_shape_env(shape_env, fake.storage_offset()),
              fake.is_nested,
          )
  
      # Checks whether the given shape_env fails when produce_guards is called.
      def check_shapeenv_fails(
          shape_env: ShapeEnv, tracked_fakes: Optional[List[Any]]
      ) -> Optional[ValidationException]:
          assert tracked_fakes is not None
          try:
              # This produce_guards call is a best-effort replication, since we
              # don't populate EqualityConstraint list. Reason: we would also have
              # to save OutputGraph.tracked_fakes_id_to_source.
              shape_env.produce_guards(
                  [
                      new_with_shape_env(shape_env, a.fake)
                      for a in tracked_fakes
                  ],
                  [a.source for a in tracked_fakes],
                  input_contexts=[
                      a.symbolic_context for a in tracked_fakes
                  ],
              )
              return None
          except ValidationException as e:
              return e
  
      # Checks whether the ShapeEnv reconstructed by replaying the events until
      # node is created fails when produce_guards is called.
      def check_node_fails(
          node: torch.fx.Node,
      ) -> Optional[ValidationException]:
          number = node.meta[SHAPEENV_EVENT_KEY]
          # Reconstruct shape_env until the event at event_number.
          shape_env = replay_shape_env_events(events[: number + 1])
          shape_env.graph.lint()
          return check_shapeenv_fails(
              shape_env, events[number].tracked_fakes
          )
  
      last_exception = check_shapeenv_fails(
          shape_env, shape_env.snapshot_tracked_fakes()
      )
  
      if not last_exception:
          # We don't actually fail due to a produce_guards call.
          # Stop and don't bisect.
          log.info("translation validation succeeded: no errors found.")
          return
  
      if (
          not shape_env.should_record_events
          or config.translation_validation_no_bisect
      ):
          # Bisection is off.
          # Return the last ValidationException we got.
          raise last_exception
  
      # Cache the raised exception (if any) at each bisection point.
      exception = {}
  
      # Bisection happens on the assertion nodes of the recorded FX graph for
      # dynamic shapes.
      assert_nodes = [
          node
          for node in shape_env.graph.nodes
          if node.target == torch._assert
      ]
  
      # Preparing the indices for binary search.
      left, mid, right = 0, 0, len(assert_nodes) - 1
  
      while left < right:
          mid = (left + right) // 2
  
          node = assert_nodes[mid]
          log.debug("bisecting at %s: %s", mid, get_node_event(node))
  
          # Check whether the new shape_env raises a ValidationException or not.
          exception[mid] = check_node_fails(node)
  
          if exception[mid]:
              right = mid
          else:
              left = mid + 1
  
      assert left in exception and isinstance(
          exception[left], ValidationException
      )
  
      node = assert_nodes[left]
      event = get_node_event(node)
  
      if event.is_evaluate_expr():
          failed_action = "evaluating"
      else:
          assert (
              event.is_defer_runtime_assert()
          ), f"unexpected event type: {event}"
          failed_action = "adding runtime assert"
  
      args = event.args
      assert args is not None
      assert len(args) >= 2, (
          f"bisecting expects {event.name} to have at least 2 positional arguments. "
          f"Got: {len(args)}"
      )
      assert isinstance(args[1], sympy.Basic), (
          f"bisecting expects {event.name} to have a SymPy expression as its second argument. "
          f"Got: {type(args[1])}"
      )
  
      raise BisectValidationException(
          exception[left],
          expr=args[1],
          failed_action=failed_action,
          traced_node=node.meta[CURRENT_NODE_KEY],
      )
  
imports: import functools
  import logging
  import math
  import operator
  import sympy
  import builtins
  from dataclasses import dataclass
  from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
  import torch
  import torch.fx
  import torch.fx.traceback
  from torch._dynamo.exc import TorchDynamoException
  from torch.fx.node import Argument, Target
  from torch.utils._sympy.interp import sympy_interp
  from torch.fx.experimental import _config
label_desc: Use image node_id 4 for calling a global function with example usage: bisect(shape_env) and returns: events, FakeTensorMeta, check_shapeenv_fails, fake, torch, None, e