code: def test_tw_unbalanced_perf_device(self) -> None:
      sharding_options = self.enumerator.enumerate(
          module=self.model, sharders=[TWSharder()]
      )
  
      for i, sharding_option in enumerate(sharding_options):
          perf = (
              Perf(
                  fwd_compute=40,
                  fwd_comms=30,
                  bwd_compute=20,
                  bwd_comms=10,
              )
              if i > 0
              else Perf(
                  fwd_compute=75,
                  fwd_comms=75,
                  bwd_compute=75,
                  bwd_comms=75,
              )
          )
          sharding_option.shards[0].perf = perf
          sharding_option.shards[0].storage = Storage(
              hbm=1000, ddr=1000
          )
  
      candidate_topology = copy.deepcopy(self.topology)
      sharding_plan = self.partitioner.partition(
          proposal=sharding_options,
          storage_constraint=candidate_topology,
      )
      # pyre-ignore[16]
      solution_topology = self.partitioner._topology
  
      expected_ranks = {
          "table_0": [0],
          "table_1": [1],
          "table_2": [1],
          "table_3": [1],
      }
  
      ranks = {
          sharding_option.name: [
              shard.rank for shard in sharding_option.shards
          ]
          for sharding_option in sharding_plan
      }
      self.assertEqual(expected_ranks, ranks)
  
      expected_perfs = [
          Perf(
              fwd_compute=75, fwd_comms=75, bwd_compute=75, bwd_comms=75
          ),
          Perf(
              fwd_compute=120,
              fwd_comms=90,
              bwd_compute=60,
              bwd_comms=30,
          ),
      ]
  
      self.assertEqual(
          solution_topology.devices[0].perf, expected_perfs[0]
      )
      self.assertEqual(
          solution_topology.devices[1].perf, expected_perfs[1]
      )
  
      self.assertEqual(
          solution_topology.devices[0].storage,
          self.topology.devices[0].storage - Storage(1000, 1000),
      )
      self.assertEqual(
          solution_topology.devices[1].storage,
          self.topology.devices[1].storage - Storage(3000, 3000),
      )
  
imports: import copy
  import unittest
  from typing import cast, List
  from unittest.mock import MagicMock
  from torch import nn
  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.partitioners import GreedyPerfPartitioner, MemoryBalancedPartitioner, OrderedDeviceHardware
  from torchrec.distributed.planner.types import DeviceHardware, ParameterConstraints, PartitionByType, Perf, PlannerError, Shard, ShardingOption, Storage, Topology
  from torchrec.distributed.planner.utils import reset_shard_rank
  from torchrec.distributed.test_utils.test_model import TestSparseNN
  from torchrec.distributed.types import ModuleSharder, ShardingType
  from torchrec.modules.embedding_configs import EmbeddingBagConfig
label_desc: Use image node_id 4 for calling the TestGreedyPerfPartitioner obj's underlying member method code with example usage: obj.test_tw_unbalanced_perf_device() without return types