code: def build_affine_storage_model(
      uvm_caching_sharding_options: List[ShardingOption],
      enumerator: Enumerator,
  ) -> torch.Tensor:
      plan: List[ShardingOption] = copy.deepcopy(
          uvm_caching_sharding_options
      )
  
      def compute_hbm_sizes(clf: float) -> torch.Tensor:
          for sharding_option in plan:
              assert sharding_option.cache_params  # appease pyre
              sharding_option.cache_params.load_factor = clf
          enumerator.populate_estimates(plan)
          return torch.tensor(
              [
                  sharding_option.total_storage.hbm
                  for sharding_option in plan
              ]
          )
  
      low_clf, high_clf = 0.1, 0.9
      low_hbms = compute_hbm_sizes(low_clf)
      high_hbms = compute_hbm_sizes(high_clf)
  
      A = (high_hbms - low_hbms) / (high_clf - low_clf)
      B = low_hbms - A * low_clf
      return torch.stack((A, B), dim=1)
  
imports: import copy
  import itertools
  import logging
  from decimal import Decimal
  from typing import cast, Dict, List, Optional, Set, Tuple, Union
  import torch
  from torchrec.distributed.embedding_types import EmbeddingComputeKernel
  from torchrec.distributed.planner.types import Enumerator, Perf, Proposer, ShardingOption, Topology
  from torchrec.distributed.planner.utils import BinarySearchPredicate, bytes_to_gb, prod
label_desc: Use image node_id 10 for calling the EmbeddingOffloadScaleupProposer obj's underlying member method code with example usage: obj.build_affine_storage_model(uvm_caching_sharding_options, enumerator) and returns: torch, torch