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