Hi,
I have been extending autograd following the instruction. However, after I call backward function, the gradients of variables are always None even the return of the extended backward function is not None at all.
The extended Op is as follows,
import torch
import _ext.cunnex
import pdb
from torch.autograd import Variable

class SeparableConvolution(torch.autograd.Function):

    @staticmethod
    def forward(ctx, input, vertical, horizontal):
        ctx.save_for_backward(input, vertical, horizontal)
        ctx.data_for_backward = input, vertical, horizontal
        intBatches = input.size(0)
        intInputDepth = input.size(1)
        intInputHeight = input.size(2)
        intInputWidth = input.size(3)
        intFilterSize = min(vertical.size(1), horizontal.size(1))
        intOutputHeight = min(vertical.size(2), horizontal.size(2))
        intOutputWidth = min(vertical.size(3), horizontal.size(3))

        assert(intInputHeight - 51 == intOutputHeight - 1)
        assert(intInputWidth - 51 == intOutputWidth - 1)
        assert(intFilterSize == 51)

        assert(input.is_contiguous() == True)
        assert(vertical.is_contiguous() == True)
        assert(horizontal.is_contiguous() == True)

        output = input.new().resize_(intBatches, intInputDepth, intOutputHeight, intOutputWidth).zero_()

        if input.is_cuda == True:
            _ext.cunnex.SeparableConvolution_cuda_forward(
                input,
                vertical,
                horizontal,
                output
            )

        elif input.is_cuda == False:
            raise NotImplementedError() # CPU VERSION NOT IMPLEMENTED

        # end
        return output
    # end
    @staticmethod
    def backward(ctx, grad_output):
        input, vertical, horizontal = ctx.data_for_backward
        intBatches = input.size(0)
        intInputDepth = input.size(1)
        intInputHeight = input.size(2)
        intInputWidth = input.size(3)
        intFilterSize = min(vertical.size(1), horizontal.size(1))
        intOutputHeight = min(vertical.size(2), horizontal.size(2))
        intOutputWidth = min(vertical.size(3), horizontal.size(3))

        grad_input = input.new().resize_(intBatches, intInputDepth, intInputHeight, intInputWidth).zero_()
        grad_vertical = vertical.new().resize_(intBatches, intFilterSize, intOutputHeight, intOutputWidth).zero_()
        grad_horizontal = horizontal.new().resize_(intBatches, intFilterSize, intOutputHeight, intOutputWidth).zero_()

        if grad_output.is_cuda == True:
            _ext.cunnex.SeparableConvolution_cuda_backward(
                grad_output.data,
                input,
                vertical,
                horizontal,
                grad_input,
                grad_vertical,
                grad_horizontal
            )

        elif grad_output.is_cuda == False:
            raise NotImplementedError() # CPU VERSION NOT IMPLEMENTED

        return Variable(grad_input), Variable(grad_vertical), Variable(grad_horizontal)

    # end
    # end


The detailed forward and backward methods, like ‘SeparableConvolution_cuda_forward’ and ‘SeparableConvolution_cuda_backward’  are implemented in CUDA. I have checked that ‘Variable(grad_input), Variable(grad_vertical)’ and ‘Variable(grad_horizontal)’ are torch tensors. I call this new operation above in a simple test case when GPU is available. However, when I print out gradients of inputs, they are always None.
The simple test case is,
import torch
from torch.autograd import Variable
from util.SeparableConvolution import SeparableConvolution
import math
import pdb

img = Variable(torch.zeros(1, 1, 51, 51), requires_grad=True).cuda()
img[0, 0, 25, 25] = 1
img[0, 0, 23, 24] = 5
v = Variable(torch.zeros(1, 51, 1, 1), requires_grad=True).cuda()
v[0, 25, 0, 0] = 2
v[0, 23, 0, 0] = 7
h = Variable(torch.zeros(1, 51, 1, 1), requires_grad=True).cuda()
h[0, 25, 0, 0] = 3
h[0, 24, 0, 0] = 11

input = img, v, h
output = SeparableConvolution.apply(*input)

gt = 389 * Variable(torch.ones(1, 1, 1, 1)).cuda()
loss_Lp = torch.nn.MSELoss()
loss = loss_Lp(output, gt)

loss.backward()
print(img.grad)
print(v.grad)
print(img.grad)


‘img.grad’, ‘v.grad’ and ‘h.grad’ are None. I cannot find the error in my code. Could anyone help me with this issue?
Best