code: def khatri_rao(
      x: Sequence[Union[ivy.Array, ivy.NativeArray]],
      weights: Optional[Union[ivy.Array, ivy.NativeArray]] = None,
      skip_matrix: Optional[Sequence[int]] = None,
      mask: Optional[Union[ivy.Array, ivy.NativeArray]] = None,
      out: Optional[ivy.Array] = None,
  ) -> ivy.Array:
      """Khatri-Rao product of a sequence of matrices.
  
          This can be seen as a column-wise kronecker product.
          If one matrix only is given, that matrix is directly returned.
  
      Parameters
      ----------
      x
          Sequence of tensors with the same number of columns, i.e.::
              for i in len(x):
                  x[i].shape = (n_i, m)
  
      weights
          array of weights for each rank, of length m, the number of column of the factors
          (i.e. m == factor[i].shape[1] for any factor)
  
      skip_matrix
          if not None, index of a matrix to skip
  
      mask
          array of 1s and 0s of length m
  
      out
          optional output array, for writing the result to. It must have a shape that the
          result can broadcast to.
  
      Returns
      -------
      khatri_rao_product: ivy.Array of shape ``(prod(n_i), m)``
          where ``prod(n_i) = prod([m.shape[0] for m in input])``
          i.e. the product of the number of rows of all the input in the product.
      """
      if skip_matrix is not None:
          x = [x[i] for i in range(len(x)) if i != skip_matrix]
  
      # Khatri-rao of only one matrix: just return that matrix
      if len(x) == 1:
          if ivy.exists(out):
              return ivy.inplace_update(out, x[0])
          return x[0]
  
      if len(x[0].shape) == 2:
          n_columns = x[0].shape[1]
      else:
          n_columns = 1
          x = [ivy.reshape(m, (-1, 1)) for m in x]
          logging.warning(
              "Khatri-rao of a series of vectors instead of input. "
              "Considering each as a matrix with 1 column."
          )
  
      # Testing whether the input have the proper size
      for i, matrix in enumerate(x):
          if len(matrix.shape) != 2:
              raise ValueError(
                  "All the input must have exactly 2 dimensions!"
                  f"Matrix {i} has dimension {len(matrix.shape)} != 2."
              )
          if matrix.shape[1] != n_columns:
              raise ValueError(
                  "All input must have same number of columns!"
                  f"Matrix {i} has {matrix.shape[1]} columns != {n_columns}."
              )
  
      for i, e in enumerate(x[1:]):
          if not i:
              if weights is None:
                  res = x[0]
              else:
                  res = x[0] * ivy.reshape(weights, (1, -1))
          s1, s2 = ivy.shape(res)
          s3, s4 = ivy.shape(e)
  
          a = ivy.reshape(res, (s1, 1, s2))
          b = ivy.reshape(e, (1, s3, s4))
          res = ivy.reshape(a * b, (-1, n_columns))
  
      m = ivy.reshape(mask, (1, -1)) if mask is not None else 1
  
      res = res * m
  
      if ivy.exists(out):
          return ivy.inplace_update(out, res)
  
      return res
  
imports: import logging
  from typing import Union, Optional, Tuple, List, Sequence, Literal
  import ivy
  from ivy.utils.backend import current_backend
  from ivy.func_wrapper import to_native_arrays_and_back, handle_out_argument, handle_nestable, handle_array_like_without_promotion, handle_array_function, handle_device, inputs_to_ivy_arrays, handle_backend_invalid
  from ivy.utils.exceptions import handle_exceptions
label_desc: Use image node_id 13 for calling a global function with example usage: khatri_rao(x, weights, skip_matrix, mask, out) and returns: res, x, ivy, ivy