def _dynamic_rnn_loop(cell,

                      inputs,

                      initial_state,

                      parallel_iterations,

                      swap_memory,

                      att_scores=None,

                      sequence_length=None,

                      dtype=None):
    """Internal implementation of Dynamic RNN.



    Args:

      cell: An instance of RNNCell.

      inputs: A `Tensor` of shape [time, batch_size, input_size], or a nested

        tuple of such elements.

      initial_state: A `Tensor` of shape `[batch_size, state_size]`, or if

        `cell.state_size` is a tuple, then this should be a tuple of

        tensors having shapes `[batch_size, s] for s in cell.state_size`.

      parallel_iterations: Positive Python int.

      swap_memory: A Python boolean

      sequence_length: (optional) An `int32` `Tensor` of shape [batch_size].

      dtype: (optional) Expected dtype of output. If not specified, inferred from

        initial_state.



    Returns:

      Tuple `(final_outputs, final_state)`.

      final_outputs:

        A `Tensor` of shape `[time, batch_size, cell.output_size]`.  If

        `cell.output_size` is a (possibly nested) tuple of ints or `TensorShape`

        objects, then this returns a (possibly nsted) tuple of Tensors matching

        the corresponding shapes.

      final_state:

        A `Tensor`, or possibly nested tuple of Tensors, matching in length

        and shapes to `initial_state`.



    Raises:

      ValueError: If the input depth cannot be inferred via shape inference

        from the inputs.

    """

    state = initial_state

    assert isinstance(parallel_iterations, int), "parallel_iterations must be int"

    state_size = cell.state_size

    flat_input = nest.flatten(inputs)

    flat_output_size = nest.flatten(cell.output_size)

    # Construct an initial output

    input_shape = array_ops.shape(flat_input[0])

    time_steps = input_shape[0]

    batch_size = _best_effort_input_batch_size(flat_input)

    inputs_got_shape = tuple(input_.get_shape().with_rank_at_least(3)

                             for input_ in flat_input)

    const_time_steps, const_batch_size = inputs_got_shape[0].as_list()[:2]

    for shape in inputs_got_shape:

        if not shape[2:].is_fully_defined():
            raise ValueError(

                "Input size (depth of inputs) must be accessible via shape inference,"

                " but saw value None.")

        got_time_steps = shape[0]

        got_batch_size = shape[1]

        if const_time_steps != got_time_steps:
            raise ValueError(

                "Time steps is not the same for all the elements in the input in a "

                "batch.")

        if const_batch_size != got_batch_size:
            raise ValueError(

                "Batch_size is not the same for all the elements in the input.")

    # Prepare dynamic conditional copying of state & output

    def _create_zero_arrays(size):

        size = _concat(batch_size, size)

        return array_ops.zeros(

            array_ops.stack(size), _infer_state_dtype(dtype, state))

    flat_zero_output = tuple(_create_zero_arrays(output)

                             for output in flat_output_size)

    zero_output = nest.pack_sequence_as(structure=cell.output_size,

                                        flat_sequence=flat_zero_output)

    if sequence_length is not None:
        min_sequence_length = math_ops.reduce_min(sequence_length)

        max_sequence_length = math_ops.reduce_max(sequence_length)

    time = array_ops.constant(0, dtype=dtypes.int32, name="time")

    with ops.name_scope("dynamic_rnn") as scope:

        base_name = scope

    def _create_ta(name, dtype):

        return tensor_array_ops.TensorArray(dtype=dtype,

                                            size=time_steps,

                                            tensor_array_name=base_name + name)

    output_ta = tuple(_create_ta("output_%d" % i,

                                 _infer_state_dtype(dtype, state))

                      for i in range(len(flat_output_size)))

    input_ta = tuple(_create_ta("input_%d" % i, flat_input[i].dtype)

                     for i in range(len(flat_input)))

    input_ta = tuple(ta.unstack(input_)

                     for ta, input_ in zip(input_ta, flat_input))

    def _time_step(time, output_ta_t, state, att_scores=None):

        """Take a time step of the dynamic RNN.



        Args:

          time: int32 scalar Tensor.

          output_ta_t: List of `TensorArray`s that represent the output.

          state: nested tuple of vector tensors that represent the state.



        Returns:

          The tuple (time + 1, output_ta_t with updated flow, new_state).

        """

        input_t = tuple(ta.read(time) for ta in input_ta)

        # Restore some shape information

        for input_, shape in zip(input_t, inputs_got_shape):
            input_.set_shape(shape[1:])

        input_t = nest.pack_sequence_as(structure=inputs, flat_sequence=input_t)

        if att_scores is not None:

            att_score = att_scores[:, time, :]

            call_cell = lambda: cell(input_t, state, att_score)

        else:

            call_cell = lambda: cell(input_t, state)

        if sequence_length is not None:

            (output, new_state) = _rnn_step(

                time=time,

                sequence_length=sequence_length,

                min_sequence_length=min_sequence_length,

                max_sequence_length=max_sequence_length,

                zero_output=zero_output,

                state=state,

                call_cell=call_cell,

                state_size=state_size,

                skip_conditionals=True)

        else:

            (output, new_state) = call_cell()

        # Pack state if using state tuples

        output = nest.flatten(output)

        output_ta_t = tuple(

            ta.write(time, out) for ta, out in zip(output_ta_t, output))

        if att_scores is not None:

            return (time + 1, output_ta_t, new_state, att_scores)

        else:

            return (time + 1, output_ta_t, new_state)

    if att_scores is not None:

        _, output_final_ta, final_state, _ = control_flow_ops.while_loop(

            cond=lambda time, *_: time < time_steps,

            body=_time_step,

            loop_vars=(time, output_ta, state, att_scores),

            parallel_iterations=parallel_iterations,

            swap_memory=swap_memory)

    else:

        _, output_final_ta, final_state = control_flow_ops.while_loop(

            cond=lambda time, *_: time < time_steps,

            body=_time_step,

            loop_vars=(time, output_ta, state),

            parallel_iterations=parallel_iterations,

            swap_memory=swap_memory)

    # Unpack final output if not using output tuples.

    final_outputs = tuple(ta.stack() for ta in output_final_ta)

    # Restore some shape information

    for output, output_size in zip(final_outputs, flat_output_size):
        shape = _concat(

            [const_time_steps, const_batch_size], output_size, static=True)

        output.set_shape(shape)

    final_outputs = nest.pack_sequence_as(

        structure=cell.output_size, flat_sequence=final_outputs)

    return (final_outputs, final_state)
Internal implementation of Dynamic RNN.



    Args:

      cell: An instance of RNNCell.

      inputs: A `Tensor` of shape [time, batch_size, input_size], or a nested

        tuple of such elements.

      initial_state: A `Tensor` of shape `[batch_size, state_size]`, or if

        `cell.state_size` is a tuple, then this should be a tuple of

        tensors having shapes `[batch_size, s] for s in cell.state_size`.

      parallel_iterations: Positive Python int.

      swap_memory: A Python boolean

      sequence_length: (optional) An `int32` `Tensor` of shape [batch_size].

      dtype: (optional) Expected dtype of output. If not specified, inferred from

        initial_state.



    Returns:

      Tuple `(final_outputs, final_state)`.

      final_outputs:

        A `Tensor` of shape `[time, batch_size, cell.output_size]`.  If

        `cell.output_size` is a (possibly nested) tuple of ints or `TensorShape`

        objects, then this returns a (possibly nsted) tuple of Tensors matching

        the corresponding shapes.

      final_state:

        A `Tensor`, or possibly nested tuple of Tensors, matching in length

        and shapes to `initial_state`.



    Raises:

      ValueError: If the input depth cannot be inferred via shape inference

        from the inputs.

    
deepctr/contrib/rnn_v2.py