code: def test_scaleup_ample_budget_and_deprecated_feature(self) -> None:
      tables = [
          EmbeddingBagConfig(
              num_embeddings=2_000_000,
              embedding_dim=10,
              name=f"table_{i}",
              feature_names=[f"feature_{i}"],
          )
          for i in range(3)
      ]
  
      # Place first two tables into cache, 3rd table leave on hbm. table_1 has an
      # expected lookup of 0 (deprecated feature).
      constraints = {
          "table_0": ParameterConstraints(
              compute_kernels=[
                  EmbeddingComputeKernel.FUSED_UVM_CACHING.value
              ],
              cache_params=CacheParams(
                  load_factor=0.1,
                  stats=MockCacheStatistics(
                      expected_lookups=2, cacheability=0.2
                  ),
              ),
          ),
          "table_1": ParameterConstraints(
              compute_kernels=[
                  EmbeddingComputeKernel.FUSED_UVM_CACHING.value
              ],
              cache_params=CacheParams(
                  load_factor=0.1,
                  stats=MockCacheStatistics(
                      expected_lookups=0, cacheability=0
                  ),
              ),
          ),
      }
  
      MB = 1024 * 1024
      storage_constraint = Topology(
          world_size=2,
          compute_device="cuda",
          hbm_cap=100 * MB,
          ddr_cap=1000 * MB,
      )
  
      model = TestSparseNN(
          tables=tables, sparse_device=torch.device("meta")
      )
      enumerator = EmbeddingEnumerator(
          topology=storage_constraint,
          batch_size=BATCH_SIZE,
          constraints=constraints,
      )
      search_space = enumerator.enumerate(
          module=model,
          sharders=[
              cast(
                  ModuleSharder[torch.nn.Module],
                  EmbeddingBagCollectionSharder(),
              )
          ],
      )
      proposer = EmbeddingOffloadScaleupProposer()
      proposer.load(search_space, enumerator=enumerator)
  
      output = []
      proposal = proposer.propose()
      while proposal is not None:
          output.append(
              [
                  (
                      candidate.name,
                      candidate.compute_kernel,
                      candidate.cache_params.load_factor
                      if candidate.cache_params
                      else None,
                  )
                  for candidate in proposal
              ]
          )
          proposer.feedback(
              partitionable=True,
              plan=proposal,
              storage_constraint=storage_constraint,
          )
          proposal = proposer.propose()
  
      # Expected output (name, kernel clf).
      # First attempt uses the mins supplied, then as we apply increasing budget
      # clfs increase, table 0 gets promoted, table 1 left as original minimum.
      expected_output = [
          [
              ("table_0", "fused_uvm_caching", 0.1),
              ("table_1", "fused_uvm_caching", 0.1),
              ("table_2", "fused", None),
          ],
          [
              ("table_0", "fused_uvm_caching", 0.8090304136276245),
              ("table_1", "fused_uvm_caching", 0.1),
              ("table_2", "fused", None),
          ],
          [
              ("table_0", "fused", None),
              ("table_1", "fused_uvm_caching", 0.1),
              ("table_2", "fused", None),
          ],
      ]
      self.assertEqual(output[0:3], expected_output)
  
imports: import unittest
  from typing import cast, List, Optional
  from unittest.mock import MagicMock
  import torch
  from torchrec.distributed.embedding_types import EmbeddingComputeKernel
  from torchrec.distributed.embeddingbag import EmbeddingBagCollectionSharder
  from torchrec.distributed.planner.constants import BATCH_SIZE
  from torchrec.distributed.planner.enumerators import EmbeddingEnumerator
  from torchrec.distributed.planner.proposers import EmbeddingOffloadScaleupProposer, GreedyProposer, GridSearchProposer, proposers_to_proposals_list, UniformProposer
  from torchrec.distributed.planner.types import Enumerator, ParameterConstraints, Proposer, ShardingOption, Topology
  from torchrec.distributed.test_utils.test_model import TestSparseNN
  from torchrec.distributed.types import CacheParams, CacheStatistics, ModuleSharder, ShardingType
  from torchrec.modules.embedding_configs import EmbeddingBagConfig
label_desc: Use image node_id 7 for calling the TestProposers obj's underlying member method code with example usage: obj.test_scaleup_ample_budget_and_deprecated_feature() without return types