+
    –°³j±Ž  ã            	       ó˜  € ^ RI t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	H
t
Ht ^ RIHtHt ^ RIt^ RIHt ^ RIHu Ht ^ RIHt ^ RIHt . R4Ot]P2                  ! 4       t]! R4      t]! R4      t]! R4      t ! R R4      t]t ! R R4      t  ! R R	]PB                  ]] 4      t" ! R R
]#4      t$ ! R R]PB                  ]] ]$R7      t% ! R R]%4      t&R R lt'R t(R t)R R lt* ! R  R]&4      t+R5R! lt,R" t-R6R# lt.R$ t/].! R% R&R'7      t0].! R( R)]-R*7      t1].! R+ R,R-R.7      t2].! R/ R0R'7      t3],! R1 R2 R)R'7      t4 ! R3 R]&4      t5R# )7é    N)ÚOrderedDict)ÚCallable)ÚAnyÚConcatenateÚTypeVar)Ú
deprecatedÚ	ParamSpec)Ú
_functions©Úcustom_function_callÚFunctionCtxÚBackwardCFunctionÚFunctionMetaÚFunctionÚInplaceFunctionÚNestedIOFunctionÚ_TÚ_RÚ_Pc                   ó¸   a € ] tR t^&t o V 3R lR ltV 3R lR ltV 3R lR lt]! R]R7      R	 4       t	V 3R
 lR lt
V 3R lR ltV 3R lR ltV 3R ltRtV tR# )r   c                ó4   <€ V ^8„  d   QhRS[ P                  /# ©é   Útensors©ÚtorchÚTensor)ÚformatÚ__classdict__s   "€ÚX/home/luca/screen-checking/.venv/lib/python3.14/site-packages/torch/autograd/function.pyÚ__annotate__ÚFunctionCtx.__annotate__)   s   ø€ ÷ ;ñ ;©%¯,©,ñ ;ó    c                ó   € Wn         R# )aÌ	  Save given tensors for a future call to :func:`~Function.backward`.

``save_for_backward`` should be called at most once, in either the
:func:`setup_context` or :func:`forward` methods, and only with tensors.

All tensors intended to be used in the backward pass should be saved
with ``save_for_backward`` (as opposed to directly on ``ctx``) to prevent
incorrect gradients and memory leaks, and enable the application of saved
tensor hooks. See :class:`torch.autograd.graph.saved_tensors_hooks`.
See :ref:`extending-autograd` for more details.

Note that if intermediary tensors, tensors that are neither inputs
nor outputs of :func:`forward`, are saved for backward, your custom Function
may not support double backward.
Custom Functions that do not support double backward should decorate their
:func:`backward` method with ``@once_differentiable`` so that performing
double backward raises an error. If you'd like to support double backward,
you can either recompute intermediaries based on the inputs during backward
or return the intermediaries as the outputs of the custom Function. See the
`double backward tutorial <https://pytorch.org/tutorials/intermediate/custom_function_double_backward_tutorial.html>`_
for more details.

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::

    >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_AUTOGRAD)
    >>> class Func(Function):
    >>>     @staticmethod
    >>>     def forward(ctx, x: torch.Tensor, y: torch.Tensor, z: int):
    >>>         w = x * z
    >>>         out = x * y + y * z + w * y
    >>>         ctx.save_for_backward(x, y, w, out)
    >>>         ctx.z = z  # z is not a tensor
    >>>         return out
    >>>
    >>>     @staticmethod
    >>>     @once_differentiable
    >>>     def backward(ctx, grad_out):
    >>>         x, y, w, out = ctx.saved_tensors
    >>>         z = ctx.z
    >>>         gx = grad_out * (y + y * z)
    >>>         gy = grad_out * (x + z + w)
    >>>         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   s   &*r    Úsave_for_backwardÚFunctionCtx.save_for_backward)   s
   € ðv Žr#   c                ó4   <€ V ^8„  d   QhRS[ P                  /# r   r   )r   r   s   "€r    r!   r"   f   s   ø€ ÷ 6)ñ 6)©¯©ñ 6)r#   c                ó†   € V F4  p\        V\        P                  4      '       d   K%  Vf   K+  \        R4      h	  Wn        R# )aæ  Save given tensors for a future call to :func:`~Function.jvp`.

``save_for_forward`` should be called at most once, in either the
:func:`setup_context` or :func:`forward` methods, and all arguments
should be tensors.

In :func:`jvp`, saved objects can be accessed through the :attr:`saved_tensors`
attribute.

Arguments can also be ``None``. This is a no-op.

See :ref:`extending-autograd` for more details on how to use this method.

Example::

    >>> # xdoctest: +SKIP
    >>> class Func(torch.autograd.Function):
    >>>     @staticmethod
    >>>     def forward(ctx, x: torch.Tensor, y: torch.Tensor, z: int):
    >>>         ctx.save_for_backward(x, y)
    >>>         ctx.save_for_forward(x, y)
    >>>         ctx.z = z
    >>>         return x * y * z
    >>>
    >>>     @staticmethod
    >>>     def jvp(ctx, x_t, y_t, _):
    >>>         x, y = ctx.saved_tensors
    >>>         z = ctx.z
    >>>         return z * (y * x_t + x * y_t)
    >>>
    >>>     @staticmethod
    >>>     def vjp(ctx, grad_out):
    >>>         x, y = ctx.saved_tensors
    >>>         z = ctx.z
    >>>         return z * grad_out * y, z * grad_out * x, None
    >>>
    >>>     a = torch.tensor(1., requires_grad=True, dtype=torch.double)
    >>>     t = torch.tensor(1., dtype=torch.double)
    >>>     b = torch.tensor(2., requires_grad=True, dtype=torch.double)
    >>>     c = 4
    >>>
    >>>     with fwAD.dual_level():
    >>>         a_dual = fwAD.make_dual(a, t)
    >>>         d = Func.apply(a_dual, b, c)

Nzgsave_for_forward expects all arguments to be tensors; you should save non-tensors as attributes on ctx.)Ú
isinstancer   r   ÚAssertionErrorÚsaved_for_forward)r&   r   Útensors   &* r    Úsave_for_forwardÚFunctionCtx.save_for_forwardf   s>   € ó^ ˆFÜ˜v¤u§|¡|×4Ô4¸¼Ü$ð=óð ñ ð ")Ör#   c                ó4   <€ V ^8„  d   QhRS[ P                  /# ©r   Úargsr   )r   r   s   "€r    r!   r"   ž   s   ø€ ÷ #"ñ #"¡§¡ñ #"r#   c                ó   € Wn         R# )a  Mark given tensors as modified in an in-place operation.

This should be called at most once, in either the :func:`setup_context`
or :func:`forward` methods, 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::
    >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_AUTOGRAD)
    >>> 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
    >>> # xdoctest: +SKIP
    >>> b.backward() # RuntimeError: one of the variables needed for gradient
    >>>              # computation has been modified by an inplace operation

N)Údirty_tensors©r&   r3   s   &*r    Ú
mark_dirtyÚFunctionCtx.mark_dirtyž   s   € ðF "Ör#   zˆ`mark_shared_storage` is deprecated. Tensors with shared storages are automatically tracked. Note that calls to `set_()` are not tracked)Úcategoryc                ó   € R # ©N© )r&   Úpairss   &*r    Úmark_shared_storageÚFunctionCtx.mark_shared_storageÃ   s   € ñ 	r#   c                ó4   <€ V ^8„  d   QhRS[ P                  /# r2   r   )r   r   s   "€r    r!   r"   Ì   s   ø€ ÷ 'ñ '©U¯\©\ñ 'r#   c                ó   € Wn         R# )aP  Mark outputs as non-differentiable.

This should be called at most once, in either the :func:`setup_context`
or :func:`forward` methods, 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_differentiabler6   s   &*r    Úmark_non_differentiableÚ#FunctionCtx.mark_non_differentiableÌ   s
   € ð< #'Ör#   c                ó"   <€ V ^8„  d   QhRRRR/# )r   Údtypesztorch.dtype | NoneÚreturnNr<   )r   r   s   "€r    r!   r"   ì   s   ø€ ÷ &)ñ &)Ð-Að &)Àdñ &)r#   c                óD   € V P                   e   \        R4      hWn         R# )a¦  Declare the gradient dtype for each of this Function's outputs.

This should be called at most once, from either the
:func:`setup_context` or :func:`forward` methods. The number of
declarations must match the number of returned values, and each argument
corresponds positionally to the output at the same index.

For each output, pass the dtype your backward should receive its
gradient in:

- Pass a :class:`torch.dtype` and the engine guarantees the gradient
  handed to backward has that dtype. This is only valid for a
  differentiable Tensor output.
- Pass ``None`` and the gradient is handed to backward with whatever
  dtype it already has. This is also the only valid choice for a
  non-Tensor or non-differentiable output, which has no gradient.
- Omit this call (or pass the output's own dtype) and the gradient is
  handed to backward in the output's dtype, which is the default.

For example::

    >>> # xdoctest: +SKIP
    >>> @staticmethod
    >>> def forward(ctx, x):
    >>>     t1 = x.sin()
    >>>     t2 = x.cos()
    >>>     t3 = x.tan()
    >>>     ctx.set_output_grad_dtype(torch.float32, t2.dtype, None, None)
    >>>     return t1, t2, t3, "not a tensor"

This ensures that backward receives ``t1``'s gradient in ``float32``,
keeps the default behavior for ``t2``'s gradient via ``t2.dtype``,
passes ``t3``'s gradient through uncast with ``None``, and uses ``None``
as the placeholder for the trailing non-Tensor output.
Nz-set_output_grad_dtype can only be called once)Úoutput_grad_dtypesÚRuntimeError)r&   rF   s   &*r    Úset_output_grad_dtypeÚ!FunctionCtx.set_output_grad_dtypeì   s#   € ðH ×"Ñ"Ò.ÜÐNÓOÐOØ"(Ör#   c                ó    <€ V ^8„  d   QhRS[ /# )r   Úvalue)Úbool)r   r   s   "€r    r!   r"     s   ø€ ÷ -'ñ -'©4ñ -'r#   c                ó   € Wn         R# )aØ  Set whether to materialize grad tensors. Default is ``True``.

This should be called only from either the :func:`setup_context` or
:func:`forward` methods.

If ``True``, undefined grad tensors will be expanded to tensors full of zeros
prior to calling the :func:`backward` and :func:`jvp` methods.

Example::

    >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_AUTOGRAD)
    >>> 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)Úmaterialize_grads)r&   rN   s   &&r    Úset_materialize_gradsÚ!FunctionCtx.set_materialize_grads  s   € ðZ "'Ör#   c                ó$   <€ V ^8„  d   Qh/ R;R&   # )r   z%tuple[torch.dtype | None, ...] | NonerI   r<   )r   r   s   "€r    r!   r"   &   s   ø‡ ‚ Ø?Ñ?ò r#   )r5   rQ   rB   rI   r-   r%   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r'   r/   r7   r   ÚFutureWarningr>   rC   rK   rR   Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r   s   @r    r   r   &   sq   ø‡ € ÷;ð ;÷z6)ð 6)÷p#"ð #"ñJ ð	6ð ô	ñóð÷'ð '÷@&)ð &)÷P-'ð -'÷] ƒ r#   c                   ó0   a € ] tR tRt o ]R 4       tRtV tR# )Ú
_HookMixiniH  c                ól   € V f   \        4       p \        P                  ! V 4      pWVP                  &   W3# r;   )r   ÚhooksÚRemovableHandleÚid)Úbackward_hooksÚhookÚhandles   && r    Ú_register_hookÚ_HookMixin._register_hookI  s4   € àÒ!Ü(›]ˆNÜ×&Ò& ~Ó6ˆØ$(�v—y‘yÑ!ØÐ%Ð%r#   r<   N)rU   rV   rW   rX   Ústaticmethodrg   r[   r\   r]   s   @r    r_   r_   H  s   ø‡ € Øñ&ó ö&r#   r_   c                   óB   a € ] tR tRt o RtR tR tR tR tR t	Rt
V tR	# )
r   iR  z<
This class is used for internal autograd work. Do not use.
c                óð   € V P                   P                  pV P                   P                  pV\        P                  Jd    V\        P                  Jd   \	        R 4      hV\        P                  Jd   V# T# )zsImplementing both 'backward' and 'vjp' for a custom Function is not allowed. You should only implement one of them.)Ú_forward_clsÚbackwardÚvjpr   rJ   )r&   Úbackward_fnÚvjp_fns   &  r    Ú_get_user_fnÚBackwardCFunction._get_user_fnW  sg   € Ø×'Ñ'×0Ñ0ˆØ×"Ñ"×&Ñ&ˆØœh×/Ñ/Ó/°FÄ(Ç,Á,Ó4NÜðóð ð
  ¤x§|¡|Ó3ˆvÐD¸ÐDr#   c                óŒ   € V P                  4       pV P                  p\        VRR4      '       d   \        V4      3pV! V .VO5!  # )zõ
Apply method used when executing this Node during the backward.

Called by the autograd engine (non-boxed path) and by direct
grad_fn.apply() calls. When boxed_grads_call is True, boxes
grads into a mutable list before calling user's backward.
Úboxed_grads_callF)rq   rl   ÚgetattrÚlist)r&   r3   Úuser_fnÚfwd_clss   &*  r    ÚapplyÚBackwardCFunction.applyb  sH   € ð ×#Ñ#Ó%ˆØ×#Ñ#ˆÜ�7Ð.°×6Ò6Ü˜“J�=ˆDÙ�tÐ#˜dÓ#Ð#r#   c                ó2   € V P                  4       ! V .VO5!  # )zµ
Apply method called by the autograd engine when boxed_grads_call
is True. Grads arrive as a single mutable list argument, allowing
backward to free individual grads mid-execution.
)rq   r6   s   &*r    Úapply_boxedÚBackwardCFunction.apply_boxedp  s   € ð × Ñ Ô" 4Ð/¨$Ó/Ð/r#   c                ó>   € V P                   P                  ! V .VO5!  # )zE
Apply method used when executing forward mode AD during the forward
)rl   Újvpr6   s   &*r    Ú	apply_jvpÚBackwardCFunction.apply_jvpx  s    € ð
 × Ñ ×$Ò$ TÐ1¨DÓ1Ð1r#   c                ó8   € V P                   P                  V 4      # r;   )rl   Ú_compiled_autograd_key)r&   s   &r    rƒ   Ú(BackwardCFunction._compiled_autograd_key  s   € Ø× Ñ ×7Ñ7¸Ó=Ð=r#   r<   N)rU   rV   rW   rX   Ú__doc__rq   ry   r|   r€   rƒ   r[   r\   r]   s   @r    r   r   R  s)   ø‡ € ñò	Eò$ò0ò2÷>ð >r#   c                   ó6   a a€ ] tR tRt oRtV 3R ltRtVtV ;t# )r   iƒ  zìFunction metaclass.

This metaclass sets up the following properties:
    _backward_cls: The Function class corresponding to the differentiated
        version of this function (which is generated on the fly by this
        metaclass).
c                ó’   <€ \        VR ,           \        3RV /4      p\        \        4      Vn        W@n        \        SV `  WV4       R# )ÚBackwardrl   N)Útyper   ÚnextÚAUTOGRAD_FUNCTION_COUNTERÚ_autograd_function_idÚ_backward_clsÚsuperÚ__init__)ÚclsÚnameÚbasesÚattrsro   Ú	__class__s   &&&& €r    r�   ÚFunctionMeta.__init__Œ  sG   ø€ ÜØ�:ÕÔ 1Ð3°nÀcÐ5Jó
ˆô -1Ô1JÓ,KˆÔ)Ø'Ôä‰Ñ˜ eÖ,r#   r<   ©	rU   rV   rW   rX   r…   r�   r[   r\   Ú__classcell__©r”   r   s   @@r    r   r   ƒ  s   ù‡ € ñ÷-õ -r#   c                   ó    a € ] tR tRt o ]V 3R lR l4       t]V 3R lR l4       t]V 3R lR l4       t]t Rt	 Rt
]V 3R	 lR
 l4       tRtV tR# )Ú_SingleLevelFunctioni–  c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[ /# )r   r3   ÚkwargsrG   ©r   )r   r   s   "€r    r!   Ú!_SingleLevelFunction.__annotate__š  s"   ø€ ÷ ,
ñ ,
‘sð ,
¡cð ,
©cñ ,
r#   c                 ó   € \        R4      h)a³  Define the forward of the custom autograd Function.

This function is to be overridden by all subclasses.
There are two ways to define forward:

Usage 1 (Combined forward and ctx)::

    @staticmethod
    def forward(ctx: Any, *args: Any, **kwargs: Any) -> Any:
        pass

- It must accept a context ctx as the first argument, followed by any
  number of arguments (tensors or other types).
- See :ref:`combining-forward-context` for more details

Usage 2 (Separate forward and ctx)::

    @staticmethod
    def forward(*args: Any, **kwargs: Any) -> Any:
        pass


    @staticmethod
    def setup_context(ctx: Any, inputs: Tuple[Any, ...], output: Any) -> None:
        pass

- The forward no longer accepts a ctx argument.
- Instead, you must also override the :meth:`torch.autograd.Function.setup_context`
  staticmethod to handle setting up the ``ctx`` object.
  ``output`` is the output of the forward, ``inputs`` are a Tuple of inputs
  to the forward.
- See :ref:`extending-autograd` for more details

The context can be used to store arbitrary data that can be then
retrieved during the backward pass. Tensors should not be stored
directly on `ctx` (though this is not currently enforced for
backward compatibility). Instead, tensors should be saved either with
:func:`ctx.save_for_backward` if they are intended to be used in
``backward`` (equivalently, ``vjp``) or :func:`ctx.save_for_forward`
if they are intended to be used for in ``jvp``.
zEYou must implement the forward function for custom autograd.Function.©ÚNotImplementedError)r3   rœ   s   *,r    ÚforwardÚ_SingleLevelFunction.forward™  s   € ôV "ØSó
ð 	
r#   c                óF   <€ V ^8„  d   QhRS[ RS[S[ R3,          RS[ RS[ /# )r   ÚctxÚinputs.ÚoutputrG   )r   Útuple)r   r   s   "€r    r!   rž   É  s7   ø€ ÷ Gñ G™3ð G©©c°3¨h­ð GÁð GÉñ Gr#   c                ó   € \        R4      h)a5  There are two ways to define the forward pass of an autograd.Function.

Either:

1. Override forward with the signature ``forward(ctx, *args, **kwargs)``.
   ``setup_context`` is not overridden. Setting up the ctx for backward
   happens inside the ``forward``.
2. Override forward with the signature ``forward(*args, **kwargs)`` and
   override ``setup_context``. Setting up the ctx for backward happens
   inside ``setup_context`` (as opposed to inside the ``forward``)

See :meth:`torch.autograd.Function.forward` and :ref:`extending-autograd` for more details.
z!setup_context is not implemented.r    )r¥   r¦   r§   s   &&&r    Úsetup_contextÚ"_SingleLevelFunction.setup_contextÈ  s   € ô "Ð"EÓFÐFr#   c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[ /# )r   r¥   Úgrad_outputsrG   r�   )r   r   s   "€r    r!   rž   Ú  s"   ø€ ÷ 
ñ 
‘cð 
©#ð 
±#ñ 
r#   c                ó   € \        R4      h)aI  Define a formula for differentiating the operation with backward mode automatic differentiation.

This function is to be overridden by all subclasses.
(Defining this function is equivalent to defining the ``vjp`` function.)

It must accept a context :attr:`ctx` as the first argument, followed by
as many outputs as the :func:`forward` returned (None will be passed in
for non tensor outputs of the forward function),
and it should return as many tensors, as there were inputs to
:func:`forward`. Each argument is the gradient w.r.t the given output,
and each returned value should be the gradient w.r.t. the
corresponding input. If an input is not a Tensor or is a Tensor not
requiring grads, you can just pass None as a gradient for that input.

The context can be used to retrieve tensors saved during the forward
pass. It also has an attribute :attr:`ctx.needs_input_grad` as a tuple
of booleans representing whether each input needs gradient. E.g.,
:func:`backward` will have ``ctx.needs_input_grad[0] = True`` if the
first input to :func:`forward` needs gradient computed w.r.t. the
output.
zwYou must implement either the backward or vjp method for your custom autograd.Function to use it with backward mode AD.r    )r¥   r­   s   &*r    rm   Ú_SingleLevelFunction.backwardÙ  s   € ô. "ðó
ð 	
r#   Fc                ó,   <€ V ^8„  d   QhRS[ RS[ RS[ /# )r   r¥   Úgrad_inputsrG   r�   )r   r   s   "€r    r!   rž     s"   ø€ ÷ 
ñ 
‘ð 
¡Cð 
©Cñ 
r#   c                ó   € \        R4      h)a  Define a formula for differentiating the operation with forward mode automatic differentiation.

This function is to be overridden by all subclasses.
It must accept a context :attr:`ctx` as the first argument, followed by
as many inputs as the :func:`forward` got (None will be passed in
for non tensor inputs of the forward function),
and it should return as many tensors as there were outputs to
:func:`forward`. Each argument is the gradient w.r.t the given input,
and each returned value should be the gradient w.r.t. the
corresponding output. If an output is not a Tensor or the function is not
differentiable with respect to that output, you can just pass None as a
gradient for that input.

You can use the :attr:`ctx` object to pass any value from the forward to this
functions.
z`You must implement the jvp function for custom autograd.Function to use it with forward mode AD.r    )r¥   r±   s   &*r    r   Ú_SingleLevelFunction.jvp  s   € ô$ "ð@ó
ð 	
r#   r<   N)rU   rV   rW   rX   ri   r¢   rª   rm   rn   Úclear_saved_tensors_on_accessrt   r   r[   r\   r]   s   @r    rš   rš   –  sw   ø‡ € ð ÷,
ó ð,
ð\ ÷Gó ðGð  ÷
ó ð
ð: €Cð
ð %*Ð!ð
ð Ðà÷
ó ö
r#   rš   )Ú	metaclassc                   ó�   a € ] tR tRt o RtR tR t Rt]R 4       t	]
P                  P                  R,          t]R 4       tR	tV tR
# )r   i+  aO  Base class to create custom `autograd.Function`.

To create a custom `autograd.Function`, subclass this class and implement
the :meth:`forward` and :meth:`backward` static methods. Then, to use your custom
op in the forward pass, call the class method ``apply``. Do not call
:meth:`forward` directly.

To ensure correctness and best performance, make sure you are calling the
correct methods on ``ctx`` and validating your backward function using
:func:`torch.autograd.gradcheck`.

See :ref:`extending-autograd` for more details on how to use this class.

Examples::

    >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_AUTOGRAD)
    >>> class Exp(Function):
    >>>     @staticmethod
    >>>     def forward(ctx, i):
    >>>         result = i.exp()
    >>>         ctx.save_for_backward(result)
    >>>         return result
    >>>
    >>>     @staticmethod
    >>>     def backward(ctx, grad_output):
    >>>         result, = ctx.saved_tensors
    >>>         return grad_output * result
    >>>
    >>> # Use it by calling the apply method:
    >>> # xdoctest: +SKIP
    >>> output = Exp.apply(input)
c                óZ   € \         P                  ! V P                   R 2\        ^R7       R# )zÐ should not be instantiated. Methods on autograd functions are all static, so you should invoke them on the class itself. Instantiating an autograd function will raise an error in a future version of PyTorch.)Ú
stacklevelN)ÚwarningsÚwarnr”   ÚDeprecationWarning©r&   r3   rœ   s   &*,r    r�   ÚFunction.__init__M  s*   € Ü�ŠØ�~‰~Ðð 4ð 4ô Ø÷	
r#   c                ó   € \        R 4      h)zÚLegacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function))rJ   r¼   s   &*,r    Ú__call__ÚFunction.__call__W  s   € Üð_ó
ð 	
r#   Fc                ó   € \        R4      h)aÛ  Define the behavior for this autograd.Function underneath :func:`torch.vmap`.

For a :func:`torch.autograd.Function` to support
:func:`torch.vmap`, you must either override this static method, or set
``generate_vmap_rule`` to ``True`` (you may not do both).

If you choose to override this staticmethod: it must accept

- an ``info`` object as the first argument. ``info.batch_size``
  specifies the size of the dimension being vmapped over,
  while ``info.randomness`` is the randomness option passed to
  :func:`torch.vmap`.
- an ``in_dims`` tuple as the second argument.
  For each arg in ``args``, ``in_dims`` has a corresponding
  ``Optional[int]``. It is ``None`` if the arg is not a Tensor or if
  the arg is not being vmapped over, otherwise, it is an integer
  specifying what dimension of the Tensor is being vmapped over.
- ``*args``, which is the same as the args to :meth:`~Function.forward`.

The return of the vmap staticmethod is a tuple of ``(output, out_dims)``.
Similar to ``in_dims``, ``out_dims`` should be of the same structure as
``output`` and contain one ``out_dim`` per output that specifies if the
output has the vmapped dimension and what index it is in.

Please see :ref:`func-autograd-function` for more details.
zrTo use autograd.Function with vmap, you must either override the vmap staticmethod or set generate_vmap_rule=True.r    )ÚinfoÚin_dimsr3   s   &&*r    ÚvmapÚFunction.vmapi  s   € ô8 "ð@ó
ð 	
r#   ry   c                ó   € V P                   3# r;   )rŒ   )r¥   s   &r    rƒ   ÚFunction._compiled_autograd_keyŒ  s   € à×)Ñ)Ð+Ð+r#   r<   N)rU   rV   rW   rX   r…   r�   r¿   Úgenerate_vmap_ruleri   rÄ   Ú_CÚ_FunctionBaseÚ__dict__ry   rƒ   r[   r\   r]   s   @r    r   r   +  s_   ø‡ € ñòB
ò
ðð Ðàñ
ó ð
ð@ ×Ñ×%Ñ% gÕ.€Eàñ,ó ö,r#   c          
      óÜ   € V ^8„  d   QhR\         \        \        3,          R\        P                  R\        P                  R\
        \        P                  \        P                  3,          /# )r   Úfuncr3   rœ   rG   )r   r   r   r3   rœ   r¨   )r   s   "r    r!   r!   ‘  sS   € ÷ .ñ .Ü
”2”s�7Õ
ð.ä
�'‰'ð.ô �I‰Ið.ô Œ2�7‰7”B—I‘IÐÕñ	.r#   c                 ó®   € \         P                  ! V 4      pVP                  ! T/ Vf   / MTB pVP                  4        VP                  VP
                  3# r;   )ÚinspectÚ	signatureÚbindÚapply_defaultsr3   rœ   )rÍ   r3   rœ   rÐ   Ú
bound_argss   &&&  r    Ú_bind_default_argsrÔ   ‘  sN   € ô
 ×!Ò! $Ó'€IØ—’ ÐL°²©"ÀFÑL€JØ×ÑÔØ�?‰?˜J×-Ñ-Ð-Ð-r#   c                 óB   € Vf   \        V .VO5!  # \        V .VO5/ VB # r;   r   )r�   r3   rœ   s   &&&r    Ú_call_custom_function_callrÖ   œ  s,   € Ø‚~Ü# CÐ/¨$Ó/Ð/Ü Ð5 dÒ5¨fÑ5Ð5r#   c                 ó(   € V \         P                  8g  # r;   )rš   rª   )Úfns   &r    Ú_is_setup_context_definedrÙ   ¢  s   € ØÔ%×3Ñ3Ñ3Ð3r#   c                ó¸   € V ^8„  d   QhR\         \        \        \        3,          \        3,          R\         \        \        \        3,          \        3,          /# )r   rØ   rG   )r   r   r   r   r   )r   s   "r    r!   r!   ¦  sB   € ÷ 0ñ 0Ü”œR¤˜VÕ$¤bÐ(Õ)ð0äŒkœ"œb˜&Õ!¤2Ð%Õ&ñ0r#   c                 óL   a € \         P                  ! S 4      R  V 3R ll4       pV# )c                óp   € V ^8„  d   QhR\         R\        P                  R\        P                  R\        /# )r   r¥   r3   rœ   rG   )r   r   r3   rœ   r   )r   s   "r    r!   Ú)once_differentiable.<locals>.__annotate__ª  s6   € ÷ *Bñ *B”Rð *B¤§¡ð *B´2·9±9ð *BÄñ *Br#   c                 ó  <€ \         P                  ! 4       ;_uu_ 4        S	! V .VO5/ VB pR R R 4       \         P                  ! 4       '       g   X# \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      pV'       g   X# \	        X\
        4      '       g   V3pMTp\        P                  ! R\        V4      4      pR pT! V Uu. uF
  q‡! V4      NK  	  up!  #   + '       g   i     LÅ; iu upi )Nc              3   ó~   "  € T F3  p\        V\        P                  4      ;'       d    VP                  x € K5  	  R # 5ir;   )r+   r   r   Úrequires_grad)Ú.0Úargs   & r    Ú	<genexpr>Ú7once_differentiable.<locals>.wrapper.<locals>.<genexpr>º  s/   é € ð 
ÙKOÀCŒJ�sœEŸL™LÓ)×?Ð?¨c×.?Ñ.?Ô?Ë4ùs   ‚%=¨=TFsR   trying to differentiate twice a function that was marked with @once_differentiablec                 ó<   € V e   V P                  4       p RV n        V # )NT)Údetachrà   )Úvars   &r    Úfake_requires_gradÚ@once_differentiable.<locals>.wrapper.<locals>.fake_requires_gradÎ  s   € ØŠØ—j‘j“l�Ø$(�Ô!ØˆJr#   )	r   Úno_gradÚis_grad_enabledÚanyr+   r¨   r
   ÚDelayedErrorÚlen)
r¥   r3   rœ   Úoutputsrà   Úoutputs_Úerr_fnrè   ÚvrØ   s
   &*,      €r    ÚwrapperÚ$once_differentiable.<locals>.wrapper©  sà   ø€ ä�]Š]�_�_Ù˜Ð.˜tÒ. vÑ.ˆG÷ ô ×$Ò$×&Ò&ØˆN÷ ›ñ 
ÙKOó
ŸŸšñ 
ÙKOó
ó 
ˆ÷ ØˆNä˜'¤5×)Ò)Ø�z‰HàˆHä×(Ò(ð)ä�‹Mó
ˆò	ñ ±xÓ@±x°!Ð*¨1Ö-±xÑ@ÑAÐA÷S �_üòR As   ŸC)ÃC<Ã)C9	)Ú	functoolsÚwraps)rØ   ró   s   f r    Úonce_differentiabler÷   ¦  s*   ø€ ô ‡_‚_�RÓ÷*Bó ð*BðX €Nr#   c                   ó:   a a€ ] tR tRt oRtRV 3R lltRtVtV ;t# )r   iÙ  úy
This class is here only for backward compatibility reasons.
Use :class:`Function` instead of this for any new use case.
c                ó0   <€ \         SV `  4        Wn        R # r;   )rŽ   r�   Úinplace)r&   rû   r”   s   &&€r    r�   ÚInplaceFunction.__init__ß  s   ø€ Ü‰ÑÔØŽr#   )rû   )Fr–   r˜   s   @@r    r   r   Ù  s   ù‡ € ñ÷
÷ r#   c                 ó    a aaa€ VV VV3R  loS# )c                 ó   <€ S! V 4      '       d	   S! V 4      # V f   R # \        V \        \        34      '       d?   V3R lV  4       p\        V R4      '       d   \	        V 4      ! V!  # \	        V 4      ! V4      # \        V \
        4      '       d   V  Uu/ uF  q"S! W,          4      bK  	  up# \        R\        P                  ! V 4      ,           S'       d   RS,           R,           ,           4      hR,           4      hu upi )Nc              3   ó4   <"  € T F  pS! V4      x € K  	  R # 5ir;   r<   )rá   ÚxÚ_maps   & €r    rã   Ú,_nested_map.<locals>._map.<locals>.<genexpr>ë  s   øé € Ð+¡s !‘d˜1—g�g£sùs   ƒÚ_fieldsúAAuto nesting doesn't know how to process an input object of type ú. Accepted types: ú, or lists/tuples of themÚ )	r+   rv   r¨   Úhasattrr‰   ÚdictÚ
ValueErrorr   Útypename)ÚobjÚmappedr   r  Ú	conditionÚcondition_msgrØ   s   &  €€€€r    r  Ú_nested_map.<locals>._mapå  sã   ø€ Ù�S�>Š>Ù�c“7ˆNØŠ[ÙÜ˜œd¤E˜]×+Ò+Ü+¡sÓ+ˆFÜ�s˜I×&Ò&ä˜C”y &Ñ)Ð)Ü˜”9˜VÓ$Ð$Ü˜œT×"Ò"Ù-0Ó1©S¨‘t˜C�F“|’O©SÑ1Ð1äð+ä—.’. Ó%õ&÷
 %ð )¨=Õ8Ð;VÕVõ	ó	ð 	ð õó	ð 	ùò 2s   ÂC;r<   )r  rØ   r  r  s   fff@r    Ú_nested_mapr  ä  s   û€ ÷ð ð2 €Kr#   c                 óJ   € \        V R 4      '       d   V P                  4       # V # )Ú_jit_unwrap)r  r  )r  s   &r    Ú_jit_unwrap_structuredr    s!   € Üˆs�M×"Ò"Ø�‰Ó Ð Ø€Jr#   c                 ó$   a aaaa€ VVV VV3R  loS# )c              3   ó  <"  € Se	   S! V 4      p S! V 4      '       d   V x € R # V f   R # \        V \        \        34      '       d   V  F  pS! V4       R j  x€L
  K  	  R # \        V \        4      '       d*   V P	                  4        F  pS! V4       R j  x€L
  K  	  R # S'       d   V x € R # \        R\        P                  ! V 4      ,           S'       d   RS,           R,           ,           4      hR,           4      h L¦ Li5i)Nr  r  r  r  )r+   rv   r¨   r	  Úvaluesr
  r   r  )r  ÚoÚ_iterÚallow_unknownr  r  Ú
conversions   & €€€€€r    r  Ú_iter_filter.<locals>._iter  sà   øé € ØÒ!Ù˜S“/ˆCÙ�S�>Š>ØŒIØŠ[ÙÜ˜œd¤E˜]×+Ò+Û�Ù  ›8×#Ò#ó ä˜œT×"Ò"à—Z‘Z–\�Ù  ›8×#Ò#ó "çØŒIäð+ä—.’. Ó%õ&÷
 %ð )¨=Õ8Ð;VÕVõ	ó	ð 	ð õó	ð 	ñ $ñ $ùs/   ƒDž8DÁC=Á>DÂC?ÂDÂ(ADÃ?Dr<   )r  r  r  r  r  s   ffff@r    Ú_iter_filterr    s   ü€ ÷ñ ð8 €Lr#   c                 ó.   a€ V3R  loS! W4      ^ ,          # )c                 óF  <€ . p\        VR 4      '       d   VP                  V 4      # \        V\        \        34      '       g   V ^ ,          V R,          3# V F5  pVf   VP                  V4       K  S! W4      w  r@VP                  V4       K7  	  \        V4      ! V4      V 3# )Ú	_jit_wrap:é   NN)r  r   r+   rv   r¨   Úappendr‰   )ÚinputÚprotoÚresÚeÚres_eÚunflatten_helpers   &&   €r    r(  Ú$_unflatten.<locals>.unflatten_helper*  s�   ø€ Ø)+ˆÜ�5˜+×&Ò&Ø—?‘? 5Ó)Ð)Ü˜%¤$¬ ×/Ò/Ø˜•8˜U 2�YÐ&Ð&ÛˆAØŠyØ—
‘
˜1–á/°Ó9‘�Ø—
‘
˜5Ö!ñ ô �EŒ{˜3Ó Ð&Ð&r#   r<   )r#  r$  r(  s   &&@r    Ú
_unflattenr*  '  s   ø€ õ'ñ ˜EÓ)¨!Õ,Ð,r#   c                 ób   € V R J ;'       g%    \        V \        P                  P                  4      # r;   )r+   r   rÉ   ÚValue©r  s   &r    Ú<lambda>r.  <  s"   € ˆa�4ˆi×8Ð8œ: a¬¯©¯©Ó8Ð8r#   zjit's Values or None)r  c                 ó6   € \        V \        P                  4      # r;   ©r+   r   r   ©r   s   &r    r.  r.  @  ó   € Œj˜œEŸL™LÔ)r#   ÚTensors)r  r  c                 ó6   € \        V \        P                  4      # r;   r0  r1  s   &r    r.  r.  E  r2  r#   TzTensors (permissive))r  r  c                 óN   € V R J ;'       g    \        V \        P                  4      # r;   r0  r-  s   &r    r.  r.  J  s   € ˆa�4ˆi×6Ð6œ: a¬¯©Ó6Ð6r#   zTensors or Nonec                 ó6   € \        V \        P                  4      # r;   r0  r1  s   &r    r.  r.  M  r2  r#   c                 ó   € V P                   # r;   )Údatar-  s   &r    r.  r.  M  s   € °Q·V²Vr#   c                   óÚ   a a€ ] tR tRt oRtV 3R ltV 3R ltV3R lR lt]tV3R lR lt	V3R	 lR
 lt
]V 3R l4       tV3R lR ltV3R lR ltV3R lR ltV3R lR ltRtVtV ;t# )r   iQ  rù   c                ó‚   <€ Wn         \        \        V4      4      p\        SV `  ! V!  p\        W0P                  4      pV# r;   )Ú_nested_inputr¨   Ú_iter_tensorsrŽ   Ú_do_forwardr*  Ú_nested_output)r&   r#  Ú
flat_inputÚflat_outputÚnested_tensorsr”   s   &*   €r    r=  ÚNestedIOFunction._do_forwardZ  s=   ø€ Ø"ÔÜœ=¨Ó/Ó0ˆ
Ü‘gÒ)¨:Ñ6ˆÜ# K×1DÑ1DÓEˆØÐr#   c                óJ   <€ W n         \        SV `	  W4      pV'       g   V =V =V# r;   )Úretain_variablesrŽ   Ú_do_backwardr>  Ú_to_save_nested)r&   Ú	gradientsrD  Úresultr”   s   &&& €r    rE  ÚNestedIOFunction._do_backwarda  s,   ø€ Ø 0ÔÜ‘Ñ% iÓBˆßØÐ#ØÐ$Øˆr#   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r   rG  rG   r�   )r   r   s   "€r    r!   ÚNestedIOFunction.__annotate__i  s   ø€ ÷ 1ñ 1¡3ð 1©3ñ 1r#   c                ót   € \        WP                  4      pV P                  ! V!  p\        \	        V4      4      # )z
Shared backward utility.
)r*  r>  Úbackward_extendedr¨   Ú_iter_None_tensors)r&   rG  Únested_gradientsrH  s   &*  r    rm   ÚNestedIOFunction.backwardi  s7   € ô & i×1DÑ1DÓEÐØ×'Ò'Ð)9Ñ:ˆÜÔ'¨Ó/Ó0Ð0r#   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r   r3   rG   r�   )r   r   s   "€r    r!   rK  s  s   ø€ ÷ ,ñ ,™Sð ,¡Sñ ,r#   c                ó„   € \        V P                  4      pV P                  ! V!  pV =W0n        \	        \        V4      4      # )z
Shared forward utility.
)Ú_map_tensor_datar;  Úforward_extendedr>  r¨   r<  )r&   r3   rA  rH  s   &*  r    r¢   ÚNestedIOFunction.forwards  s@   € ô *¨$×*<Ñ*<Ó=ˆØ×&Ò&¨Ñ7ˆØÐØ$ÔÜ”] 6Ó*Ó+Ð+r#   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   r3   rG   Nr�   )r   r   s   "€r    r!   rK  }  s   ø€ ÷ $ñ $¡sð $¨tñ $r#   c                óD   € \        \        V4      4      V n        Wn        R# )z)
See :meth:`Function.save_for_backward`.
N)r¨   r<  r%   rF  r6   s   &*r    r'   Ú"NestedIOFunction.save_for_backward}  s   € ô œ]¨4Ó0Ó1ˆŒØ#Ör#   c                óB   <€ \         SV `  p\        WP                  4      # )z%
See :meth:`Function.saved_tensors`.
)rŽ   Úsaved_tensorsr*  rF  )r&   Úflat_tensorsr”   s   & €r    rZ  ÚNestedIOFunction.saved_tensors„  s    ø€ ô
 ‘wÑ,ˆÜ˜,×(<Ñ(<Ó=Ð=r#   c                ó*   <€ V ^8„  d   QhRS[ RS[ RR/# ©r   r3   rœ   rG   Nr�   )r   r   s   "€r    r!   rK  Œ  s'   ø€ ÷ Bñ B¡ð B©sð B°tñ Br#   c                ó:   € \        \        W34      4      V n        R# )z"
See :meth:`Function.mark_dirty`.
N)r¨   r<  r5   r¼   s   &*,r    r7   ÚNestedIOFunction.mark_dirtyŒ  s   € ô #¤=°$°Ó#@ÓAˆÖr#   c                ó*   <€ V ^8„  d   QhRS[ RS[ RR/# r^  r�   )r   r   s   "€r    r!   rK  ’  s'   ø€ ÷ Gñ G©Sð G¹Cð GÀDñ Gr#   c                ó:   € \        \        W34      4      V n        R# )z/
See :meth:`Function.mark_non_differentiable`.
N)r¨   r<  rB   r¼   s   &*,r    rC   Ú(NestedIOFunction.mark_non_differentiable’  s   € ô #(¬°t°nÓ(EÓ"FˆÖr#   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   r#  rG   Nr�   )r   r   s   "€r    r!   rK  ˜  s   ø€ ÷ "ñ "¡sð "¨tñ "r#   c                ó   € \         h)z
User defined forward.
r    )r&   r#  s   &*r    rT  Ú!NestedIOFunction.forward_extended˜  ó
   € ô "Ð!r#   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   Úgrad_outputrG   Nr�   )r   r   s   "€r    r!   rK  ž  s   ø€ ÷ "ñ "©cð "°dñ "r#   c                ó   € \         h)z
User defined backward.
r    )r&   ri  s   &*r    rM  Ú"NestedIOFunction.backward_extendedž  rg  r#   )r;  r>  rF  r5   rB   rD  r%   )rU   rV   rW   rX   r…   r=  rE  rm   r¿   r¢   r'   ÚpropertyrZ  r7   rC   rT  rM  r[   r\   r—   r˜   s   @@r    r   r   Q  s~   ù‡ € ñõõ÷1ð 1ð €H÷,ð ,÷$ð $ð ô>ó ð>÷Bð B÷Gð G÷"ð "÷"÷ "ð "r#   )r   r   r   r   r÷   r   r   r;   )FNN)6rõ   rÏ   Ú	itertoolsr¹   Úcollectionsr   Úcollections.abcr   Útypingr   r   r   Útyping_extensionsr   r	   r   Útorch._CrÉ   Útorch.utils.hooksÚutilsra   r
   Ú"torch._functorch.autograd_functionr   Ú__all__Úcountr‹   r   r   r   r   Ú_ContextMethodMixinr_   rÊ   r   r‰   r   rš   r   rÔ   rÖ   rÙ   r÷   r   r  r  r  r*  Ú_iter_jit_valuesr<  Ú_iter_tensors_permissiverN  rS  r   r<   r#   r    Ú<module>r{     s{  ðã Û Û Û Ý #Ý $ß ,Ñ ,ß 3ã Ý ß !Ð !Ý Ý Cò€ð &ŸOšOÓ-Ð áˆTƒ]€ÙˆTƒ]€Ùˆtƒ_€÷['ñ ['ð~ "Ð ÷&ñ &ô.>˜×(Ñ(¨+°zô .>ôb-�4ô -ô&R
Ø×Ñ�k :¸õR
ôjc,Ð#ô c,õL.ò6ò4õ0ôf�hô ôò:ôò@-ñ(  Ù8Ø(ôÐ ñ Ù)ØØ%ô€ñ
 (Ù)ØØ(ôÐ ñ
 "Ù6ÐFWôÐ ñ Ù)Ñ+;È9ôÐ ô
Q"�xö Q"r#   