class_docstr: Partitioned AR StrategyBuilder.
  
  This StrategyBuilder generates a strategy that partitions each variable along its first dimension,
  and synchronizes them using AllReduce. It might be advantageous for communicating extremely large
  messages -- when synchronizing a single message is bounded by single-flow bandwidth.
  
  It will also sequentially merge collective ops into a single collective group based on chunk_size.
  This strategy does not support synchronizing sparse updates with >1 nodes due to the TF AllGather bug.
docstr: Gets the minimum number of shards for a variable.
code: def get_num_shards_and_axis(var, grad):
      """Gets the minimum number of shards for a variable."""
      if not var.initial_value.shape.ndims:
          return 1, 0
  
      shape_list = var.initial_value.shape.as_list()
      non_one_dim = []
      for i, dim in enumerate(shape_list):
          if dim > 1:
              non_one_dim.append(i)
      if not non_one_dim:
          return 1, 0
  
      if isinstance(grad, IndexedSlices):
          partition_axis = 0
      else:
          idx = int(np.random.randint(0, len(non_one_dim)))
          partition_axis = non_one_dim[idx]
      n = int(var.initial_value.shape[partition_axis])
      for i in range(2, n):
          if n % i == 0:
              return i, partition_axis
      return n, partition_axis
  
file_path: autodist/autodist/strategy/random_axis_partition_all_reduce_strategy.py
imports: import numpy
  from tensorflow.python.framework.ops import IndexedSlices
  from autodist.kernel.common.utils import get_op_name
  from autodist.kernel.partitioner import PartitionerConfig
  from autodist.proto import strategy_pb2, synchronizers_pb2
  from autodist.strategy.base import Strategy, StrategyBuilder
label_desc: Use image node_id 4 for calling the RandomAxisPartitionAR obj's underlying member method code with example usage: obj.get_num_shards_and_axis(var, grad) and returns: n,  partition_axis, int,  int, int,  int, i,  partition_axis