Skip to content

Twice differentiability of pointwise functions#1531

Merged
soumith merged 8 commits intopytorch:masterfrom
t-vi:second_derivatives
May 15, 2017
Merged

Twice differentiability of pointwise functions#1531
soumith merged 8 commits intopytorch:masterfrom
t-vi:second_derivatives

Conversation

@t-vi
Copy link
Collaborator

@t-vi t-vi commented May 10, 2017

Hi,

this attempts to convert pointwise.py to new-style functions.

I have tried to stay to close to the original and close to the argument order of torch.foo functions (in particular AddCmul and AddCdiv).
Also, I am not 100% sure about the backward in _ConstantGrad - the old implementation had quite an elaborate allocation and I just wrote grad_output.mul(cls.grad_value) without fully understanding the motivation for the old code.

I have converted a few inplace computations to not inplace to deal with gradients being variables.

It seems to pass the test/test_autograd.py and flake8.

Thank you for considering this pull request.

Thomas

@t-vi
Copy link
Collaborator Author

t-vi commented May 10, 2017

O_o I should run the full test suite.

@t-vi t-vi closed this May 10, 2017
@apaszke apaszke reopened this May 10, 2017
return grad_output * i.mul(i).add(1).reciprocal()


class Reciprocal(Function):

This comment was marked as off-topic.

@staticmethod
def backward(ctx, grad_output):
i, = ctx.saved_variables
return grad_output * i.mul(i).add(1).reciprocal()

This comment was marked as off-topic.

@staticmethod
def backward(ctx, grad_output):
i, = ctx.saved_variables
return grad_output.mul(i.pow(-0.5)).div(2)

This comment was marked as off-topic.

@staticmethod
def backward(ctx, grad_output):
a, b = ctx.saved_variables
mask = a.gt(b).type_as(a)

This comment was marked as off-topic.

This comment was marked as off-topic.

grad_output * self._min_buffer,
grad_output * self._min_buffer.eq(0).type_as(grad_output)
grad_output * mask,
grad_output * mask.eq(0).type_as(grad_output)

This comment was marked as off-topic.

grad_input = grad_output.new(*repeat(1, grad_output.dim()))
grad_input = grad_input.fill_(self.grad_value).expand_as(grad_output)
return grad_input.mul(grad_output)
@classmethod

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

@staticmethod
def backward(ctx, grad_output):
return grad_output.mul(1 - ctx._weight), grad_output.mul(ctx._weight), None
# TODO: grad for weight?

This comment was marked as off-topic.

self.mark_dirty(add_tensor)
return add_tensor.addcmul_(self.scale, mul_tensor1, mul_tensor2)
@staticmethod
def forward(ctx, add_tensor, *args, **argsd):

This comment was marked as off-topic.

return add_tensor.addcmul_(self.scale, mul_tensor1, mul_tensor2)
@staticmethod
def forward(ctx, add_tensor, *args, **argsd):
inplace = argsd.get("inplace", False)

This comment was marked as off-topic.

self.mark_dirty(add_tensor)
return add_tensor.addcdiv_(self.scale, div_tensor1, div_tensor2)
@staticmethod
def forward(ctx, add_tensor, *args, **argsd):

This comment was marked as off-topic.

This comment was marked as off-topic.

@t-vi
Copy link
Collaborator Author

t-vi commented May 10, 2017

Thank you for helping me improve my code! I hope this is better.

Copy link
Contributor

@apaszke apaszke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just 3 minor comments and it's good to go!

if self.needs_input_grad[2]:
grad_mul2 = grad_output.mul(mul_tensor1).mul(self.scale)
if ctx.needs_input_grad[2]:
grad_mul2 = grad_output.mul(mul_tensor1).mul(ctx._scale)

This comment was marked as off-topic.

grad_div2.neg_().mul_(self.scale)

return grad_add, grad_div1, grad_div2
grad_div2 = grad_output.mul(div_tensor1).div(div_tensor2_sq).neg().mul(ctx._scale)

This comment was marked as off-topic.

This comment was marked as off-topic.

return op()(self, *args)
return op.apply(self, *args)

def addcmul(self, *args):

This comment was marked as off-topic.

@t-vi
Copy link
Collaborator Author

t-vi commented May 12, 2017

Trying to get the CI to try again

@t-vi t-vi closed this May 12, 2017
@t-vi t-vi reopened this May 12, 2017
@t-vi
Copy link
Collaborator Author

t-vi commented May 12, 2017

So I think I have the comments covered except for the inplace test which I understand is automatic and not manual.

grad_div2.neg_().mul_(self.scale)

return grad_add, grad_div1, grad_div2
grad_div2 = grad_output.mul(div_tensor1).div(div_tensor2_sq).neg_().mul_(ctx._scale)

This comment was marked as off-topic.

@apaszke
Copy link
Contributor

apaszke commented May 14, 2017

Can you please also fix the conflicts?

@soumith
Copy link
Collaborator

soumith commented May 15, 2017

I resolved conflicts and made that change.

@soumith
Copy link
Collaborator

soumith commented May 15, 2017

@pytorchbot test this please

@t-vi
Copy link
Collaborator Author

t-vi commented May 15, 2017

Hi

Apologies, I've been travelling with no access to my torch computer. Thanks for fixing my patches.
Best regards

Thomas

@soumith soumith merged commit 6107d15 into pytorch:master May 15, 2017
zasdfgbnm pushed a commit to zasdfgbnm/pytorch that referenced this pull request Mar 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants