code: def varlength_concat(x, y, x_length, dtype=None, tensor_rank=None):
      """Concatenates rows of `x` and `y` where each row of
      `x` has a variable length.
  
      Both `x` and `y` are of numeric dtypes, such as `tf.int32` and `tf.float32`,
      with mask value `0`. The two tensors must be of the same dtype.
  
      Args:
          x: A tensor of shape `[batch_size, x_dim_2, other_dims]`.
          y: A tensor of shape `[batch_size, y_dim_2, other_dims]`.
              All dimensions except the 2nd dimension must be the same
              with those of `x`.
          x_length: A 1D int tensor of shape `[batch_size]` containing
              the length of each `x` row.
              Elements beyond the respective lengths will be
              made zero.
          dtype: Type of :attr:`x`. If `None`, inferred from
              :attr:`x` automatically.
          tensor_rank (int, optional): The number of dimensions of
              :attr:`x`. If not given, inferred from :attr:`x`
              automatically.
  
      Returns:
          A Tensor of shape `[batch_size, x_dim_2 + y_dim_2, other_dims]`.
  
      Example:
          .. code-block:: python
  
              x = tf.constant([[1, 1, 0, 0],
                               [1, 1, 1, 0]])
              x_length = [2, 3]
              y = tf.constant([[2, 2, 0],
                               [2, 2, 2]])
  
              out = varlength_concat(x, y, x_length)
              # out = [[1, 1, 2, 2, 0, 0, 0]
              #        [1, 1, 1, 2, 2, 2, 0]]
      """
      x = tf.convert_to_tensor(x)
      y = tf.convert_to_tensor(y)
      x_length = tf.convert_to_tensor(x_length)
  
      if tensor_rank is None:
          tensor_rank = get_rank(x) or get_rank(y)
      if tensor_rank is None:
          raise ValueError(
              "Unable to infer the rank of `x`. "
              "Please set `tensor_rank` explicitly."
          )
  
      x_masked = mask_sequences(
          x, x_length, dtype=dtype, tensor_rank=tensor_rank
      )
      zeros_y = tf.zeros_like(y)
      x_aug = tf.concat([x_masked, zeros_y], axis=1)
  
      zeros_x = tf.zeros_like(x)
      y_aug = tf.concat([zeros_x, y], axis=1)
  
      # Now, x_aug.shape == y_aug.shape
  
      max_length_x = tf.shape(x)[1]
      batch_size = tf.shape(x)[0]
  
      initial_index = tf.constant(0, dtype=tf.int32)
      initial_outputs_ta = tf.TensorArray(
          dtype=dtype or x.dtype, size=0, dynamic_size=True
      )
  
      def _cond(index, _):
          return tf.less(index, batch_size)
  
      def _body(index, outputs_ta):
          y_aug_i_rolled = tf.roll(
              input=y_aug[index],
              shift=x_length[index] - max_length_x,  # shift to left
              axis=0,
          )
          xy = x_aug[index] + y_aug_i_rolled
          return [index + 1, outputs_ta.write(index, xy)]
  
      res = tf.while_loop(
          _cond, _body, [initial_index, initial_outputs_ta]
      )
  
      return res[1].stack()
  
file_path: texar/texar/tf/utils/shapes.py
imports: import numpy
  import tensorflow
  from tensorflow.python.util import nest
  from tensorflow.python.ops import rnn
  from tensorflow.python.framework import ops
label_desc: Use image node_id 11 for calling a global function with example usage: varlength_concat(x, y, x_length, dtype, tensor_rank) and returns: res, tf, list