class_docstr: Partitioned PS StrategyBuilder with Greedy Load Balancer.
  
  Determine the number of partitions for each partition-able
  variable by finding its minimum divisor along the first axis.
  
  Then, use a greedy load balancer (determined by memory usage)
  to assign the partitions to Parameter Servers. This means that,
  unlike the standard PS StrategyBuilder, that a variable can be
  spread across multiple servers using this StrategyBuilder.
docstr: Creates a NodeConfig specifying synchronization with Parameter Servers.
  
  Args:
      var (Variable): The variable to generate a config for.
  
  Returns:
      Dict: the config dict for the node.
docstr_tok: ["Creates","a","NodeConfig","specifying","synchronization","with","Parameter","Servers",".","Args",":","var","(","Variable",")",":","The","variable","to","generate","a","config","for",".","Returns",":","Dict",":","the","config","dict","for","the","node","."]
code: def _gen_ps_node_config(self, var):
      """
      Creates a NodeConfig specifying synchronization with Parameter Servers.
  
      Args:
          var (Variable): The variable to generate a config for.
  
      Returns:
          Dict: the config dict for the node.
      """
      if (
          len(self.loads) < 1 and not ENV.AUTODIST_IS_TESTING.val
      ) or any(
          (o.type in CONTROL_FLOW_OPS for o in get_consumers(var.op))
      ):
          # Don't partition if there is only one reduction device or if the variable is connected to control flow
          # For stability, we err on the side of not partitioning over potentially breaking
          num_shards = 1
      else:
          num_shards = self.get_num_shards(var)
  
      # Determine placement of vars/parts
      sorted_ps = sorted(self.loads, key=self.loads.get)
      if num_shards > len(self.loads):
          # If there's more shards than servers, round-robin in greedy order
          sorted_ps = sorted_ps * ceil(num_shards / len(self.loads))
      min_ps = sorted_ps[0:num_shards]
      for ps in min_ps:
          self.loads[ps] += byte_size_load_fn(var) / num_shards
  
      # setup node config
      node = strategy_pb2.Strategy.Node()
      node.var_name = var.name
  
      if num_shards == 1:
          node.PSSynchronizer.reduction_destination = min_ps[0]
          node.PSSynchronizer.local_replication = (
              self._local_proxy_variable
          )
          node.PSSynchronizer.sync = self._sync
          node.PSSynchronizer.staleness = self._staleness
      else:
          # generate the partitioner config
          shape = var.initial_value.shape
          partition_list = [1] * len(var.initial_value.shape)
          partition_axis = 0
          partition_list[partition_axis] = min(
              num_shards, shape.dims[partition_axis].value
          )
          pc = PartitionerConfig(partition_list=partition_list)
          node.partitioner = pc.partition_str
  
          for i in range(num_shards):
              part = strategy_pb2.Strategy.Node()
              part.var_name = "{}/part_{}:0".format(
                  get_op_name(var.name), i
              )
              part.PSSynchronizer.reduction_destination = min_ps[i]
              part.PSSynchronizer.local_replication = (
                  self._local_proxy_variable
              )
              part.PSSynchronizer.sync = self._sync
              part.PSSynchronizer.staleness = self._staleness
              node.part_config.extend([part])
      return node
  
file_path: autodist/autodist/strategy/partitioned_ps_strategy.py
imports: from math import ceil
  from tensorflow.python.framework import tensor_shape
  from autodist.const import ENV
  from autodist.kernel.common.op_info import CONTROL_FLOW_OPS
  from autodist.kernel.common.utils import get_consumers, get_op_name
  from autodist.kernel.partitioner import PartitionerConfig
  from autodist.strategy.base import Strategy, StrategyBuilder
  from autodist.proto import strategy_pb2
label_desc: Use image node_id 3 for calling the PartitionedPS obj's underlying member method code with example usage: obj._gen_ps_node_config(var) and returns: node