code: def fill_triangular_inverse(x, upper=False, name=None):
      """Creates a vector from a (batch of) triangular matrix.
  
      The vector is created from the lower-triangular or upper-triangular portion
      depending on the value of the parameter `upper`.
  
      If `x.shape` is `[b1, b2, ..., bB, n, n]` then the output shape is
      `[b1, b2, ..., bB, d]` where `d = n (n + 1) / 2`.
  
      Example:
  
      ```python
      fill_triangular_inverse(
        [[4, 0, 0],
         [6, 5, 0],
         [3, 2, 1]])
  
      # ==> [1, 2, 3, 4, 5, 6]
  
      fill_triangular_inverse(
        [[1, 2, 3],
         [0, 5, 6],
         [0, 0, 4]], upper=True)
  
      # ==> [1, 2, 3, 4, 5, 6]
      ```
  
      Args:
        x: `Tensor` representing lower (or upper) triangular elements.
        upper: Python `bool` representing whether output matrix should be upper
          triangular (`True`) or lower triangular (`False`, default).
        name: Python `str`. The name to give this op.
  
      Returns:
        flat_tril: (Batch of) vector-shaped `Tensor` representing vectorized lower
          (or upper) triangular elements from `x`.
      """
  
      with tf.name_scope(name or "fill_triangular_inverse"):
          x = tf.convert_to_tensor(x, name="x")
          n = tf.compat.dimension_value(
              tensorshape_util.with_rank_at_least(x.shape, 2)[-1]
          )
          if n is not None:
              n = np.int32(n)
              m = np.int32((n * (n + 1)) // 2)
              static_final_shape = tensorshape_util.concatenate(
                  x.shape[:-2], [m]
              )
          else:
              n = tf.shape(x)[-1]
              m = (n * (n + 1)) // 2
              static_final_shape = tensorshape_util.concatenate(
                  tensorshape_util.with_rank_at_least(x.shape, 2)[:-2],
                  [None],
              )
          ndims = ps.rank(x)
          if upper:
              initial_elements = x[..., 0, :]
              triangular_portion = x[..., 1:, :]
          else:
              initial_elements = tf.reverse(
                  x[..., -1, :], axis=[ndims - 2]
              )
              triangular_portion = x[..., :-1, :]
          rotated_triangular_portion = tf.reverse(
              tf.reverse(triangular_portion, axis=[ndims - 1]),
              axis=[ndims - 2],
          )
          consolidated_matrix = (
              triangular_portion + rotated_triangular_portion
          )
          end_sequence = tf.reshape(
              consolidated_matrix,
              ps.concat([ps.shape(x)[:-2], [n * (n - 1)]], axis=0),
          )
          y = tf.concat(
              [initial_elements, end_sequence[..., : m - n]], axis=-1
          )
          tensorshape_util.set_shape(y, static_final_shape)
          return y
  
imports: import numpy
  import tensorflow.compat.v1
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import custom_gradient
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.math import generic
label_desc: Use image node_id 15 for calling a global function with example usage: fill_triangular_inverse(x, upper, name) and returns: y