I don’t know why the implemented it like this, its a bit annoying. If instead of embed_dim being an input they asked you for head_dim and they calculated embed_dim as:
self.embed_dim = self.head_dim * num_heads

It would be much easier to understand because you can do a per-head reasoning when defining the shapes, and it would also guarantee you never get an error. The easiest way to deal with this is just to do the math on your own outside:
nhead = 5
head_dim = 32
dmodel = nhead * head_dim

net = nn.Transformer(d_model=d_model, nhead=nhead)