Hi,
You want to do e.backward(create_graph=True) that will make sure the backward pass run in a differentiable manner.
Also creating a .grad that requires grad is usually not recommended because when you do l.backward() here, you will accumulate in the same p.grad which can easily become confusing. You can do the following to make it simpler:
w = torch.tensor([3.2], requires_grad=True)
p = torch.tensor([2.0, 1, 7], requires_grad=True)
g = torch.sum(p ** 2)
e = w * g
f = autograd.grad(e, p, create_graph=True)[0]

l = e + 0.5 * f.mean()
l.backward()