/usr/local/lib64/python3.6/site-packages/torch/autograd/__pycache__
Edit: /usr/local/lib64/python3.6/site-packages/torch/autograd/__pycache__/function.cpython-36.pyc (22587B)
3
EgX @ s~ d dl Z d dljZd dlmZ d dljjZd dlmZ d dl Z d dl
Z
d dlmZ d dl
mZmZmZ G dd deZeZG dd d eZG d
d dejeeZG dd
d
eZG dd deeejeeZdd Zdd ZG dd deZd0ddZdd Zd1ddZdd Z edd d!d"Z!ed#d d$ed%Z"ed&d d'd(d)Z#ed*d d+d"Z$ed,d d-d d$d"Z%G d.d/ d/eZ&dS )2 N)
_functions)with_metaclass)OrderedDict)AnyListOptionalc @ sR e Zd ZejdddZejdddZdd Zejdd d
Ze ddd
Z
dS )FunctionCtx)tensorsc G s
|| _ dS )a Saves given tensors for a future call to :func:`~Function.backward`.
**This should be called at most once, and only from inside the**
:func:`forward` **method. This should only be called with input or
output tensors**
In :func:`backward`, saved tensors can be accessed through the :attr:`saved_tensors`
attribute. Before returning them to the user, a check is made to ensure
they weren't used in any in-place operation that modified their content.
Arguments can also be ``None``. This is a no-op.
See :ref:`extending-autograd` for more details on how to use this method.
Example::
>>> class Func(Function):
>>> @staticmethod
>>> def forward(ctx, x: torch.Tensor, y: torch.Tensor, z: int):
>>> w = x * y * z
>>> out = x * y + y * z + w
>>> ctx.save_for_backward(x, y, out)
>>> ctx.z = z # z is not a tensor
>>> ctx.w = w # w is neither input nor output
>>> return out
>>>
>>> @staticmethod
>>> def backward(ctx, grad_out):
>>> x, y, out = ctx.saved_tensors
>>> z = ctx.z
>>> gx = grad_out * (y + y * z)
>>> gy = grad_out * (x + z + x * z)
>>> gz = None
>>> return gx, gy, gz
>>>
>>> a = torch.tensor(1., requires_grad=True, dtype=torch.double)
>>> b = torch.tensor(2., requires_grad=True, dtype=torch.double)
>>> c = 4
>>> d = Func.apply(a, b, c)
N)to_save)selfr r C/usr/local/lib64/python3.6/site-packages/torch/autograd/function.pysave_for_backward s )zFunctionCtx.save_for_backward)argsc G s
|| _ dS )a Marks given tensors as modified in an in-place operation.
**This should be called at most once, only from inside the**
:func:`forward` **method, and all arguments should be inputs.**
Every tensor that's been modified in-place in a call to :func:`forward`
should be given to this function, to ensure correctness of our checks.
It doesn't matter whether the function is called before or after
modification.
Examples::
>>> class Inplace(Function):
>>> @staticmethod
>>> def forward(ctx, x):
>>> x_npy = x.numpy() # x_npy shares storage with x
>>> x_npy += 1
>>> ctx.mark_dirty(x)
>>> return x
>>>
>>> @staticmethod
>>> @once_differentiable
>>> def backward(ctx, grad_output):
>>> return grad_output
>>>
>>> a = torch.tensor(1., requires_grad=True, dtype=torch.double).clone()
>>> b = a * a
>>> Inplace.apply(a) # This would lead to wrong gradients!
>>> # but the engine would not know unless we mark_dirty
>>> b.backward() # RuntimeError: one of the variables needed for gradient
>>> # computation has been modified by an inplace operation
N)
dirty_tensors)r r r r r
mark_dirty9 s !zFunctionCtx.mark_dirtyc G s t jd d S )Nzmark_shared_storage is deprecated. Tensors with shared storages are automatically tracked. Note that calls to `set_()` are not tracked)warningswarn)r pairsr r r
mark_shared_storage\ s zFunctionCtx.mark_shared_storagec G s
|| _ dS )a Marks outputs as non-differentiable.
**This should be called at most once, only from inside the**
:func:`forward` **method, and all arguments should be tensor outputs.**
This will mark outputs as not requiring gradients, increasing the
efficiency of backward computation. You still need to accept a gradient
for each output in :meth:`~Function.backward`, but it's always going to
be a zero tensor with the same shape as the shape of a corresponding
output.
This is used e.g. for indices returned from a sort. See example::
>>> class Func(Function):
>>> @staticmethod
>>> def forward(ctx, x):
>>> sorted, idx = x.sort()
>>> ctx.mark_non_differentiable(idx)
>>> ctx.save_for_backward(x, idx)
>>> return sorted, idx
>>>
>>> @staticmethod
>>> @once_differentiable
>>> def backward(ctx, g1, g2): # still need to accept g2
>>> x, idx = ctx.saved_tensors
>>> grad_input = torch.zeros_like(x)
>>> grad_input.index_add_(0, idx, g1)
>>> return grad_input
N)non_differentiable)r r r r r
mark_non_differentiableb s z#FunctionCtx.mark_non_differentiable)valuec C s
|| _ dS )a Sets whether to materialize output grad tensors. Default is ``True``.
**This should be called only from inside the** :func:`forward` **method**
If ``True``, undefined output grad tensors will be expanded to tensors full
of zeros prior to calling the :func:`backward` method.
Example::
>>> class SimpleFunc(Function):
>>> @staticmethod
>>> def forward(ctx, x):
>>> return x.clone(), x.clone()
>>>
>>> @staticmethod
>>> @once_differentiable
>>> def backward(ctx, g1, g2):
>>> return g1 + g2 # No check for None necessary
>>>
>>> # We modify SimpleFunc to handle non-materialized grad outputs
>>> class Func(Function):
>>> @staticmethod
>>> def forward(ctx, x):
>>> ctx.set_materialize_grads(False)
>>> ctx.save_for_backward(x)
>>> return x.clone(), x.clone()
>>>
>>> @staticmethod
>>> @once_differentiable
>>> def backward(ctx, g1, g2):
>>> x, = ctx.saved_tensors
>>> grad_input = torch.zeros_like(x)
>>> if g1 is not None: # We must check for None now
>>> grad_input += g1
>>> if g2 is not None:
>>> grad_input += g2
>>> return grad_input
>>>
>>> a = torch.tensor(1., requires_grad=True)
>>> b, _ = Func.apply(a) # induces g2 to be undefined
N)Zmaterialize_grads)r r r r r
set_materialize_grads s *z!FunctionCtx.set_materialize_gradsN)__name__
__module____qualname__torchTensorr r r r boolr r r r r
r s
+# r c @ s e Zd Zedd ZdS )
_HookMixinc C s* | d krt } tj| }|| |j<