I think something simpler can be done e.g.,
import torch

n, p, q = 9, 2, 3
x = torch.randn(p, q, requires_grad=True)
A = torch.randn(q, p)
z = torch.randn(q, 1)

f = A@x
y = None
for k in range(int(n/q)):
    if(y is None):                                                                                                                  y = f @ z
    else:                                                                                                                           y = torch.vstack( ( y, f @ z ) )                                                                                                                                                                                                                    # prepare for next time step                                                                                                f = (A@x) @ f
dydx = list()
for i in range(n):
    x.grad = None
    y[i, 0].backward(retain_graph=True)
    dydx.append(x.grad.clone())
dydx = torch.stack(dydx)
print('dydx with autograd: \n', dydx)
print(dydx.shape)