class_docstr: Performs Value Range Analysis on LoopBody's fx graph by calling BoundVars.run()
  It exposes the ranges of the nodes in the `bounds` variable
  
  Note. A current limitation of this analysis is that it just works on a per-loop basis.
  We should be able to propagate the bounds between across the whole graph. This may benefit
  the case a bounded variable is returned by a kernel and fed into another.
class_docstr_tok: ["Performs","Value","Range","Analysis","on","LoopBody","'s","fx","graph","by","calling","BoundVars.run","(",")","It","exposes","the","ranges","of","the","nodes","in","the","`","bounds","`","variable","Note",".","A","current","limitation","of","this","analysis","is","that","it","just","works","on","a","per-loop","basis",".","We","should","be","able","to","propagate","the","bounds","between","across","the","whole","graph",".","This","may","benefit","the","case","a","bounded","variable","is","returned","by","a","kernel","and","fed","into","another","."]
code: def __init__(self, loop_body: LoopBody) -> None:
      self.loop_body = loop_body
      self.replacement_vals = {
          k: ValueRanges(0, v - 1)
          if (isinstance(v, int) or v.is_number)
          else bound_sympy(v)
          for k, v in loop_body.var_ranges.items()
      }
      # avoid computing these values, pessimistically assume that they are unbounded
      self.unbounded_vars = dominated_nodes(
          node
          for node in self.loop_body.get_nodes()
          if node.target in ["load", "reduction", operator.getitem]
          or "masked_subblock" in node.target
      )
      # To access this variable call `get_bounds()`
      self._bounds: Dict[torch.fx.Node, ValueRanges] = {}
  
file_path: pytorch/torch/_inductor/bounds.py
imports: import operator
  from functools import partial
  from typing import Any, Callable, Dict
  from sympy import Expr
  import torch
  from torch.utils._sympy.value_ranges import bound_sympy, ValueRangeAnalysis, ValueRanges
  from .ir import InterpreterShim, LoopBody, LoopBodyBlock
  from .utils import cache_on_self, dominated_nodes
  from .virtualized import V
label_desc: Use image node_id 1 to create a new BoundVars object  with example: obj = BoundVars(loop_body)