No output grad when using a custom autograd function

Hi, everyone. I want a rank layer and then use backpropagation transfer its gradient to its original position, and I have written a custom function. When I test it, the forward propagation works well, and I can get expected results. However, I can not get the result of gradient. I’m really curious about where I have ignored.

This is my custom function:

class RankingFunc(Function): 
    @staticmethod
    def forward(ctx, x, ranking_size): 
        p, c, h, w = x.size()
        y = torch.empty(x.size())
        ind = torch.arange(0, h*w).view(h, w).unsqueeze(0).repeat(p, c, 1, 1)
        ctx.ranking_size = ranking_size
        
        h_num = h // ranking_size
        w_num = w // ranking_size
        
        for i in range(h_num):
            for j in range(w_num):
                temp1 = x[:, :, i * ranking_size : (i + 1) * ranking_size, j * ranking_size : (j + 1) * ranking_size].clone()
                temp2 = ind[:, :, i * ranking_size : (i + 1) * ranking_size, j * ranking_size : (j + 1) * ranking_size].clone()
                value, index = torch.sort(temp1.view(p, c, ranking_size ** 2))
                temp1 = value.view(p, c, ranking_size, ranking_size)
                y[:, :, i * ranking_size : (i + 1) * ranking_size, j * ranking_size : (j + 1) * ranking_size] = temp1
                temp2 = temp2.view(p, c, ranking_size ** 2).view(-1)
                index = index.view(-1)
                temp2 = temp2[index].view(p, c, ranking_size, ranking_size)
                ind[:, :, i * ranking_size : (i + 1) * ranking_size, j * ranking_size : (j + 1) * ranking_size] = temp2
        ctx.save_for_backward(ind)
        return y
    
    @staticmethod
    def backward(ctx, grad_y):
        index = ctx.saved_variables[0]
        p, c, h, w = grad_y.size()
        grad_y = grad_y.view(p, c, -1).contiguous()
        _, index = index.view(p, c, -1).sort()
        grad_y = grad_y.view(-1)[index.view(-1)]
        grad_y = grad_y.view(p, c, h, w)
        return grad_y, None

And this is my test code:

import torch
import RankingFunc

x = torch.rand((2, 2, 4, 4), requires_grad = True) * 100
y = RankingFunc.apply(x, 3)
z = y / 2

z_grad = torch.rand(2, 2, 4, 4) * 100
z.backward(z_grad)

There is just no output when I print(x.grad). Does anybody have any ideas? Thanks in advance!

Hi,

The problem is that you do * 100 after creating the leaf variable. So what you store in x is not the leaf variable for which the gradient is computed.

Thanks a lot! I got the result now