In terms of torch.sort or torch.take they do have grad_fns, except for the indices returned via torch.sort
>>> x = torch.randn(10,2, requires_grad=True)
>>> torch.take(x, torch.LongTensor([1]))
tensor([-0.2461], grad_fn=<TakeBackward0>)
>>> torch.sort(x)[0]
tensor([[-1.2673, -0.2461],
        [-0.6003,  0.2518],
        [-1.1847,  0.2308],
        [ 0.1341,  2.5518],
        [-3.3000,  0.4909],
        [-1.2083,  1.7219],
        [-0.1799,  1.0432],
        [-1.3900,  0.2327],
        [-0.3572,  0.0238],
        [-0.7487,  0.4416]], grad_fn=<SortBackward0>)
>>> torch.sort(x)[1]
tensor([[0, 1],
        [1, 0],
        [0, 1],
        [1, 0],
        [1, 0],
        [1, 0],
        [0, 1],
        [0, 1],
        [0, 1],
        [0, 1]])

Also, one thing to check within your loss function is to check if any intermediate gradients are 0 because gradients are calculated via the chain rule, and so if one intermediate gradient is 0 then all of them will be 0.
Also, check to make sure you’re not calling .detach() or torch.no_grad() within any part of your code, and make sure your data has requires_grad=True otherwise your gradient will be 0 by definition.