class_docstr: Computes cache statistics for uvm_fused_cache tables.
  
  Args:
  
  cachebility (float):
      The area-under-the-curve of miss-ratio curve.
  expected_lookups (float):
      The expected number of unique embedding ids per global batch.
  mrc_hist_counts (torch.Tensor):
      A 1d tensor (size n) holding a histogram of LRU miss ratio curve. Each bin
      represents 1/nth of possible LRU cache sizes (from load_factor 0 to load_factor
      1.0). The bin contains the number of expected LRU operations that could be
      handled without a cache miss if the LRU load_factor was at least that size.
  height (int):
      The height (num_embeddings) of the embedding table.
docstr: Calculate estimated cache miss ratio for the proposed cache_sizes, given the MRC
  histogram.
docstr_tok: ["Calculate","estimated","cache","miss","ratio","for","the","proposed","cache_sizes",",","given","the","MRC","histogram","."]
code: def estimate_cache_miss_rate(
      cache_sizes: torch.Tensor, hist: torch.Tensor, bins: torch.Tensor
  ) -> torch.Tensor:
      """Calculate estimated cache miss ratio for the proposed cache_sizes, given the MRC
      histogram.
      """
      ys = hist.cumsum(dim=0)
      if ys[-1] == 0:
          # feature has no usage data -> no cache misses
          return torch.zeros_like(cache_sizes, dtype=torch.float32)
      ys = ys / ys[-1]  # rescale [0,1]
      ys = 1 - ys  # make miss-ratio, not hit-ratio
  
      # torch.bucketize has slightly different semantics to np.digitize,
      # and np.digitize has a complex interface, read the docs carefully!
      # we're trying to reverse the ops of np.histogram, indices are one larger than
      # the insert positions, since with right=True, index returned such that x <
      # bins[index], so x 'lives' in hist[index-1]
      # A cache size of k will get hits for all stack distances of upto k-1 inclusive.
      larger_bin_indices = torch.bucketize(
          cache_sizes - 1, bins, right=True
      )
      # Augment ys to deal with torch.bucketize boundary conditions:
      #   values outside of bins range map to 0, or len(bins).
      # So we extend ys to populate sentinel values for these cases.  With the twist that
      # the left-hand sentinel we put on the right side of the array, as larger_bin_indices - 1
      # maps 0 -> -1, which pytorch maps to most right hand value.
      ys = torch.cat((ys, torch.tensor([0.0, 1.0])))
      return ys[larger_bin_indices - 1]
  
imports: import logging
  import math
  from typing import cast, Dict, List, Optional, Tuple, Type
  import torch
  import torchrec.optim
  from torch import nn
  from torchrec.distributed.embedding_types import EmbeddingComputeKernel
  from torchrec.distributed.planner.constants import BATCHED_COPY_PERF_FACTOR, BIGINT_DTYPE, DP_ELEMENTWISE_KERNELS_PERF_FACTOR, FULL_BLOCK_EMB_DIM, HALF_BLOCK_PENALTY, kernel_bw_lookup, QUARTER_BLOCK_PENALTY, UVM_CACHING_RATIO, WEIGHTED_KERNEL_MULTIPLIER
  from torchrec.distributed.planner.types import ParameterConstraints, Perf, PlannerError, ShardEstimator, ShardingOption, Storage, Topology
  from torchrec.distributed.planner.utils import prod, sharder_name
  from torchrec.distributed.types import CacheStatistics, CommOp, ModuleSharder, ShardingType
  from torchrec.modules.embedding_modules import EmbeddingBagCollectionInterface
label_desc: Use image node_id 5 for calling the EmbeddingOffloadStats obj's underlying member method code with example usage: obj.estimate_cache_miss_rate(cache_sizes, hist, bins) and returns: ys, torch