class_docstr: Greedy Partitioner
  
  Args:
      sort_by (SortBy): Sort sharding options by storage or perf in
          descending order (i.e., large tables will be placed first).
      balance_modules (bool): Whether to sort by modules first, where
          smaller modules will be sorted first. In effect, this will place
          tables in each module in a balanced way.
code: def _establish_minheap(
      devices: List[DeviceHardware], local_world_size: int
  ) -> List[OrderedDeviceHardware]:
      minheap_devices = [
          OrderedDeviceHardware(device, local_world_size)
          for device in devices
      ]
      heapq.heapify(minheap_devices)
      return minheap_devices
  
imports: import copy
  import heapq
  import logging
  from dataclasses import dataclass
  from enum import Enum
  from typing import cast, Dict, List, Optional
  from torchrec.distributed.planner.perf_models import NoopPerfModel
  from torchrec.distributed.planner.types import DeviceHardware, PartitionByType, Partitioner, Perf, PerfModel, PlannerError, PlannerErrorType, ShardingOption, Storage, Topology
  from torchrec.distributed.planner.utils import bytes_to_gb, reset_shard_rank
  from torchrec.distributed.types import ShardingType
label_desc: Use image node_id 3 for calling the GreedyPerfPartitioner obj's underlying member method code with example usage: obj._establish_minheap(devices, local_world_size) and returns: minheap_devices