class_docstr: PS StrategyBuilder with Greedy Load Balancing.
  
  The Load Balancing is determined by total memory
  usage for storing variables, i.e. we always assign
  a variable to the current lowest-memory-usage
  Parameter Server.
docstr: Generate the Strategy.
code: def build(self, graph_item, resource_spec):
      """Generate the Strategy."""
      expr = Strategy()
  
      # get each variable, generate variable synchronizer config
      expr.graph_config.replicas.extend(
          [k for k, v in resource_spec.gpu_devices]
      )
      for k, v in resource_spec.node_cpu_devices.items():
          if k not in resource_spec.node_gpu_devices:
              expr.graph_config.replicas.extend(v)
  
      # find all variables
      variables = graph_item.trainable_var_op_to_var.values()
      reduction_device_names = [k for k, _ in resource_spec.cpu_devices]
      self.loads = {ps: 0.0 for ps in reduction_device_names}
  
      # Mark each variable to be synchronized with a Parameter Server
      node_config = [
          self._gen_ps_node_config(
              var,
              self._local_proxy_variable,
              self._sync,
              self._staleness,
          )
          for var in variables
      ]
      expr.node_config.extend(node_config)
  
      return expr
  
file_path: autodist/autodist/strategy/ps_lb_strategy.py
imports: from tensorflow.python.framework import tensor_shape
  from autodist.strategy.base import Strategy, StrategyBuilder
  from autodist.proto import strategy_pb2
label_desc: Use image node_id 2 for calling the PSLoadBalancing obj's underlying member method code with example usage: obj.build(graph_item, resource_spec) and returns: expr