I don’t know which tensors require gradients and would thus be part of the computation graph.
I guess that one of u, v or dist_mat_norm might require gradients and due to the broadcasting in Mf the memory usage might blow up.
u = torch.randn(10, 10)
v = torch.randn(10, 10)
res = u.unsqueeze(-1) + v.unsqueeze(-2)
print(res.shape)
> torch.Size([10, 10, 10])

Could this be the reason?