class_docstr: PS Synchronizer.
  
  Synchronizes gradient updates using a Parameter Server.
  
  For in-graph synchronization, this just aggregates gradients on a worker's CPU.
  
  For between-graph synchronization, this aggregates gradients on a pre-defined
  (defined in the Strategy) parameter server.
  
  To keep this gradient aggregation in sync, the chief gives each worker a token
  for each variable for the workers to mark when their variable update is complete.
code: def _get_aggregated_sparse_grad(
      self, graph_item, var_op, grad, reduce_to_device
  ):
      indices_op_name = strip_replica_prefix(
          get_op_name(grad.indices.name)
      )
      values_op_name = strip_replica_prefix(
          get_op_name(grad.values.name)
      )
      dense_shape_op_name = strip_replica_prefix(
          get_op_name(grad.dense_shape.name)
      )
  
      indexed_slices_grads = []
      for i in range(self.num_replicas):
          indices_op = graph_item.graph.get_operation_by_name(
              ops.prepend_name_scope(indices_op_name, replica_prefix(i))
          )
          values_op = graph_item.graph.get_operation_by_name(
              ops.prepend_name_scope(values_op_name, replica_prefix(i))
          )
          dense_shape_op = graph_item.graph.get_operation_by_name(
              ops.prepend_name_scope(
                  dense_shape_op_name, replica_prefix(i)
              )
          )
          indexed_slices_grads.append(
              ops.IndexedSlices(
                  values_op.outputs[
                      utils.get_index_from_tensor_name(grad.values.name)
                  ],
                  indices_op.outputs[
                      utils.get_index_from_tensor_name(
                          grad.indices.name
                      )
                  ],
                  dense_shape_op.outputs[
                      utils.get_index_from_tensor_name(
                          grad.dense_shape.name
                      )
                  ],
              )
          )
  
      return self._aggregate_sparse_gradients(
          var_op, reduce_to_device, indexed_slices_grads, values_op_name
      )
  
imports: from functools import partial
  from typing import List
  from tensorflow.python import ops
  from tensorflow.python.framework import device_spec, dtypes, constant_op
  from tensorflow.python.platform import tf_logging
  from tensorflow.python.ops import math_ops, data_flow_ops, gen_control_flow_ops, control_flow_ops, gen_math_ops, gen_array_ops
  from autodist.const import MAX_INT64, AUTODIST_PREFIX
  from autodist.kernel.common import utils, variable_utils
  from autodist.kernel.common.op_info import UPDATE_OP_VAR_POS
  from autodist.kernel.common.proxy_variable import ProxyVariable
  from autodist.kernel.common.utils import get_op_name, get_consumers, get_ancestors, traverse, update_consumers, update_control_consumers, replica_prefix, strip_replica_prefix, get_control_consumers, remove_from_control_consumers, get_index_from_tensor_name, update_colocation_group
  from autodist.kernel.common.variable_utils import get_read_var_ops
  from autodist.kernel.synchronization.synchronizer import Synchronizer
  from autodist.proto import synchronizers_pb2
label_desc: Use image node_id 12 for calling the PSSynchronizer obj's underlying member method code with example usage: obj._get_aggregated_sparse_grad(graph_item, var_op, grad, reduce_to_device) and returns: self