docstr: Wrapper around functools.lru_cache that clears when replacements
  has been invalidated.
code: def _lru_cache(self, fn, maxsize=None):
      """
      Wrapper around functools.lru_cache that clears when replacements
      has been invalidated.
      """
      fn_cache = functools.lru_cache(maxsize)(fn)
      prior_len = len(self.replacements)
  
      @functools.wraps(fn)
      def wrapper(*args, **kwargs):
          nonlocal prior_len
          if prior_len != len(self.replacements):
              prior_len = len(self.replacements)
              fn_cache.cache_clear()
          return fn_cache(*args, **kwargs)
  
      return wrapper
  
imports: import functools
  import itertools
  import logging
  from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union
  import sympy
  from sympy import Expr
  from torch.fx.experimental.symbolic_shapes import ShapeEnv
  from torch.utils._sympy.functions import FloorDiv, ModularIndexing
  from torch.utils._sympy.value_ranges import bound_sympy
  from .utils import sympy_subs, sympy_symbol, VarRanges
  from .virtualized import V
label_desc: Use image node_id 28 for calling the SizeVarAllocator obj's underlying member method code with example usage: obj._lru_cache(fn, maxsize) and returns: wrapper, fn_cache