`torch.matmul()` 函数几乎可以用于所有矩阵/向量相乘的情况，其乘法规则视参与乘法的两个张量的维度而定。

`torch.matmul()` 将两个张量相乘划分成了五种情形：一维 × 一维、二维 × 二维、一维 × 二维、二维 × 一维、涉及到三维及三维以上维度的张量的乘法。

```>>> vec1 = torch.tensor([1, 2, 3])
>>> vec2 = torch.tensor([2, 3, 4])
>>> torch.matmul(vec1, vec2)
tensor(20)
>>> torch.dot(vec1, vec2)
tensor(20)
# 两个一维张量的元素个数要相同！
>>> vec1 = torch.tensor([1, 2, 3])
>>> vec2 = torch.tensor([2, 3, 4, 5])
>>> torch.matmul(vec1, vec2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: inconsistent tensor size, expected tensor [3] and src [4] to have the same number of elements, but got 3 and 4 elements respectively```

```>>> arg1 = torch.tensor([[1, 2], [3, 4]])
>>> arg1
tensor([[1, 2],
[3, 4]])
>>> arg2 = torch.tensor([[-1], [2]])
>>> arg2
tensor([[-1],
[ 2]])
>>> torch.matmul(arg1, arg2)
tensor([[3],
[5]])
>>> torch.mm(arg1, arg2)
tensor([[3],
[5]])
>>> arg2 = torch.tensor([[-1], [2], [1]])
>>> torch.matmul(arg1, arg2)# 要求满足矩阵乘法的条件
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: mat1 and mat2 shapes cannot be multiplied (2x2 and 3x1)```

```>>> arg1 = torch.tensor([-1, 2])
>>> arg2 = torch.tensor([[1, 2], [3, 4]])
>>> torch.matmul(arg1, arg2)
tensor([5, 6])
>>> arg1 = torch.unsqueeze(arg1, 0)# 在一维张量前增加一个维度
>>> arg1.shape
torch.Size([1, 2])
>>> ans = torch.mm(arg1, arg2)# 进行矩阵乘法
>>> ans
tensor([[5, 6]])
>>> ans = torch.squeeze(ans, 0)# 移除增加的维度
>>> ans
tensor([5, 6])```

```>>> arg1 = torch.tensor([[1, 2], [3, 4]])
>>> arg2 = torch.tensor([-1, 2])
>>> torch.matmul(arg1, arg2)
tensor([3, 5])
>>> torch.mv(arg1, arg2)
tensor([3, 5])```

`For example, if input is a (j × 1 × n × n) tensor and other is a (k × n × n) tensor, out will be a (j × k × n × n) tensor.`

```>>> arg1 = torch.tensor([1, 2, -1, 1])
>>> arg2 = torch.randint(low=-2, high=3, size=[3, 4, 1])
>>> torch.matmul(arg1, arg2)
tensor([[ 5],
[-1],
[-1]])

>>> arg2
tensor([[[ 2],
[ 2],
[-1],
[-2]],
[[-2],
[ 2],
[ 1],
[-2]],
[[ 0],
[ 0],
[-1],
[-2]]])```

```>>> arg3 = torch.unsqueeze(arg1, 0)
>>> arg3
tensor([[ 1,  2, -1,  1]])
>>> arg3.shape
torch.Size([1, 4])```

```>>> arg4 = torch.tensor([ [[ 1,  2, -1,  1]], [[ 1,  2, -1,  1]], [[ 1,  2, -1,  1]] ])
>>> arg4
tensor([[[ 1,  2, -1,  1]],
[[ 1,  2, -1,  1]],
[[ 1,  2, -1,  1]]])
>>> arg4.shape
torch.Size([3, 1, 4])```

```>>> torch.bmm(arg4, arg2)
tensor([[[ 5]],
[[-1]],
[[-1]]])```

PS：在看文档第五条规则时，起先也非常不明白，试了很多次高维和一维的张量乘法总是提示 `RuntimeError: mat1 and mat2 shapes cannot be multiplied` ，然后就尝试理解这条规则。因为这条规则很长，分成了三个小情形，并且这三个情形并不是一一独立的，而是前两个情形经过处理之后最后全都可以转变成第三个情形。另一个理解的突破口是 `prepended``appended` 这两个单词，通过它们的前缀可以猜测出：一个是在张量前面增加维度，一个是在张量后面增加维度，然后广播再进行批量矩阵乘法就验证出来了！