If it shares memory, then clearly the value of a[0] does have a gradient with respect to output. If I changed a[0] and then recalled loss it would be updated, we could then measure that update with respect to how much I changed a[0]. The very definition of the gradient
import torch
a = torch.rand(10, requires_grad=True)

output = (2 * a).sum()

print(output)
a[0] +=1
output2 = (2 * a).sum()
print(output2)


tensor(11.2303, grad_fn=<SumBackward0>)
tensor(13.2303, grad_fn=<SumBackward0>)