Gradients don’t persist through new Tensors.
There are probably many ways to create arbitrary matrices that preserves gradients, though (if that is your issue).
The easy way is to first create a base tensor that is the right size, and then you fill in each of its entries one by one:
theta = torch.tensor(10., requires_grad=True)
base = torch.ones(2, 2)
base[0][0] = torch.cos(theta)
base[0][1] = -torch.sin(theta)
base[1][0] = torch.sin(theta)
base[1][1] = torch.cos(theta)
base.backward(torch.ones_like(base))
theta.grad # tensor(1.0880)

A more advanced way is to create a custom autograd function. See PyTorch: Defining New autograd Functions — PyTorch Tutorials 1.7.0 documentation.
For example to rewrite the above using custom function we have:
class Rotation(torch.autograd.Function):
    @staticmethod
    def forward(ctx, theta):
        rot = torch.tensor([
            [torch.cos(theta), -torch.sin(theta)],
            [torch.sin(theta), torch.cos(theta)]])
        ctx.save_for_backward(theta)
        return rot

    @staticmethod
    def backward(ctx, grad_output):
        theta, = ctx.saved_tensors
        grad_input = -torch.sin(theta)*grad_output[0][0] + -torch.cos(theta)*grad_output[0][1] + \
            torch.cos(theta)*grad_output[1][0] + -torch.sin(theta)*grad_output[1][1]
        return grad_input

rotation = Rotation.apply

theta = torch.tensor(10., requires_grad=True)
rot = rotation(theta)
rot.backward(torch.ones_like(rot))
theta.grad # tensor(1.0880)