import tensorflow as tf

    Returns:
      (outputs, out_paddings, segment_ids) tuple. `outputs` is of the shape
      [time, batch, depth], and `out_paddings` has shape [time, batch]. If
      is_transparent is True, can return a list of num_transformer_layers
      tensors of shape [time, batch, depth] if `p.is_eval` is False, and a
      [time, batch, depth, num_transparent_outputs] tensor if `p.is_eval` is
      True. If packed_input is True, also returns segment_id, otherwise returns
      None.
    """
    p = self.params
    if p.packed_input:
      assert src_segment_id is not None, ('Need to specify src_segment_id if '
                                          'packed input is supported.')
    outputs_list = [transformer_input]
    with tf.name_scope(p.name):
      for i, transformer_l in enumerate(self.trans):

        # For encoder, keys, values and queries are the same
        transformer_output, _ = transformer_l.FProp(
            theta.trans[i],
            transformer_input,
            paddings,
            aux_vecs=aux_vecs,
            aux_paddings=aux_paddings,
            source_segment_id=src_segment_id,
            aux_segment_id=aux_segment_id)
        transformer_input = transformer_output
        outputs_list.append(transformer_output)
