Does it really work for you?
from torch.autograd import Function
from torch import tensor

class ManipulateGradient(Function):

    def forward(self, input):
        self.mark_dirty(input)
        print("forward Function")
        return input

    def backward(grad_out):
        # manipulate gradient here
        print("backward Function")
        return grad_out + 0.42

if __name__ == "__main__":
    layer = ManipulateGradientModule()
    input = tensor([1.0, 2.0, 3.0], requires_grad=True)
    result = layer.forward(input)
    print("result: ", result)
    dout = tensor([0.1, -0.1, 0.2])
    result.backward(dout)
    print("result.grad: ", input.grad)

Gives me:
forward Function
Traceback (most recent call last):
    result = layer.apply(input)
RuntimeError: a leaf Variable that requires grad has been used in an in-place operation.

Okay, let’s remove
self.mark_dirty(input)

Then we get:
forward Function
result:  tensor([1., 2., 3.], grad_fn=<FunctionBackward>)
Traceback (most recent call last):
  File "manipulate_gradient_non_static.py", line 22, in <module>
    result.backward(dout)
  File "python3.6/site-packages/torch/tensor.py", line 102, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "python3.6/site-packages/torch/autograd/__init__.py", line 90, in backward
    allow_unreachable=True)  # allow_unreachable flag
  File "python3.6/site-packages/torch/autograd/function.py", line 76, in apply
    return self._forward_cls.backward(self, *args)
  File "python3.6/site-packages/torch/autograd/function.py", line 180, in backward
    raise NotImplementedError
NotImplementedError


Let’s write a proper Function with @staticmethods:
class ManipulateGradientStatic(Function):

    @staticmethod
    def forward(ctx, input):
        # ManipulateGradientStatic.mark_dirty(input)
        print("forward static")
        return input

    @staticmethod
    def backward(ctx, grad_out):
        # manipulate gradient here
        print("backward static")
        return grad_out + 0.42

class ManipulateGradientModule(torch.nn.modules.Module):
    def __init__(self):
        super(ManipulateGradientModule, self).__init__()

    def forward(self, input):
        print("forward Module")
        return ManipulateGradientStatic.apply(input)

if __name__ == "__main__":
    layer = ManipulateGradientModule()
    input = tensor([1.0, 2.0, 3.0], requires_grad=True)
    result = layer.forward(input)
    print("result: ", result)
    dout = tensor([0.1, -0.1, 0.2])
    result.backward(dout)
    print("result.grad: ", input.grad)

Gives:
forward Module
forward static
result:  tensor([1., 2., 3.], grad_fn=<ManipulateGradientStaticBackward>)
backward static
result.grad:  tensor([0.5200, 0.3200, 0.6200])