# Path: third_party/bi_att_flow/my/tensorflow/general.py
# def flatten(tensor, keep):
#   fixed_shape = tensor.get_shape().as_list()
#   start = len(fixed_shape) - keep
#   left = reduce(mul,
#                 [fixed_shape[i] or tf.shape(tensor)[i] for i in range(start)])
#   out_shape = [left] + [
#       fixed_shape[i] or tf.shape(tensor)[i]
#       for i in range(start, len(fixed_shape))
#   ]
#   flat = tf.reshape(tensor, out_shape)
#   return flat
# 
# def reconstruct(tensor, ref, keep):
#   ref_shape = ref.get_shape().as_list()
#   tensor_shape = tensor.get_shape().as_list()
#   ref_stop = len(ref_shape) - keep
#   tensor_start = len(tensor_shape) - keep
#   pre_shape = [ref_shape[i] or tf.shape(ref)[i] for i in range(ref_stop)]
#   keep_shape = [
#       tensor_shape[i] or tf.shape(tensor)[i]
#       for i in range(tensor_start, len(tensor_shape))
#   ]
#   # pre_shape = [tf.shape(ref)[i] for i in range(len(ref.get_shape().as_list()[:-keep]))]
#   # keep_shape = tensor.get_shape().as_list()[-keep:]
#   target_shape = pre_shape + keep_shape
#   out = tf.reshape(tensor, target_shape)
#   return out


from tensorflow.python.ops.rnn import dynamic_rnn as _dynamic_rnn
from tensorflow.python.ops.rnn import bidirectional_dynamic_rnn as _bidirectional_dynamic_rnn
from tensorflow.contrib.learn.python.learn.models import bidirectional_rnn as _bidirectional_rnn
from third_party.bi_att_flow.my.tensorflow.general import flatten, reconstruct
import tensorflow as tf
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function





def dynamic_rnn(cell,
                inputs,
                sequence_length=None,
                initial_state=None,
                dtype=None,
                parallel_iterations=None,
                swap_memory=False,
                time_major=False,
                scope=None):
  assert not time_major  # TODO : to be implemented later!
  flat_inputs = flatten(inputs, 2)  # [-1, J, d]
  flat_len = None if sequence_length is None else tf.cast(

# Path: third_party/bi_att_flow/my/tensorflow/general.py
# def flatten(tensor, keep):
#   fixed_shape = tensor.get_shape().as_list()
#   start = len(fixed_shape) - keep
#   left = reduce(mul,
#                 [fixed_shape[i] or tf.shape(tensor)[i] for i in range(start)])
#   out_shape = [left] + [
#       fixed_shape[i] or tf.shape(tensor)[i]
#       for i in range(start, len(fixed_shape))
#   ]
#   flat = tf.reshape(tensor, out_shape)
#   return flat
# 
# def reconstruct(tensor, ref, keep):
#   ref_shape = ref.get_shape().as_list()
#   tensor_shape = tensor.get_shape().as_list()
#   ref_stop = len(ref_shape) - keep
#   tensor_start = len(tensor_shape) - keep
#   pre_shape = [ref_shape[i] or tf.shape(ref)[i] for i in range(ref_stop)]
#   keep_shape = [
#       tensor_shape[i] or tf.shape(tensor)[i]
#       for i in range(tensor_start, len(tensor_shape))
#   ]
#   # pre_shape = [tf.shape(ref)[i] for i in range(len(ref.get_shape().as_list()[:-keep]))]
#   # keep_shape = tensor.get_shape().as_list()[-keep:]
#   target_shape = pre_shape + keep_shape
#   out = tf.reshape(tensor, target_shape)
#   return out


# Path: third_party/bi_att_flow/my/tensorflow/rnn.py
from tensorflow.python.ops.rnn import dynamic_rnn as _dynamic_rnn
from tensorflow.python.ops.rnn import bidirectional_dynamic_rnn as _bidirectional_dynamic_rnn
from tensorflow.contrib.learn.python.learn.models import bidirectional_rnn as _bidirectional_rnn
from third_party.bi_att_flow.my.tensorflow.general import flatten, reconstruct
import tensorflow as tf

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function





def dynamic_rnn(cell,
                inputs,
                sequence_length=None,
                initial_state=None,
                dtype=None,
                parallel_iterations=None,
                swap_memory=False,
                time_major=False,
                scope=None):
  assert not time_major  # TODO : to be implemented later!
  flat_inputs = flatten(inputs, 2)  # [-1, J, d]
  flat_len = None if sequence_length is None else tf.cast(

      flatten(sequence_length, 0), 'int64')