class_docstr: A version of ``matmul`` for iOS 17+. The only difference between this version and the
  iOS 15 :py:class:`~.iOS15.linear.matmul` is that the ``x`` and ``y`` can have a different
  dtypes when one of them is const.
  
  Parameters
  ----------
  x: tensor<[\*, K1], T> (Required)
      * ``x`` must be 1-D or higher.
  y: tensor<[\*, K2], U> (Required)
      * ``y`` must be 1-D or higher.
  transpose_x: const bool (Optional)
      * Default to ``False``.
      * Use ``True`` to transpose the last two dimensions of ``x`` before multiplication.
        It has no effect when ``x`` is 1-D.
  transpose_y: const bool (Optional)
      * Default to ``False``.
      * Use ``True`` to transpose the last two dimensions of ``y`` before multiplication.
        It has no effect when ``y`` is 1-D.
  
  Returns
  -------
  tensor<\*, V>
      * Scalar or tensor output.
      * When ``x`` and ``y`` are both const or both non-const, it should follow ios15 behavior
        that ``x``, ``y``, and ``output`` all have the same dtype.
        When one of x and y is const, the output dtype should be the same as the non-const one.
  
  Attributes
  ----------
  T: fp16, fp32, i32
  U: fp16, fp32, i32
class_docstr_tok: ["A","version","of","``","matmul","``","for","iOS","17+",".","The","only","difference","between","this","version","and","the","iOS","15",":","py",":","class",":","`","~.iOS15.linear.matmul","`","is","that","the","``","x","``","and","``","y","``","can","have","a","different","dtypes","when","one","of","them","is","const",".","Parameters","--","--","--","--","--","x",":","tensor","<","[","\\","*",",","K1","]",",","T",">","(","Required",")","*","``","x","``","must","be","1-D","or","higher",".","y",":","tensor","<","[","\\","*",",","K2","]",",","U",">","(","Required",")","*","``","y","``","must","be","1-D","or","higher",".","transpose_x",":","const","bool","(","Optional",")","*","Default","to","``","False","``",".","*","Use","``","True","``","to","transpose","the","last","two","dimensions","of","``","x","``","before","multiplication",".","It","has","no","effect","when","``","x","``","is","1-D.","transpose_y",":","const","bool","(","Optional",")","*","Default","to","``","False","``",".","*","Use","``","True","``","to","transpose","the","last","two","dimensions","of","``","y","``","before","multiplication",".","It","has","no","effect","when","``","y","``","is","1-D.","Returns","--","--","--","-","tensor","<","\\","*",",","V",">","*","Scalar","or","tensor","output",".","*","When","``","x","``","and","``","y","``","are","both","const","or","both","non-const",",","it","should","follow","ios15","behavior","that","``","x","``",",","``","y","``",",","and","``","output","``","all","have","the","same","dtype",".","When","one","of","x","and","y","is","const",",","the","output","dtype","should","be","the","same","as","the","non-const","one",".","Attributes","--","--","--","--","--","T",":","fp16",",","fp32",",","i32","U",":","fp16",",","fp32",",","i32"]
code: def type_inference(self):
      x_is_const = (
          self.x.op is not None and self.x.op.op_type == "const"
      )
      y_is_const = (
          self.y.op is not None and self.y.op.op_type == "const"
      )
  
      if x_is_const == y_is_const and self.x.dtype != self.y.dtype:
          is_const_str = "const" if x_is_const else "non-const"
          raise ValueError(
              f'In op "matmul", when x and y are both {is_const_str}, their dtype '
              f"need to match, but got x as {types.builtin_to_string(self.x.dtype)} "
              f"and y as {types.builtin_to_string(self.y.dtype)}"
          )
  
      inferred_type = super().type_inference()
      if x_is_const != y_is_const:
          # The output dtype should be the same as the non-const one.
          output_dtype = self.x.dtype if y_is_const else self.y.dtype
          inferred_type = types.tensor(
              output_dtype, inferred_type.get_shape()
          )
  
      return inferred_type
  
file_path: coremltools/coremltools/converters/mil/mil/ops/defs/iOS17/linear.py
imports: from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.input_type import InputSpec, TensorInputType
  from coremltools.converters.mil.mil.ops.defs._op_reqs import register_op
  from coremltools.converters.mil.mil.ops.defs.iOS15.linear import linear
  from coremltools.converters.mil.mil.ops.defs.iOS15.linear import matmul
  from coremltools.converters.mil.mil.ops.defs.iOS17 import _IOS17_TARGET
label_desc: Use image node_id 1 for calling the matmul obj's underlying member method code with example usage: obj.type_inference() and returns: inferred_type