One solution might be to reuse code from the spatial transformer:
    # Make it look like a 2D data: (batch, chan, h, w) as (batch_size, 1, Cp.size(1), 1)
    Cp = Cp.unsqueeze(-1).unsqueeze(1)
    affine_transfo = torch.zeros(batch_size, 2, 3)
    # The affine transformation we want is identity + translation
    affine_transfo[:, 0, 0] = 1
    affine_transfo[:, 1, 1] = 1
    affine_transfo[:, 1, 2] = -2 * ton / height
    grid = F.affine_grid(affine_transfo, (batch_size, 1, height, 1), align_corners=True)
    Cp = F.grid_sample(Cp, grid, align_corners=True)
    Cp = Cp.squeeze(1).squeeze(-1)

That will get you gradients to the parameters. But not sure how good it’s gonna be.
Also I am absolutely not sure how the align_corners flag should be used. So you should double checkt that this is doing what you want