Create a dict() as the outgoing data in the tensor data comm route.

  Note: The tensor data in the comm route does not include the value of the
  tensor in its entirety in general. Only if a tensor satisfies the following
  conditions will its entire value be included in the return value of this
  method:
  1. Has a numeric data type (e.g., float32, int32) and has fewer than 5
     elements.
  2. Is a string tensor and has fewer than 5 elements. Each string element is
     up to 40 bytes.

  Args:
    device_name: Name of the device that the tensor is on.
    node_name: (Original) name of the node that produces the tensor.
    maybe_base_expanded_node_name: Possbily base-expanded node name.
    output_slot: Output slot number.
    debug_op: Name of the debug op.
    tensor_value: Value of the tensor, as a numpy.ndarray.
    wall_time: Wall timestamp for the tensor.

  Returns:
    A dict representing the tensor data.

def _comm_tensor_data(device_name,
                      node_name,
                      maybe_base_expanded_node_name,
                      output_slot,
                      debug_op,
                      tensor_value,
                      wall_time):
  """Create a dict() as the outgoing data in the tensor data comm route.

  Note: The tensor data in the comm route does not include the value of the
  tensor in its entirety in general. Only if a tensor satisfies the following
  conditions will its entire value be included in the return value of this
  method:
  1. Has a numeric data type (e.g., float32, int32) and has fewer than 5
     elements.
  2. Is a string tensor and has fewer than 5 elements. Each string element is
     up to 40 bytes.

  Args:
    device_name: Name of the device that the tensor is on.
    node_name: (Original) name of the node that produces the tensor.
    maybe_base_expanded_node_name: Possbily base-expanded node name.
    output_slot: Output slot number.
    debug_op: Name of the debug op.
    tensor_value: Value of the tensor, as a numpy.ndarray.
    wall_time: Wall timestamp for the tensor.

  Returns:
    A dict representing the tensor data.
  """
  output_slot = int(output_slot)
  logger.info(
      'Recording tensor value: %s, %d, %s', node_name, output_slot, debug_op)
  tensor_values = None
  if isinstance(tensor_value, debug_data.InconvertibleTensorProto):
    if not tensor_value.initialized:
      tensor_dtype = UNINITIALIZED_TAG
      tensor_shape = UNINITIALIZED_TAG
    else:
      tensor_dtype = UNSUPPORTED_TAG
      tensor_shape = UNSUPPORTED_TAG
    tensor_values = NA_TAG
  else:
    tensor_dtype = tensor_helper.translate_dtype(tensor_value.dtype)
    tensor_shape = tensor_value.shape

    # The /comm endpoint should respond with tensor values only if the tensor is
    # small enough. Otherwise, the detailed values sould be queried through a
    # dedicated tensor_data that supports slicing.
    if tensor_helper.numel(tensor_shape) < 5:
      _, _, tensor_values = tensor_helper.array_view(tensor_value)
      if tensor_dtype == 'string' and tensor_value is not None:
        tensor_values = tensor_helper.process_buffers_for_display(
            tensor_values, limit=STRING_ELEMENT_MAX_LEN)

  return {
      'type': 'tensor',
      'timestamp': wall_time,
      'data': {
          'device_name': device_name,
          'node_name': node_name,
          'maybe_base_expanded_node_name': maybe_base_expanded_node_name,
          'output_slot': output_slot,
          'debug_op': debug_op,
          'dtype': tensor_dtype,
          'shape': tensor_shape,
          'values': tensor_values,
      },
  }