I think you are on the right track.
Automatic broadcasting doesn’t work in your example, as the dimensions are missing.
Try to unsqueeze C
and it should work:
A, B, C, D = 3, 3, 2, 2
c = torch.ones(A, B) * 2
v = torch.randn(A, B, C, D)
d = c[:, :, None, None] * v
print((d[0, 0] == v[0, 0]* 2).all())