Why torch.autograd.grad() returns None with torch.cat?
I know the torch.autograd.grad() returns None if the gradient is stopped somehow, however, I am wondering what is wrong with the following snippet?
x = torch.rand(6, requires_grad=True)

y = x.pow(2).sum()
z = torch.cat([x])

grad1 = torch.autograd.grad(y, x, allow_unused=True)
grad2 = torch.autograd.grad(y, z, allow_unused=True)
      
print(f'grad1 = {grad1}, grad = {grad2}')

The output is grad1 = (tensor([0.3705, 0.7468, 0.6102, 1.8640, 0.3518, 0.5397]),), grad = (None,).
I am expecting the grad2 is the same to grad1, because z is essentially the x. May I know why please?

Update: After reading the post and the help from @Ivan, I conclude the reason is x is a leaf node of y but z is not any more. x is the leaf node of both y and z in the computation graph, but there is no direct path from z to y, so the torch.autograd.grad returns None.
Note: The returned value None does not necessarily guarantee the values are 0.

Tensor z was not used to compute the value of y, as such it is not connected to its computation graph, and you won't get a gradient on z, since it's not connected to y.
On the other hand, the following will work:
&gt;&gt;&gt; y = x.pow(2).sum()
&gt;&gt;&gt; torch.autograd.grad(y, x, allow_unused=True)
(tensor([0.3134, 1.6802, 0.1989, 0.8495, 1.9203, 1.0905]),)

&gt;&gt;&gt; z = torch.cat([x])
&gt;&gt;&gt; y = z.pow(2).sum()
&gt;&gt;&gt; torch.autograd.grad(y, z, allow_unused=True)
(tensor([0.3134, 1.6802, 0.1989, 0.8495, 1.9203, 1.0905]),)

