code: def matmul(
      x1: Union[tf.Tensor, tf.Variable],
      x2: Union[tf.Tensor, tf.Variable],
      /,
      *,
      transpose_a: bool = False,
      transpose_b: bool = False,
      adjoint_a: bool = False,
      adjoint_b: bool = False,
      out: Optional[Union[tf.Tensor, tf.Variable]] = None,
  ) -> Union[tf.Tensor, tf.Variable]:
      x1, x2 = ivy.promote_types_of_inputs(x1, x2)
      dtype_from = tf.as_dtype(x1.dtype)
  
      if transpose_a:
          x1 = tf.linalg.matrix_transpose(x1)
      if transpose_b:
          x2 = tf.linalg.matrix_transpose(x2)
  
      if adjoint_a:
          x1 = tf.linalg.adjoint(x1)
      if adjoint_b:
          x2 = tf.linalg.adjoint(x2)
  
      if (
          dtype_from.is_unsigned
          or dtype_from == tf.int8
          or dtype_from == tf.int16
      ):
          x1 = tf.cast(x1, tf.int64)
          x2 = tf.cast(x2, tf.int64)
      if x1.dtype != x2.dtype:
          x1 = tf.cast(x1, dtype_from)
          x2 = tf.cast(x2, dtype_from)
  
      if (
          x1.shape == ()
          or x2.shape == ()
          or (
              len(x1.shape) == len(x2.shape) == 1
              and x1.shape != x2.shape
          )
          or (
              len(x1.shape) == len(x2.shape) == 1
              and x1.shape != x2.shape
          )
          or (
              len(x1.shape) == 1
              and len(x2.shape) >= 2
              and x1.shape[0] != x2.shape[-2]
          )
          or (
              len(x2.shape) == 1
              and len(x1.shape) >= 2
              and x2.shape[0] != x1.shape[-1]
          )
          or (
              len(x1.shape) >= 2
              and len(x2.shape) >= 2
              and x1.shape[-1] != x2.shape[-2]
          )
      ):
          raise ivy.utils.exceptions.IvyException(
              "Error,shapes not compatible"
          )
  
      x1_padded = False
      x1_padded_2 = False
      x2_padded = False
  
      if len(x1.shape) == len(x2.shape) == 1:
          if x1.shape == 0:
              ret = tf.constant(0)
          else:
              ret = tf.reduce_sum(tf.math.multiply(x1, x2))
          ret = tf.cast(ret, dtype=dtype_from)  # return ret
  
      else:
          if len(x1.shape) == 1:
              if len(x2.shape) == 2:
                  x1_padded_2 = True
              elif len(x2.shape) > 2:
                  x1_padded = True
              x1 = tf.expand_dims(x1, axis=0)
  
          elif len(x2.shape) == 1 and len(x1.shape) >= 2:
              x2 = tf.expand_dims(x2, axis=1)
              x2_padded = True
          ret = tf.matmul(x1, x2)
  
      ret = ivy.to_native(ivy.astype(ret, dtype_from, copy=False))
      if x1_padded_2:
          ret = ret[0]
      elif x1_padded:
          ret = tf.squeeze(ret, axis=-2)
      elif x2_padded:
          ret = tf.squeeze(ret, axis=-1)
      return ret
  
imports: from typing import Union, Optional, Tuple, Literal, List, NamedTuple, Sequence
  from collections import namedtuple
  import tensorflow
  from tensorflow.python.framework.dtypes import DType
  import ivy
  from ivy import inf
  from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes
  from .None import backend_version
label_desc: Use image node_id 10 for calling a global function with example usage: matmul() and returns: ret