def _best_effort_input_batch_size(flat_input):
    """Get static input batch size if available, with fallback to the dynamic one.
    Args:
      flat_input: An iterable of time major input Tensors of shape [max_time,
        batch_size, ...]. All inputs should have compatible batch sizes.
    Returns:
      The batch size in Python integer if available, or a scalar Tensor otherwise.
    Raises:
      ValueError: if there is any input with an invalid shape.
    """

    for input_ in flat_input:

        shape = input_.shape

        if shape.ndims is None:
            continue

        if shape.ndims < 2:
            raise ValueError(

                "Expected input tensor %s to have rank at least 2" % input_)

        batch_size = shape[1].value

        if batch_size is not None:
            return batch_size

    # Fallback to the dynamic batch size of the first input.

    return array_ops.shape(flat_input[0])[1]
Get static input batch size if available, with fallback to the dynamic one.
    Args:
      flat_input: An iterable of time major input Tensors of shape [max_time,
        batch_size, ...]. All inputs should have compatible batch sizes.
    Returns:
      The batch size in Python integer if available, or a scalar Tensor otherwise.
    Raises:
      ValueError: if there is any input with an invalid shape.
    
deepctr/contrib/rnn.py