code: def matmul(
      a,
      b,
      transpose_a=False,
      transpose_b=False,
      adjoint_a=False,
      adjoint_b=False,
      name=None,
  ):
      """Perform a sparse matrix matmul between `a` and `b`.
  
      Performs a contraction between `a` and `b` along the two innermost dimensions.
      If both `a` and `b` are instances of `SparseMatrix`, returns a new instance
      of `SparseMatrix` (same type as `a`).  If one is not an instance of
      `SparseMatrix`, returns a dense `Tensor`:
  
      ```
      c = opA(a) . opB(b)
      ```
      where `opA` (resp. `opB`) is the transpose or hermitian transpose depending
      on the values of `transpose_a` (resp. `transpose_b`) and `adjoint_a`
      (resp. `adjoint_b`).
  
      Args:
        a: `Tensor` or `SparseMatrix`, having rank `2` or `3`.
        b: `Tensor` or `SparseMatrix`, having rank `2` or `3`.
        transpose_a: Python `bool`.
        transpose_b: Python `bool`.
        adjoint_a: Python `bool`.
        adjoint_b: Python `bool`.
        name: Optional name to use when creating ops.
  
      Returns:
        A `SparseMatrix` if both `a` and `b` are instances of `SparseMatrix`,
        otherwise a dense `Tensor`.
      """
      if not isinstance(a, SparseMatrix) and not isinstance(
          b, SparseMatrix
      ):
          return math_ops.matmul(
              a,
              b,
              transpose_a=transpose_a,
              transpose_b=transpose_b,
              adjoint_a=adjoint_a,
              adjoint_b=adjoint_b,
              name=name,
          )
  
      # pylint: disable=protected-access
      a_matrix = a._matrix if isinstance(a, SparseMatrix) else a
      b_matrix = b._matrix if isinstance(b, SparseMatrix) else b
      with ops.name_scope(
          name, "SparseMatrixMatMul", [a_matrix, b_matrix]
      ):
          if isinstance(a, SparseMatrix) and isinstance(
              b, SparseMatrix
          ):
              if not (isinstance(a, type(b)) or isinstance(b, type(a))):
                  raise TypeError(
                      "SparseMatrix types don't inherit from each other: "
                      "%s and %s" % (type(a), type(b))
                  )
              c = sm_ops.sparse_matrix_sparse_mat_mul(
                  a_matrix,
                  b_matrix,
                  transpose_a=transpose_a,
                  transpose_b=transpose_b,
                  adjoint_a=adjoint_a,
                  adjoint_b=adjoint_b,
                  type=a.dtype,
              )
  
              # In eager mode, shape inference functions are not called, and the output
              # shape is not set. We have to infer the output shape here.
              # TODO(penporn): Set this from the C++ kernel instead.
              c_handle = matmul_shape_inference(
                  a_matrix,
                  b_matrix,
                  c,
                  transpose_a,
                  transpose_b,
                  adjoint_a,
                  adjoint_b,
              )
              return a._from_matrix(c, handle_data=c_handle)
  
          elif isinstance(a, SparseMatrix):
              return sm_ops.sparse_matrix_mat_mul(
                  a_matrix,
                  b,
                  transpose_a=transpose_a,
                  transpose_b=transpose_b,
                  adjoint_a=adjoint_a,
                  adjoint_b=adjoint_b,
              )
          else:
              # opA(A) . opB(B) = t(nopB(B) . nopA(A))
              if not adjoint_a and not adjoint_b:
                  return sm_ops.sparse_matrix_mat_mul(
                      b_matrix,
                      a,
                      transpose_a=not transpose_b,
                      transpose_b=not transpose_a,
                      transpose_output=True,
                  )
              elif not transpose_a and not transpose_b:
                  return sm_ops.sparse_matrix_mat_mul(
                      b_matrix,
                      a,
                      adjoint_a=not adjoint_b,
                      adjoint_b=not adjoint_a,
                      transpose_output=True,
                      conjugate_output=True,
                  )
              else:
                  return sm_ops.sparse_matrix_mat_mul(
                      b_matrix,
                      math_ops.conj(a),
                      transpose_output=True,
                      conjugate_output=adjoint_b,
                  )
  
imports: import abc
  import collections
  from tensorflow.python.eager import context
  from tensorflow.python.framework import cpp_shape_inference_pb2
  from tensorflow.python.framework import dtypes
  from tensorflow.python.framework import ops
  from tensorflow.python.framework import sparse_tensor
  from tensorflow.python.framework import tensor
  from tensorflow.python.framework import tensor_shape
  from tensorflow.python.ops import array_ops
  from tensorflow.python.ops import math_ops
  from tensorflow.python.ops import resource_variable_ops
  from tensorflow.python.ops.linalg.sparse import gen_sparse_csr_matrix_ops
  from tensorflow.python.ops.linalg.sparse.gen_sparse_csr_matrix_ops import *
label_desc: Use image node_id 7 for calling a global function with example usage: matmul(a, b, transpose_a, transpose_b, adjoint_a, adjoint_b, name) and returns: math_ops, a, sm_ops, sm_ops, sm_ops, sm_ops