def matmul(x, y, transpose_x=False, transpose_y=False, name=None):
    "\n    Applies matrix multiplication to two tensors. `matmul` follows\n    the complete broadcast rules,\n    and its behavior is consistent with `np.matmul`.\n\n    Currently, the input tensors' number of dimensions can be any, `matmul` can be used to\n    achieve the `dot`, `matmul` and `batchmatmul`.\n\n    The actual behavior depends on the shapes of :math:`x`, :math:`y` and the\n    flag values of :attr:`transpose_x`, :attr:`transpose_y`. Specifically:\n\n    - If a transpose flag is specified, the last two dimensions of the tensor\n      are transposed. If the tensor is ndim-1 of shape, the transpose is invalid. If the tensor\n      is ndim-1 of shape :math:`[D]`, then for :math:`x` it is treated as :math:`[1, D]`, whereas\n      for :math:`y` it is the opposite: It is treated as :math:`[D, 1]`.\n\n    The multiplication behavior depends on the dimensions of `x` and `y`. Specifically:\n\n    - If both tensors are 1-dimensional, the dot product result is obtained.\n\n    - If both tensors are 2-dimensional, the matrix-matrix product is obtained.\n\n    - If the `x` is 1-dimensional and the `y` is 2-dimensional,\n      a `1` is prepended to its dimension in order to conduct the matrix multiply.\n      After the matrix multiply, the prepended dimension is removed.\n\n    - If the `x` is 2-dimensional and `y` is 1-dimensional,\n      the matrix-vector product is obtained.\n\n    - If both arguments are at least 1-dimensional and at least one argument\n      is N-dimensional (where N > 2), then a batched matrix multiply is obtained.\n      If the first argument is 1-dimensional, a 1 is prepended to its dimension\n      in order to conduct the batched matrix multiply and removed after.\n      If the second argument is 1-dimensional, a 1 is appended to its\n      dimension for the purpose of the batched matrix multiple and removed after.\n      The non-matrix (exclude the last two dimensions) dimensions are\n      broadcasted according the broadcast rule.\n      For example, if input is a (j, 1, n, m) tensor and the other is a (k, m, p) tensor,\n      out will be a (j, k, n, p) tensor.\n\n    Args:\n        x (Tensor): The input tensor which is a Tensor.\n        y (Tensor): The input tensor which is a Tensor.\n        transpose_x (bool): Whether to transpose :math:`x` before multiplication.\n        transpose_y (bool): Whether to transpose :math:`y` before multiplication.\n        name(str|None): A name for this layer(optional). If set None, the layer\n            will be named automatically.\n\n    Returns:\n        Tensor: The output Tensor.\n\n    Examples:\n\n    .. code-block:: python\n\n        import paddle\n        import numpy as np\n\n        # vector * vector\n        x_data = np.random.random([10]).astype(np.float32)\n        y_data = np.random.random([10]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [1]\n\n        # matrix * vector\n        x_data = np.random.random([10, 5]).astype(np.float32)\n        y_data = np.random.random([5]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10]\n\n        # batched matrix * broadcasted vector\n        x_data = np.random.random([10, 5, 2]).astype(np.float32)\n        y_data = np.random.random([2]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10, 5]\n\n        # batched matrix * batched matrix\n        x_data = np.random.random([10, 5, 2]).astype(np.float32)\n        y_data = np.random.random([10, 2, 5]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10, 5, 5]\n\n        # batched matrix * broadcasted matrix\n        x_data = np.random.random([10, 1, 5, 2]).astype(np.float32)\n        y_data = np.random.random([1, 3, 2, 5]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10, 3, 5, 5]\n\n    "
    if in_dygraph_mode():
        return _C_ops.final_state_matmul(x, y, transpose_x, transpose_y)
    if _in_legacy_dygraph():
        op_type = 'matmul_v2'
        op = getattr(_C_ops, op_type)
        return op(x, y, 'trans_x', transpose_x, 'trans_y', transpose_y)
    attrs = {'trans_x': transpose_x, 'trans_y': transpose_y}

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for (name, val) in var_names.items():
            check_variable_and_dtype(val, name, ['float16', 'float32', 'float64', 'complex64', 'complex128'], 'matmul')
    __check_input(x, y)
    helper = LayerHelper('matmul_v2', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    helper.append_op(type='matmul_v2', inputs={'X': x, 'Y': y}, outputs={'Out': out}, attrs=attrs)
    return out
Applies matrix multiplication to two tensors. `matmul` follows
the complete broadcast rules,
and its behavior is consistent with `np.matmul`.

Currently, the input tensors' number of dimensions can be any, `matmul` can be used to
achieve the `dot`, `matmul` and `batchmatmul`.

The actual behavior depends on the shapes of :math:`x`, :math:`y` and the
flag values of :attr:`transpose_x`, :attr:`transpose_y`. Specifically:

- If a transpose flag is specified, the last two dimensions of the tensor
  are transposed. If the tensor is ndim-1 of shape, the transpose is invalid. If the tensor
  is ndim-1 of shape :math:`[D]`, then for :math:`x` it is treated as :math:`[1, D]`, whereas
  for :math:`y` it is the opposite: It is treated as :math:`[D, 1]`.

The multiplication behavior depends on the dimensions of `x` and `y`. Specifically:

- If both tensors are 1-dimensional, the dot product result is obtained.

- If both tensors are 2-dimensional, the matrix-matrix product is obtained.

- If the `x` is 1-dimensional and the `y` is 2-dimensional,
  a `1` is prepended to its dimension in order to conduct the matrix multiply.
  After the matrix multiply, the prepended dimension is removed.

- If the `x` is 2-dimensional and `y` is 1-dimensional,
  the matrix-vector product is obtained.

- If both arguments are at least 1-dimensional and at least one argument
  is N-dimensional (where N > 2), then a batched matrix multiply is obtained.
  If the first argument is 1-dimensional, a 1 is prepended to its dimension
  in order to conduct the batched matrix multiply and removed after.
  If the second argument is 1-dimensional, a 1 is appended to its
  dimension for the purpose of the batched matrix multiple and removed after.
  The non-matrix (exclude the last two dimensions) dimensions are
  broadcasted according the broadcast rule.
  For example, if input is a (j, 1, n, m) tensor and the other is a (k, m, p) tensor,
  out will be a (j, k, n, p) tensor.

Args:
    x (Tensor): The input tensor which is a Tensor.
    y (Tensor): The input tensor which is a Tensor.
    transpose_x (bool): Whether to transpose :math:`x` before multiplication.
    transpose_y (bool): Whether to transpose :math:`y` before multiplication.
    name(str|None): A name for this layer(optional). If set None, the layer
        will be named automatically.

Returns:
    Tensor: The output Tensor.

Examples:

.. code-block:: python

    import paddle
    import numpy as np

    # vector * vector
    x_data = np.random.random([10]).astype(np.float32)
    y_data = np.random.random([10]).astype(np.float32)
    x = paddle.to_tensor(x_data)
    y = paddle.to_tensor(y_data)
    z = paddle.matmul(x, y)
    print(z.numpy().shape)
    # [1]

    # matrix * vector
    x_data = np.random.random([10, 5]).astype(np.float32)
    y_data = np.random.random([5]).astype(np.float32)
    x = paddle.to_tensor(x_data)
    y = paddle.to_tensor(y_data)
    z = paddle.matmul(x, y)
    print(z.numpy().shape)
    # [10]

    # batched matrix * broadcasted vector
    x_data = np.random.random([10, 5, 2]).astype(np.float32)
    y_data = np.random.random([2]).astype(np.float32)
    x = paddle.to_tensor(x_data)
    y = paddle.to_tensor(y_data)
    z = paddle.matmul(x, y)
    print(z.numpy().shape)
    # [10, 5]

    # batched matrix * batched matrix
    x_data = np.random.random([10, 5, 2]).astype(np.float32)
    y_data = np.random.random([10, 2, 5]).astype(np.float32)
    x = paddle.to_tensor(x_data)
    y = paddle.to_tensor(y_data)
    z = paddle.matmul(x, y)
    print(z.numpy().shape)
    # [10, 5, 5]

    # batched matrix * broadcasted matrix
    x_data = np.random.random([10, 1, 5, 2]).astype(np.float32)
    y_data = np.random.random([1, 3, 2, 5]).astype(np.float32)
    x = paddle.to_tensor(x_data)
    y = paddle.to_tensor(y_data)
    z = paddle.matmul(x, y)
    print(z.numpy().shape)
    # [10, 3, 5, 5]
def matmul(x, y, transpose_x=False, transpose_y=False, name=None):
    "\n    Applies matrix multiplication to two tensors. `matmul` follows\n    the complete broadcast rules,\n    and its behavior is consistent with `np.matmul`.\n\n    Currently, the input tensors' number of dimensions can be any, `matmul` can be used to\n    achieve the `dot`, `matmul` and `batchmatmul`.\n\n    The actual behavior depends on the shapes of :math:`x`, :math:`y` and the\n    flag values of :attr:`transpose_x`, :attr:`transpose_y`. Specifically:\n\n    - If a transpose flag is specified, the last two dimensions of the tensor\n      are transposed. If the tensor is ndim-1 of shape, the transpose is invalid. If the tensor\n      is ndim-1 of shape :math:`[D]`, then for :math:`x` it is treated as :math:`[1, D]`, whereas\n      for :math:`y` it is the opposite: It is treated as :math:`[D, 1]`.\n\n    The multiplication behavior depends on the dimensions of `x` and `y`. Specifically:\n\n    - If both tensors are 1-dimensional, the dot product result is obtained.\n\n    - If both tensors are 2-dimensional, the matrix-matrix product is obtained.\n\n    - If the `x` is 1-dimensional and the `y` is 2-dimensional,\n      a `1` is prepended to its dimension in order to conduct the matrix multiply.\n      After the matrix multiply, the prepended dimension is removed.\n\n    - If the `x` is 2-dimensional and `y` is 1-dimensional,\n      the matrix-vector product is obtained.\n\n    - If both arguments are at least 1-dimensional and at least one argument\n      is N-dimensional (where N > 2), then a batched matrix multiply is obtained.\n      If the first argument is 1-dimensional, a 1 is prepended to its dimension\n      in order to conduct the batched matrix multiply and removed after.\n      If the second argument is 1-dimensional, a 1 is appended to its\n      dimension for the purpose of the batched matrix multiple and removed after.\n      The non-matrix (exclude the last two dimensions) dimensions are\n      broadcasted according the broadcast rule.\n      For example, if input is a (j, 1, n, m) tensor and the other is a (k, m, p) tensor,\n      out will be a (j, k, n, p) tensor.\n\n    Args:\n        x (Tensor): The input tensor which is a Tensor.\n        y (Tensor): The input tensor which is a Tensor.\n        transpose_x (bool): Whether to transpose :math:`x` before multiplication.\n        transpose_y (bool): Whether to transpose :math:`y` before multiplication.\n        name(str|None): A name for this layer(optional). If set None, the layer\n            will be named automatically.\n\n    Returns:\n        Tensor: The output Tensor.\n\n    Examples:\n\n    .. code-block:: python\n\n        import paddle\n        import numpy as np\n\n        # vector * vector\n        x_data = np.random.random([10]).astype(np.float32)\n        y_data = np.random.random([10]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [1]\n\n        # matrix * vector\n        x_data = np.random.random([10, 5]).astype(np.float32)\n        y_data = np.random.random([5]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10]\n\n        # batched matrix * broadcasted vector\n        x_data = np.random.random([10, 5, 2]).astype(np.float32)\n        y_data = np.random.random([2]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10, 5]\n\n        # batched matrix * batched matrix\n        x_data = np.random.random([10, 5, 2]).astype(np.float32)\n        y_data = np.random.random([10, 2, 5]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10, 5, 5]\n\n        # batched matrix * broadcasted matrix\n        x_data = np.random.random([10, 1, 5, 2]).astype(np.float32)\n        y_data = np.random.random([1, 3, 2, 5]).astype(np.float32)\n        x = paddle.to_tensor(x_data)\n        y = paddle.to_tensor(y_data)\n        z = paddle.matmul(x, y)\n        print(z.numpy().shape)\n        # [10, 3, 5, 5]\n\n    "
    if in_dygraph_mode():
        return _C_ops.final_state_matmul(x, y, transpose_x, transpose_y)
    if _in_legacy_dygraph():
        op_type = 'matmul_v2'
        op = getattr(_C_ops, op_type)
        return op(x, y, 'trans_x', transpose_x, 'trans_y', transpose_y)
    attrs = {'trans_x': transpose_x, 'trans_y': transpose_y}

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for (name, val) in var_names.items():
            check_variable_and_dtype(val, name, ['float16', 'float32', 'float64', 'complex64', 'complex128'], 'matmul')
    __check_input(x, y)
    helper = LayerHelper('matmul_v2', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    helper.append_op(type='matmul_v2', inputs={'X': x, 'Y': y}, outputs={'Out': out}, attrs=attrs)
    return out