§
    E�’jIb  ã                  óh  — d dl mZ d dlZd dlmZmZmZ d dlZd dlm	Z	 d dlm
Z
 d dlmZ er
d dlmZmZmZ dNd	„ZdOd„ZdPd„ZdQd„ZdQd„Z	 dRdSd!„ZdTd&„Z	 dRdUd(„Z	 	 dVdWd.„ZdXd0„ZdYd2„Z G d3„ d4e	j        ¦  «        Z G d5„ d6e	j        ¦  «        Z	 dRdZd9„Z	 dRd[d;„Z d\d?„Z!d]dB„Z"	 	 d^d_dK„Z#	 	 d^d`dM„Z$dS )aé    )ÚannotationsN)ÚAnyÚNoReturnÚTYPE_CHECKING)ÚTensor)ÚNamedMemberAccessor)ÚCallableÚIterableÚSequenceÚreturnr   c                 ó    — t          d¦  «        ‚)Na$  make_functional(module): we don't yet support models that do parameter tying (also sometimes known as weight sharing). Please try to rewrite your model by replacing all instances of the tied parameter with another and/or comment your support in https://github.com/pytorch/functorch/issues/446)ÚRuntimeError© ó    úNC:\Projects\DSCons\.venv\Lib\site-packages\torch\_functorch\make_functional.pyÚraise_parameter_tying_errorr      s   € Ý
ð	:ñô ð r   Únamed_paramsú0dict[str, Tensor] | Iterable[tuple[str, Tensor]]Útied_named_paramsúdict[str, list[str]]c                óB  — t          | ¦  «        }t          |¦  «        }t          |                     ¦   «         ¦  «        }t          |                     ¦   «         ¦  «        }|                     |¦  «        st	          d|› d|› �¦  «        ‚i }|                     ¦   «         D ]\  }}|g f||<   Œ|                     ¦   «         D ]=\  }}||vrt	          d|› d�¦  «        ‚||         d                              |¦  «         Œ>t          |                     ¦   «         ¦  «        S )a[  
    named_params is a dictionary of tensors: {'A': A, 'B': B}
    tied_named_params is another dictionary of tensors {'A': A, 'B': B, 'B_tied': B}
    with potentially tied (or 'duplicated') tensors

    This function creates a mapping from the names in named_params to the
    names in tied_named_params: {'A': ['A'], 'B': ['B', 'B_tied']}.
    ztensors_dict_keys z+ is not a subset of tied_tensors_dict_keys ztensor for key 'z ' not found in tensor_to_mappingé   )ÚdictÚsetÚkeysÚissubsetÚAssertionErrorÚitemsÚappendÚvalues)	r   r   Únamed_params_dictÚtied_named_params_dictÚtensors_dict_keysÚtied_tensors_dict_keysÚtensor_to_mappingÚkeyÚtensors	            r   Úcreate_names_mapr(   $   sb  € õ ˜\Ñ*Ô*ÐÝ!Ð"3Ñ4Ô4ÐåÐ-×2Ò2Ñ4Ô4Ñ5Ô5ÐÝ Ð!7×!<Ò!<Ñ!>Ô!>Ñ?Ô?ÐØ×%Ò%Ð&<Ñ=Ô=ð 
Ýð?Ð!2ð ?ð ?Ø&<ð?ð ?ñ
ô 
ð 	
ð
 >@ÐØ(×.Ò.Ñ0Ô0ð .ð .‰ˆˆVØ%(¨" IÐ˜&Ñ!Ð!Ø-×3Ò3Ñ5Ô5ð 1ð 1‰ˆˆVØÐ*Ð*Ð*Ý ØH 3ÐHÐHÐHñô ð ð 	˜&Ô! !Ô$×+Ò+¨CÑ0Ô0Ð0Ð0ÝÐ!×(Ò(Ñ*Ô*Ñ+Ô+Ð+r   Úmodú	nn.ModuleÚnamed_membersú+Callable[..., Iterable[tuple[str, Tensor]]]ÚsubclassúCallable[[Tensor], Tensor]ú@tuple[tuple[Tensor, ...], tuple[str, ...], dict[str, list[str]]]c                ó”  — t           |d¬¦  «        ¦  «        }t           |d¬¦  «        ¦  «        }t          ||¦  «        }i }t          | ¦  «        }|D ]I\  }}	|	|vr" |t          j        |	d¬¦  «        ¦  «        ||	<   ||	         }
|                     ||
¦  «         ŒJt          |¦  «        dk    rd\  }}nt          |Ž \  }}|||fS )NF)Úremove_duplicateTÚmeta)Údevicer   ©r   r   )Útupler(   r   ÚtorchÚ
empty_likeÚ
set_tensorÚlenÚzip)r)   r+   r-   Úall_named_membersÚunique_named_membersÚ	names_mapÚmemoÚaccessorÚnameÚpÚreplacementÚnamesÚparamss                r   Ú_extract_membersrE   G   sû   € õ
 ˜m˜m¸UÐCÑCÔCÑDÔDÐÝ   ÀÐ!EÑ!EÔ!EÑFÔFÐÝ Ð!5Ð7HÑIÔI€Ið €DÝ" 3Ñ'Ô'€HØ$ð /ð /‰ˆˆaØ�Dˆ=ˆ=Ø�h�uÔ/°¸&ÐAÑAÔAÑBÔBˆD�‰GØ˜1”gˆØ×Ò˜D +Ñ.Ô.Ð.Ð.å
ÐÑ Ô  AÒ%Ð%Ø‰ˆˆvˆvåÐ1Ð2‰ˆˆvØ�5˜)Ð#Ð#r   c                óB   — t          | | j        t          j        ¦  «        S )aZ  
    This function removes all the Parameters from the model and
    return them as a tuple as well as their original attribute names.
    The weights must be re-loaded with `load_weights` before the model
    can be used again.
    Note that this function modifies the model in place and after this
    call, mod.parameters() will be empty.
    )rE   Únamed_parametersÚnnÚ	Parameter©r)   s    r   Úextract_weightsrK   a   s   € õ ˜C Ô!5µr´|ÑDÔDÐDr   c                ó0   — t          | | j        d„ ¦  «        S )Nc                ó   — | S ©Nr   )Úxs    r   ú<lambda>z!extract_buffers.<locals>.<lambda>r   s   € ¸a€ r   )rE   Únamed_buffersrJ   s    r   Úextract_buffersrR   o   s   € õ ˜C Ô!2°K°KÑ@Ô@Ð@r   FrC   úSequence[str]rD   úSequence[Tensor]Ú	as_paramsÚboolÚNonec                ól   — t          | ¦  «        }|rd„ |D ¦   «         }|                     ||¦  «         dS )a	  
    Reload a set of weights so that `mod` can be used again to perform a forward pass.
    Note that the `params` are regular Tensors (that can have history) and so are left
    as Tensors. This means that mod.parameters() will still be empty after this call.
    c                ó6   — g | ]}t          j        |¦  «        ‘ŒS r   )rH   rI   )Ú.0rA   s     r   ú
<listcomp>z load_weights.<locals>.<listcomp>‚   s    € Ð2Ð2Ð2 a•"”,˜q‘/”/Ð2Ð2Ð2r   N©r   Úset_tensors)r)   rC   rD   rU   r?   s        r   Úload_weightsr^   u   sH   € õ # 3Ñ'Ô'€HØð 3Ø2Ð2¨6Ð2Ñ2Ô2ˆØ×Ò˜ Ñ'Ô'Ð'Ð'Ð'r   r=   ÚelemsúIterable[Tensor]úlist[Tensor]c                ó4  — g }t          | ¦  «        }t          |                     ¦   «         |¦  «        D ]c\  \  }}}t          |¦  «        D ]K\  }}	|dk    r*|                     |                     |	|¦  «        ¦  «         Œ5|                     |	|¦  «         ŒLŒd|S )Nr   )r   r:   r   Ú	enumerater   Úswap_tensorr8   )
r)   r=   r_   Úresultr?   Ú_Ú
attr_namesÚelemÚiÚ	attr_names
             r   Ú_swap_staterk   †   s°   € ð €FÝ" 3Ñ'Ô'€HÝ!$ Y§_¢_Ñ%6Ô%6¸Ñ!>Ô!>ð 5ð 5Ñ‰ˆˆJ˜Ý% jÑ1Ô1ð 	5ð 	5‰LˆAˆyØ�AŠvˆvØ—’˜h×2Ò2°9¸dÑCÔCÑDÔDÐDÐDà×#Ò# I¨tÑ4Ô4Ð4Ð4ð		5ð
 €Mr   Úbuffersc                óP   — t          | ¦  «        }|                     ||¦  «         d S rN   r\   )r)   rC   rl   rU   r?   s        r   Úload_buffersrn   ”   s-   € õ # 3Ñ'Ô'€HØ×Ò˜ Ñ(Ô(Ð(Ð(Ð(r   r   ÚmodelÚweightsÚweight_namesÚbuffer_namesc                ó¬  — t          |¦  «        t          |¦  «        k    r/t          dt          |¦  «        › dt          |¦  «        › �¦  «        ‚t          | ||¦  «         t          |¦  «        dk    r`t          |¦  «        t          |¦  «        k    r/t          dt          |¦  «        › dt          |¦  «        › �¦  «        ‚t          | ||¦  «         | S )zæload_state(model, weights, weight_names, buffers=(), buffer_names=()) -> model

    load_state takes `weights` and `buffers` and assigns them to the model.
    This is the inverse operation of `make_functional_deprecated_v1`.
    zlen(weight_names)=z != len(weights)=r   zlen(buffer_names)=z != len(buffers)=)r9   r   r^   rn   )ro   rp   rq   rl   rr   s        r   Ú
load_statert   ž   sÚ   € õ ˆ<ÑÔ�C ™LœLÒ(Ð(ÝØS¥ \Ñ!2Ô!2ÐSÐSÅSÈÁ\Ä\ÐSÐSñ
ô 
ð 	
õ �˜ gÑ.Ô.Ð.Ý
ˆ7�|„|�aÒÐÝˆ|ÑÔ¥ G¡¤Ò,Ð,Ý ØW¥S¨Ñ%6Ô%6ÐWÐWÍÈWÉÌÐWÐWñô ð õ 	�U˜L¨'Ñ2Ô2Ð2Ø€Lr   ú>tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]c                óÊ   ‡ ‡— t          ‰                      ¦   «         ¦  «        }t          |¦  «        dk    rt          d¦  «        ‚t	          ‰ ¦  «        \  }Š}d
ˆˆ fd	„}||‰fS )a  make_functional_deprecated_v1(model) -> weights, func, weight_names

    Given an nn.Module, make_functional_deprecated_v1 extracts the state (weights)
    and returns a functional version of the model, `func`. This makes
    it so that it is possible use transforms over the parameters of
    `model`.

    `func` can be invoked as follows:
    ```
    x = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    weights, func, _ = make_functional_deprecated_v1(model)
    func(weights, (x,))
    ```

    And here is an example of applying the grad transform:
    ```
    x = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    weights, _, func = make_functional_deprecated_v1(model)
    grad_weights = grad(func)(weights, (x,))
    ```

    To put the state back into a model, use `load_state`.
    r   z€make_functional_deprecated_v1(model): `model` has buffers. Please use make_functional_with_buffers_deprecated_v1(model) instead.rp   útuple[Tensor, ...]Údataútuple[Any, ...]r   r   c                óX   •— t          j        ‰¦  «        }t          |‰| ¦  «          ||Ž S rN   )ÚcopyÚdeepcopyr^   )rp   rx   Úmutable_modelÚdescriptorsro   s      €€r   Úfunz*make_functional_deprecated_v1.<locals>.funÜ   s1   ø€ Ýœ eÑ,Ô,ˆÝ�] K°Ñ9Ô9Ð9Øˆ}˜dÐ#Ð#r   )rp   rw   rx   ry   r   r   )Úlistrl   r9   r   rK   )ro   rl   rp   rf   r   r~   s   `    @r   Úmake_functional_deprecated_v1r�   ¸   sŒ   øø€ õ8 �5—=’=‘?”?Ñ#Ô#€GÝ
ˆ7�|„|�aÒÐÝðIñ
ô 
ð 	
õ .¨eÑ4Ô4Ñ€Gˆ[˜!ð$ð $ð $ð $ð $ð $ð $ð
 �C˜Ð$Ð$r   úctuple[tuple[Tensor, ...], tuple[Tensor, ...], Callable[..., Any], tuple[str, ...], tuple[str, ...]]c                ór   ‡ ‡‡— t          ‰ ¦  «        \  }Š}t          ‰ ¦  «        \  }Š}d	ˆˆ ˆfd„}|||‰‰fS )
a`  make_functional_with_buffers_deprecated_v1(model) -> weights, buffers, func, weight_names, buffer_names

    Given an nn.Module, make_functional_with_buffers_deprecated_v1 extracts the state (weights and buffers)
    and returns a functional version of the model, `func`.

    `func` can be invoked as follows:
    ```
    x = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    weights, buffers, func, _, _ = make_functional_with_buffers_deprecated_v1(model)
    func(weights, buffers, (x,))
    ```

    And here is an example of applying the grad transform:
    ```
    x = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    weights, buffers, func, _, _ = make_functional_with_buffers_deprecated_v1(model)
    func(weights, buffers, (x,))
    grad_weights = grad(func)(weights, buffers, (x,))
    ```

    To put the state back into a model, use `load_state`.
    rp   rw   rl   rx   ry   r   r   c                óz   •— t          j        ‰¦  «        }t          |‰| ¦  «         t          |‰|¦  «          ||Ž S rN   )r{   r|   r^   rn   )rp   rl   rx   r}   Úbuf_descriptorsro   Úweight_descriptorss       €€€r   r   z7make_functional_with_buffers_deprecated_v1.<locals>.fun  sF   ø€ õ
 œ eÑ,Ô,ˆÝ�]Ð$6¸Ñ@Ô@Ð@Ý�] O°WÑ=Ô=Ð=Øˆ}˜dÐ#Ð#r   )rp   rw   rl   rw   rx   ry   r   r   )rK   rR   )ro   rp   rf   rl   r   r…   r†   s   `    @@r   Ú*make_functional_with_buffers_deprecated_v1r‡   ä   sm   øøø€ õB &5°UÑ%;Ô%;Ñ"€GÐ Ý"1°%Ñ"8Ô"8Ñ€Gˆ_˜að$ð $ð $ð $ð $ð $ð $ð $ð �G˜SÐ"4°oÐEÐEr   c                  óH   ‡ — e Zd ZdZdˆ fd„Ze	 ddd„¦   «         Zdd„Zˆ xZS )ÚFunctionalModuleWithBufferszW
    This is the callable object returned by :func:`make_functional_with_buffers`.
    Ústateless_modelr*   Úparam_namesútuple[str, ...]rr   Úparam_names_mapr   Úbuffer_names_mapr   rW   c                óÎ   •— t          ¦   «                              ¦   «          || _        || _        || _        t          |¦  «        | _        | j                             |¦  «         d S rN   )ÚsuperÚ__init__rŠ   r‹   rr   r   Úall_names_mapÚupdate)ÚselfrŠ   r‹   rr   r�   rŽ   Ú	__class__s         €r   r‘   z$FunctionalModuleWithBuffers.__init__  sa   ø€ õ 	‰Œ×ÒÑÔÐØ.ˆÔØ&ˆÔØ(ˆÔå! /Ñ2Ô2ˆÔØÔ×!Ò!Ð"2Ñ3Ô3Ð3Ð3Ð3r   Fro   Údisable_autograd_trackingrV   úJtuple[FunctionalModuleWithBuffers, tuple[Tensor, ...], tuple[Tensor, ...]]c                óÚ   — t          j        | ¦  «        }t          |¦  «        \  }}}t          |¦  «        \  }}}|r|D ]}	|	                     d¦  «         Œt          |||||¦  «        ||fS ©NF)r{   r|   rK   rR   Úrequires_grad_r‰   )
ro   r–   Ú
model_copyrD   r‹   r�   rl   rr   rŽ   Úparams
             r   Ú_create_fromz(FunctionalModuleWithBuffers._create_from*  s•   € õ
 ”] 5Ñ)Ô)ˆ
Ý/>¸zÑ/JÔ/JÑ,ˆ�˜_Ý2AÀ*Ñ2MÔ2MÑ/ˆ�Ð/Ø$ð 	,Øð ,ð ,�Ø×$Ò$ UÑ+Ô+Ð+Ð+å'Ø˜K¨°ÐHXñô ð Øð
ð 	
r   rD   r`   rl   Úargsr   Úkwargsc                ó  — t          | j        | j        t          |¦  «        t          |¦  «        z   ¦  «        }	  | j        |i |¤Žt          | j        | j        |¦  «         S # t          | j        | j        |¦  «         w xY wrN   )rk   rŠ   r’   r5   )r”   rD   rl   rž   rŸ   Ú	old_states         r   Úforwardz#FunctionalModuleWithBuffers.forward=  s‰   € õ  ØÔ ØÔÝ�&‰MŒM�E '™NœNÑ*ñ
ô 
ˆ	ð
	MØ'�4Ô'¨Ð8°Ð8Ð8õ ˜Ô,¨dÔ.@À)ÑLÔLÐLÐLø�K˜Ô,¨dÔ.@À)ÑLÔLÐLÐLøøøs   ºA" Á"A?)rŠ   r*   r‹   rŒ   rr   rŒ   r�   r   rŽ   r   r   rW   ©F©ro   r*   r–   rV   r   r—   )
rD   r`   rl   r`   rž   r   rŸ   r   r   r   ©	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r‘   Ústaticmethodr�   r¢   Ú__classcell__©r•   s   @r   r‰   r‰     s‹   ø€ € € € € ðð ð4ð 4ð 4ð 4ð 4ð 4ð  à<Að
ð 
ð 
ð 
ñ „\ð
ð$Mð Mð Mð Mð Mð Mð Mð Mr   r‰   c                  óH   ‡ — e Zd ZdZdˆ fd
„Ze	 ddd„¦   «         Zdd„Zˆ xZS )ÚFunctionalModulezJ
    This is the callable object returned by :func:`make_functional`.
    rŠ   r*   r‹   rŒ   r=   r   r   rW   c                ór   •— t          ¦   «                              ¦   «          || _        || _        || _        d S rN   )r�   r‘   rŠ   r‹   r=   )r”   rŠ   r‹   r=   r•   s       €r   r‘   zFunctionalModule.__init__V  s6   ø€ õ 	‰Œ×ÒÑÔÐØ.ˆÔØ&ˆÔØ"ˆŒˆˆr   Fro   r–   rV   ú+tuple[FunctionalModule, tuple[Tensor, ...]]c                ó®   — t          j        | ¦  «        }t          |¦  «        \  }}}|r|D ]}|                     d¦  «         Œt	          |||¦  «        |fS r™   )r{   r|   rK   rš   r®   )ro   r–   r›   rD   r‹   r=   rœ   s          r   r�   zFunctionalModule._create_froma  sl   € õ
 ”] 5Ñ)Ô)ˆ
Ý)8¸Ñ)DÔ)DÑ&ˆ�˜YØ$ð 	,Øð ,ð ,�Ø×$Ò$ UÑ+Ô+Ð+Ð+Ý 
¨K¸ÑCÔCÀVÐKÐKr   rD   r`   rž   r   rŸ   c                óÊ   — t          | j        | j        |¦  «        }	  | j        |i |¤Žt          | j        | j        |¦  «         S # t          | j        | j        |¦  «         w xY wrN   )rk   rŠ   r=   )r”   rD   rž   rŸ   r¡   s        r   r¢   zFunctionalModule.forwardm  sl   € å Ô 4°d´nÀfÑMÔMˆ	ð	IØ'�4Ô'¨Ð8°Ð8Ð8õ ˜Ô,¨d¬n¸iÑHÔHÐHÐHø�K˜Ô,¨d¬n¸iÑHÔHÐHÐHøøøs   �A ÁA")rŠ   r*   r‹   rŒ   r=   r   r   rW   r£   ©ro   r*   r–   rV   r   r°   )rD   r`   rž   r   rŸ   r   r   r   r¥   r¬   s   @r   r®   r®   Q  s�   ø€ € € € € ðð ð	#ð 	#ð 	#ð 	#ð 	#ð 	#ð à<Að	Lð 	Lð 	Lð 	Lñ „\ð	LðIð Ið Ið Ið Ið Ið Ið Ir   r®   r–   r°   c                óÀ   — t          |                      ¦   «         ¦  «        }t          |¦  «        dk    rt          d¦  «        ‚t                               | |¬¦  «        S )aÂ  make_functional(model, disable_autograd_tracking=False) -> func, params

    Given a ``torch.nn.Module``, :func:`make_functional` extracts the state
    (params) and returns a functional version of the model, ``func``. This
    makes it so that it is possible use transforms over the parameters of
    ``model``.

    ``func`` can be invoked as follows:

    .. code-block:: python

        import torch
        import torch.nn as nn
        from functorch import make_functional

        x = torch.randn(4, 3)
        model = nn.Linear(3, 3)
        func, params = make_functional(model)
        func(params, x)

    And here is an example of applying the grad transform over the parameters
    of a model.

    .. code-block:: python

        import torch
        import torch.nn as nn
        from functorch import make_functional, grad

        x = torch.randn(4, 3)
        t = torch.randn(4, 3)
        model = nn.Linear(3, 3)
        func, params = make_functional(model)


        def compute_loss(params, x, t):
            y = func(params, x)
            return nn.functional.mse_loss(y, t)


        grad_weights = grad(compute_loss)(params, x, t)

    If the model has any buffers, please use :func:`make_functional_with_buffers` instead.

    Args:
        model (torch.nn.Module): Input model.
        disable_autograd_tracking (bool): Flag to disable gradients tracking for output parameters.
            The returned params are unrelated to the set of params from the original model. If False (default),
            the params will have ``requires_grad=True`` on them (aka they will be trackable with regular
            PyTorch autograd), matching the requires_grad-ness of the params from the original model.
            Otherwise, the returned params will have ``requires_grad=False``. Default, False.
            If you plan on using regular PyTorch autograd (e.g., if you want to call ``.backward()`` or
            ``torch.autograd.grad()``, then set ``disable_autograd_tracking=False``.
            Otherwise, if you're only planning on using functorch's gradient transforms,
            then please set ``disable_autograd_tracking=True`` to avoid unnecessarily tracking
            history with PyTorch autograd.

    r   zdmake_functional(model): `model` has buffers. Please use make_functional_with_buffers(model) instead.©r–   )r€   rl   r9   r   r®   r�   )ro   r–   rl   s      r   Úmake_functionalr¶   w  sg   € õz �5—=’=‘?”?Ñ#Ô#€GÝ
ˆ7�|„|�aÒÐÝð;ñ
ô 
ð 	
õ ×(Ò(ØÐ)Bð )ñ ô ð r   r—   c                ó:   — t                                | |¬¦  «        S )aÀ  make_functional_with_buffers(model, disable_autograd_tracking=False) -> func, params, buffers

    Given a ``torch.nn.Module``, make_functional_with_buffers extracts the
    state (params and buffers) and returns a functional version of the model
    ``func`` that can be invoked like a function.

    ``func`` can be invoked as follows:

    .. code-block:: python

        import torch
        import torch.nn as nn
        from functorch import make_functional_with_buffers

        x = torch.randn(4, 3)
        model = nn.Linear(3, 3)
        func, params, buffers = make_functional_with_buffers(model)
        func(params, buffers, x)

    And here is an example of applying the grad transform over the parameters
    of a model:

    .. code-block:: python

        import torch
        import torch.nn as nn
        from functorch import make_functional_with_buffers, grad

        x = torch.randn(4, 3)
        t = torch.randn(4, 3)
        model = nn.Linear(3, 3)
        func, params, buffers = make_functional_with_buffers(model)


        def compute_loss(params, buffers, x, t):
            y = func(params, buffers, x)
            return nn.functional.mse_loss(y, t)


        grad_weights = grad(compute_loss)(params, buffers, x, t)

    Args:
        model (torch.nn.Module): Input model.
        disable_autograd_tracking (bool): Flag to disable gradients tracking for output parameters.
            The returned params are unrelated to the set of params from the original model. If False (default),
            the params will have ``requires_grad=True`` on them (aka they will be trackable with regular
            PyTorch autograd), matching the requires_grad-ness of the params from the original model.
            Otherwise, the returned params will have ``requires_grad=False``. Default, False.
            If you plan on using regular PyTorch autograd (e.g., if you want to call ``.backward()`` or
            ``torch.autograd.grad()``, then set ``disable_autograd_tracking=False``.
            Otherwise, if you're only planning on using functorch's gradient transforms,
            then please set ``disable_autograd_tracking=True`` to avoid unnecessarily tracking
            history with PyTorch autograd.

    rµ   )r‰   r�   )ro   r–   s     r   Úmake_functional_with_buffersr¸   ¿  s(   € õt '×3Ò3ØÐ)Bð 4ñ ô ð r   Útuple_of_tuple_of_tensorsútuple[tuple[Tensor, ...], ...]rw   c                ód   — t          t          | Ž ¦  «        } t          d„ | D ¦   «         ¦  «        }|S )Nc              3  ób   K  — | ]*}t          j        |¦  «                             ¦   «         V — Œ+d S rN   ©r6   ÚstackÚdetach©rZ   Úshardss     r   ú	<genexpr>z"transpose_stack.<locals>.<genexpr>  sI   è è € ð ð Ø)/�Œ�FÑÔ×"Ò"Ñ$Ô$ðð ð ð ð ð r   )r5   r:   )r¹   Úresultss     r   Útranspose_stackrÄ   þ  sJ   € õ !&¥cÐ+DÐ&EÑ FÔ FÐÝð ð Ø3Lðñ ô ñ ô €Gð €Nr   ÚmodelsúSequence[nn.Module]c                óÈ  ‡— t          | ¦  «        dk    rt          d¦  «        ‚t          d„ | D ¦   «         ¦  «        s(t          d„ | D ¦   «         ¦  «        st          d¦  «        ‚t          | d         ¦  «        Št          ˆfd„| D ¦   «         ¦  «        st          d¦  «        ‚t	          d„ | D ¦   «         Ž \  }}}t          |¦  «        }t          |¦  «        }|d         ||fS )	a(  combine_state_for_ensemble(models) -> func, params, buffers

    Prepares a list of torch.nn.Modules for ensembling with :func:`vmap`.

    Given a list of ``M`` ``nn.Modules`` of the same class, stacks all of their
    parameters and buffers together to make ``params`` and ``buffers``.
    Each parameter and buffer in the result will have an additional dimension
    of size ``M``.

    :func:`combine_state_for_ensemble` also returns ``func``, a functional
    version of one of the models in :attr:`models`. One cannot directly run
    ``func(params, buffers, *args, **kwargs)`` directly, you probably want to
    use ``vmap(func, ...)(params, buffers, *args, **kwargs)``

    Here's an example of how to ensemble over a very simple model:

    .. code-block:: python

        num_models = 5
        batch_size = 64
        in_features, out_features = 3, 3
        models = [torch.nn.Linear(in_features, out_features) for i in range(num_models)]
        data = torch.randn(batch_size, 3)

        fmodel, params, buffers = combine_state_for_ensemble(models)
        output = vmap(fmodel, (0, 0, None))(params, buffers, data)

        assert output.shape == (num_models, batch_size, out_features)

    .. warning::
        All of the modules being stacked together must be the same (except for
        the values of their parameters/buffers). For example, they should be in the
        same mode (training vs eval).

        This API is subject to change -- we're investigating better ways to
        create ensembles and would love your feedback how to improve this.
    r   z?combine_state_for_ensemble: Expected at least one model, got 0.c              3  ó$   K  — | ]}|j         V — Œd S rN   ©Útraining©rZ   Úms     r   rÂ   z-combine_state_for_ensemble.<locals>.<genexpr>4  s$   è è € Ð+Ð+˜q�”
Ð+Ð+Ð+Ð+Ð+Ð+r   c              3  ó&   K  — | ]}|j          V — Œd S rN   rÉ   rË   s     r   rÂ   z-combine_state_for_ensemble.<locals>.<genexpr>4  s&   è è € Ð2RÐ2RÀa°q´z°>Ð2RÐ2RÐ2RÐ2RÐ2RÐ2Rr   zTcombine_state_for_ensemble: Expected all models to have the same training/eval mode.c              3  ó:   •K  — | ]}t          |¦  «        ‰u V — Œd S rN   )Útype)rZ   rÌ   Ú
model0_typs     €r   rÂ   z-combine_state_for_ensemble.<locals>.<genexpr>:  s.   øè è € Ð5Ð5¨�t�A‰wŒw˜*Ð$Ð5Ð5Ð5Ð5Ð5Ð5r   zHcombine_state_for_ensemble: Expected all models to be of the same class.c                ó,   — g | ]}t          |¦  «        ‘ŒS r   )r¸   ©rZ   ro   s     r   r[   z.combine_state_for_ensemble.<locals>.<listcomp>?  s!   € Ð	BÐ	BÐ	B°%Õ
& uÑ
-Ô
-Ð	BÐ	BÐ	Br   )r9   r   ÚallrÏ   r:   rÄ   )rÅ   ÚfuncsrD   rl   rÐ   s       @r   Úcombine_state_for_ensemblerÕ     s  ø€ õP ˆ6�{„{�aÒÐÝØMñ
ô 
ð 	
õ Ð+Ð+ FÐ+Ñ+Ô+Ñ+Ô+ð 
­sÐ2RÐ2RÈ6Ð2RÑ2RÔ2RÑ/RÔ/Rð 
Ýð0ñ
ô 
ð 	
õ �f˜Q”i‘”€JÝÐ5Ð5Ð5Ð5¨fÐ5Ñ5Ô5Ñ5Ô5ð 
ÝØVñ
ô 
ð 	
õ !Ø	BÐ	B¸6Ð	BÑ	BÔ	BðÑ€Eˆ6�7õ ˜VÑ$Ô$€FÝ˜gÑ&Ô&€GØ�Œ8�V˜WÐ$Ð$r   ÚcpuÚmodel_classútype[nn.Module]Úensemble_shapeútuple[()] | tuple[int, ...]r3   útorch.types.DeviceúMCallable[..., tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]]c                ó   ‡ ‡‡— dˆˆˆ fd„}|S )Nrž   r   rŸ   r   ru   c                 ó*  •‡ ‡— t          ‰
¦  «        dk    rt          d¦  «        ‚t          ‰
¦  «        dk    r* ‰‰ i ‰¤Ž                     ‰	¦  «        }t          |¦  «        S ‰
d         }|dk    rt          d|› d�¦  «        ‚t	          ˆ ˆ	ˆˆfd„t          |¦  «        D ¦   «         ¦  «        }t           ‰‰ i ‰¤Ž¦  «        \  }}}t	          d„ |D ¦   «         ¦  «        }t	          t          |Ž ¦  «        }t	          d„ |D ¦   «         ¦  «        }|||fS )	Né   ú,NYI: ensemble_shape with more than 1 elementr   únum_models ú should be > 0c              3  óN   •K  — | ]} ‰‰i ‰¤Ž                      ‰¦  «        V — Œ d S rN   ©Úto©rZ   rf   rž   r3   rŸ   r×   s     €€€€r   rÂ   z3functional_init.<locals>.wrapped.<locals>.<genexpr>W  óQ   øè è € ð 
ð 
Ø89ˆKˆK˜Ð( Ð(Ð(×+Ò+¨FÑ3Ô3ð
ð 
ð 
ð 
ð 
ð 
r   c              3  ó@   K  — | ]}t          |¦  «        d          V — ŒdS )r   N)r�   rÒ   s     r   rÂ   z3functional_init.<locals>.wrapped.<locals>.<genexpr>[  s0   è è € ÐTÐTÀEÕ5°eÑ<Ô<¸QÔ?ÐTÐTÐTÐTÐTÐTr   c              3  ób   K  — | ]*}t          j        |¦  «                             ¦   «         V — Œ+d S rN   r½   rÀ   s     r   rÂ   z3functional_init.<locals>.wrapped.<locals>.<genexpr>]  ó8   è è € ÐKÐK¸�œ FÑ+Ô+×2Ò2Ñ4Ô4ÐKÐKÐKÐKÐKÐKr   )r9   Ú
ValueErrorrå   r�   r5   Úranger:   )rž   rŸ   ro   Ú
num_modelsrÅ   rf   ÚfnrC   rp   r3   rÙ   r×   s   ``       €€€r   Úwrappedz functional_init.<locals>.wrappedK  s_  øøø€ õ ˆ~ÑÔ !Ò#Ð#ÝÐKÑLÔLÐLÝˆ~ÑÔ !Ò#Ð#Ø�K Ð0¨Ð0Ð0×3Ò3°FÑ;Ô;ˆEÝ0°Ñ7Ô7Ð7Ø# AÔ&ˆ
Ø˜Š?ˆ?ÝÐE¨:ÐEÐEÐEÑFÔFÐFåð 
ð 
ð 
ð 
ð 
ð 
ð 
Ý=BÀ:Ñ=NÔ=Nð
ñ 
ô 
ñ 
ô 
ˆõ 5°[°[À$Ð5QÈ&Ð5QÐ5QÑRÔR‰ˆˆ2ˆuÝÐTÐTÈVÐTÑTÔTÑTÔTˆÝ�˜W˜Ñ&Ô&ˆÝÐKÐKÀ7ÐKÑKÔKÑKÔKˆØ˜˜EÐ!Ð!r   )rž   r   rŸ   r   r   ru   r   ©r×   rÙ   r3   rï   s   ``` r   Úfunctional_initrñ   F  s4   øøø€ ð
"ð "ð "ð "ð "ð "ð "ð "ð* €Nr   ú³Callable[..., tuple[tuple[Tensor, ...], tuple[Tensor, ...], Callable[..., Any], tuple[str, ...], tuple[str, ...]] | tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]]c                ó   ‡ ‡‡— dˆˆˆ fd„}|S )Nrž   r   rŸ   r   ú¤tuple[tuple[Tensor, ...], tuple[Tensor, ...], Callable[..., Any], tuple[str, ...], tuple[str, ...]] | tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]c                 ó¤  •‡ ‡— t          ‰¦  «        dk    rt          d¦  «        ‚t          ‰¦  «        dk    r* ‰‰ i ‰¤Ž                     ‰¦  «        }t          |¦  «        S ‰d         }|dk    rt          d|› d�¦  «        ‚t	          ˆ ˆˆˆfd„t          |¦  «        D ¦   «         ¦  «        }t           ‰‰ i ‰¤Ž¦  «        \  }}}}}t          t	          d„ |D ¦   «         ¦  «        Ž \  }	}
t	          t          |	Ž ¦  «        }	t	          d„ |	D ¦   «         ¦  «        }	t	          t          |
Ž ¦  «        }
t	          d	„ |
D ¦   «         ¦  «        }
|	|
|||fS )
Nrß   rà   r   rá   râ   c              3  óN   •K  — | ]} ‰‰i ‰¤Ž                      ‰¦  «        V — Œ d S rN   rä   ræ   s     €€€€r   rÂ   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>‡  rç   r   c              3  óD   K  — | ]}t          |¦  «        d d…         V — Œd S )Nrß   )r‡   rÒ   s     r   rÂ   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>’  sG   è è € ð ð àõ ;¸5ÑAÔAÀ"À1À"ÔEðð ð ð ð ð r   c              3  ób   K  — | ]*}t          j        |¦  «                             ¦   «         V — Œ+d S rN   r½   rÀ   s     r   rÂ   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>˜  rê   r   c              3  ób   K  — | ]*}t          j        |¦  «                             ¦   «         V — Œ+d S rN   r½   rÀ   s     r   rÂ   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>š  rê   r   )r9   rë   rå   r�   r5   rì   r‡   r:   )rž   rŸ   ro   rí   rÅ   rf   rî   rq   rr   rp   rl   r3   rÙ   r×   s   ``         €€€r   rï   z-functional_init_with_buffers.<locals>.wrappedr  sº  øøø€ õ ˆ~ÑÔ !Ò#Ð#ÝÐKÑLÔLÐLÝˆ~ÑÔ !Ò#Ð#Ø�K Ð0¨Ð0Ð0×3Ò3°FÑ;Ô;ˆEÝ0°Ñ7Ô7Ð7Ø# AÔ&ˆ
Ø˜Š?ˆ?ÝÐE¨:ÐEÐEÐEÑFÔFÐFåð 
ð 
ð 
ð 
ð 
ð 
ð 
Ý=BÀ:Ñ=NÔ=Nð
ñ 
ô 
ñ 
ô 
ˆõ 7°{°{ÀDÐ7SÈFÐ7SÐ7SÑTÔTñ	
ØØØØØåÝð ð à#ðñ ô ñ ô ð
Ñˆ�õ �˜W˜Ñ&Ô&ˆÝÐKÐKÀ7ÐKÑKÔKÑKÔKˆÝ�˜W˜Ñ&Ô&ˆÝÐKÐKÀ7ÐKÑKÔKÑKÔKˆØ˜  \°<Ð?Ð?r   )rž   r   rŸ   r   r   rô   r   rð   s   ``` r   Úfunctional_init_with_buffersrú   c  s=   øøø€ ð)@ð )@ð )@ð )@ð )@ð )@ð )@ð )@ðV €Nr   )r   r   )r   r   r   r   r   r   )r)   r*   r+   r,   r-   r.   r   r/   )r)   r*   r   r/   r£   )
r)   r*   rC   rS   rD   rT   rU   rV   r   rW   )r)   r*   r=   r   r_   r`   r   ra   )
r)   r*   rC   rS   rl   rT   rU   rV   r   rW   r4   )ro   r*   rp   rT   rq   rS   rl   rT   rr   rS   r   r*   )ro   r*   r   ru   )ro   r*   r   r‚   r³   r¤   )r¹   rº   r   rw   )rÅ   rÆ   r   r—   )r   rÖ   )r×   rØ   rÙ   rÚ   r3   rÛ   r   rÜ   )r×   rØ   rÙ   rÚ   r3   rÛ   r   rò   )%Ú
__future__r   r{   Útypingr   r   r   r6   Útorch.nnrH   r   Ú%torch.nn.utils._named_member_accessorr   Úcollections.abcr	   r
   r   r   r(   rE   rK   rR   r^   rk   rn   rt   r�   r‡   ÚModuler‰   r®   r¶   r¸   rÄ   rÕ   rñ   rú   r   r   r   ú<module>r     sÕ  ðð #Ð "Ð "Ð "Ð "Ð "à €€€Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /à €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø EÐ EÐ EÐ EÐ EÐ Eð ð =Ø<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<ðð ð ð ð ,ð  ,ð  ,ð  ,ðF$ð $ð $ð $ð4Eð Eð Eð EðAð Að Að Að ð	(ð (ð (ð (ð (ð"ð ð ð ð$ ð	)ð )ð )ð )ð )ð !#Ø"$ðð ð ð ð ð4)%ð )%ð )%ð )%ðX.Fð .Fð .Fð .Fðb9Mð 9Mð 9Mð 9Mð 9M "¤)ñ 9Mô 9Mð 9Mðx#Ið #Ið #Ið #Ið #I�r”yñ #Iô #Ið #IðN 9>ðEð Eð Eð Eð EðR 9>ð<ð <ð <ð <ð <ð~ð ð ð ð;%ð ;%ð ;%ð ;%ð@ 35Ø!&ðð ð ð ð ð> 35Ø!&ð:ð :ð :ð :ð :ð :ð :r   