class_docstr: Proposes sharding plans in greedy fashion.
  
  Sorts sharding options for each shardable parameter by perf.
  On each iteration, finds parameter with largest current storage usage and tries its
  next sharding option.
  
  Args:
      use_depth (bool): When enabled, sharding_options of a fqn are sorted based on
          `max(shard.perf.total)`, otherwise sharding_options are sorted by
          `sum(shard.perf.total)`.
      threshold (Optional[int]): Threshold for early stopping. When specified, the
          proposer stops proposing when the proposals have consecutive worse perf_rating
          than best_perf_rating.
class_docstr_tok: ["Proposes","sharding","plans","in","greedy","fashion",".","Sorts","sharding","options","for","each","shardable","parameter","by","perf",".","On","each","iteration",",","finds","parameter","with","largest","current","storage","usage","and","tries","its","next","sharding","option",".","Args",":","use_depth","(","bool",")",":","When","enabled",",","sharding_options","of","a","fqn","are","sorted","based","on","`","max","(","shard.perf.total",")","`",",","otherwise","sharding_options","are","sorted","by","`","sum","(","shard.perf.total",")","`",".","threshold","(","Optional","[","int","]",")",":","Threshold","for","early","stopping",".","When","specified",",","the","proposer","stops","proposing","when","the","proposals","have","consecutive","worse","perf_rating","than","best_perf_rating","."]
code: def feedback(
      self,
      partitionable: bool,
      plan: Optional[List[ShardingOption]] = None,
      perf_rating: Optional[float] = None,
      storage_constraint: Optional[Topology] = None,
  ) -> None:
      # When threshold is passed, observe the perf_rating trend. If the perf_rating
      # of the newly proposed plans have worse perf_rating, stop proposing.
      if self._threshold and perf_rating:
          self._num_inferior_perf += 1
          if perf_rating < self._best_perf_rating:
              self._best_perf_rating = perf_rating
              self._num_inferior_perf = 0
          # pyre-fixme [58]: `>` is not supported for operand types `int` and `Optional[int]`.
          if self._num_inferior_perf > self._threshold:
              self._current_proposal = {}
              return
      # static strategy, ignore feedback and just provide next proposal
      largest_fqn: Optional[str] = None
      largest_storage: Tuple[float, float, float, float] = (0, 0, 0, 0)
      for (
          fqn,
          sharding_options,
      ) in self._sharding_options_by_fqn.items():
          index = self._current_proposal[fqn]
          if index + 1 < len(sharding_options):
              sharding_option = sharding_options[index]
              current_storage = (
                  # pyre-fixme [16]: `Optional` has no attribute `hbm`
                  max(
                      [
                          shard.storage.hbm
                          for shard in sharding_option.shards
                      ]
                  ),
                  sum(
                      [
                          shard.storage.hbm
                          for shard in sharding_option.shards
                      ]
                  ),
                  # pyre-fixme [16]: `Optional` has no attribute `ddr`
                  max(
                      [
                          shard.storage.ddr
                          for shard in sharding_option.shards
                      ]
                  ),
                  sum(
                      [
                          shard.storage.ddr
                          for shard in sharding_option.shards
                      ]
                  ),
              )
              if current_storage > largest_storage:
                  largest_fqn = fqn
                  largest_storage = current_storage
  
      if largest_fqn is not None:
          self._current_proposal[largest_fqn] += 1
      else:
          self._current_proposal = {}
  
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 5 for calling the GreedyProposer obj's underlying member method code with example usage: obj.feedback(partitionable, plan, perf_rating, storage_constraint) without return types