
    %VjiX                     V   d dl Z d dlmZmZ d dlmZ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 defdZdeeeef         eeeef                  f         d	eeeef         eeeef                  f         deeee         f         fd
Zdej        dedeeeef                  f         deegef         deeedf         eedf         eeee         f         f         fdZdej        deeedf         eedf         eeee         f         f         fdZdej        deeedf         eedf         eeee         f         f         fdZ	 d5dej        dee         dee         deddf
dZdej        deeee         f         dee         dee         fdZ	 d5dej        dee         dee         deddf
dZ	 	 d6dej        dee         dee         dee         d ee         dej        fd!Zdej        fd"Zdej        fd#Z G d$ d%ej                  Z  G d& d'ej                  Z!	 d5dej        d(edee!eedf         f         fd)Z"	 d5dej        d(edee eedf         eedf         f         fd*Z#d+eeedf         df         deedf         fd,Z$d-eej                 dee eedf         eedf         f         fd.Z%	 	 d7d0e&ej                 d1eed         ee'         f         d2e	j(        j)        fd3Z*	 	 d7d0e&ej                 d1eed         ee'         f         d2e	j(        j)        fd4Z+dS )8    N)IterableSequence)AnyCallableNoReturnUnion)Tensor)NamedMemberAccessorreturnc                       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     Z/root/voice-cloning/.venv/lib/python3.11/site-packages/torch/_functorch/make_functional.pyraise_parameter_tying_errorr      s    
	:  r   named_paramstied_named_paramsc                    t          |           } t          |          }t          |                                           }t          |                                          }|                    |          sJ i }|                                 D ]\  }}|g f||<   |                                D ],\  }}||v sJ ||         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']}.
       )dictsetkeysissubsetitemsappendvalues)r   r   tensors_dict_keystied_tensors_dict_keystensor_to_mappingkeytensors          r   create_names_mapr"   !   s    %%L.//L--//00 !2!7!7!9!9::%%&<======?#))++ . .V%("I&!!(..00 1 1V*****&!!$++C0000!((**+++r   modnamed_members.subclassc                    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_membersr;   =   s    
 mmUCCCDD !E!E!EFF !57HIII D"3''H$ / /aD==hu/&AAABBDG1gD+....
  A%%vv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.
    )r;   named_parametersnn	Parameterr#   s    r   extract_weightsrA   V   s     C!5r|DDDr   c                 0    t          | | j        d           S )Nc                     | S Nr   )xs    r   <lambda>z!extract_buffers.<locals>.<lambda>g   s    a r   )r;   named_buffersr@   s    r   extract_buffersrH   d   s     C!2KK@@@r   Fr9   r:   	as_paramsc                 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   )r>   r?   ).0r7   s     r   
<listcomp>z load_weights.<locals>.<listcomp>w   s     222a",q//222r   Nr
   set_tensors)r#   r9   r:   rI   r5   s        r   load_weightsrP   j   sH     #3''H 3226222'''''r   r3   elemsc                 4   g }t          |           }t          |                                |          D ]c\  \  }}}t          |          D ]K\  }}	|dk    r*|                    |                    |	|                     5|                    |	|           Ld|S )Nr   )r
   r0   r   	enumerater   swap_tensorr.   )
r#   r3   rQ   resultr5   _
attr_nameselemi	attr_names
             r   _swap_stater[   {   s     F"3''H!$Y__%6%6!>!> 5 5J%j11 	5 	5LAyAvvh229dCCDDDD##It4444		5
 Mr   buffersc                 P    t          |           }|                    ||           d S rD   rN   )r#   r9   r\   rI   r5   s        r   load_buffersr^      s-     #3''H(((((r   r   modelweightsweight_namesbuffer_namesc                     t          |          t          |          k    sJ t          | ||           t          |          dk    r3t          |          t          |          k    sJ t          | ||           | S )zload_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`.
    r   )r/   rP   r^   )r_   r`   ra   r\   rb   s        r   
load_staterd      s|     |G,,,,g...
7||a<  CLL0000UL'222Lr   c                      t                                                     }t          |          dk    rt          d          t	                     \  }} 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   zmake_functional_deprecated_v1(model): `model` has buffers. Please use make_functional_with_buffers_deprecated_v1(model) instead.c                 X    t          j                  }t          ||             || S rD   )copydeepcopyrP   )r`   datamutable_modeldescriptorsr_   s      r   funz*make_functional_deprecated_v1.<locals>.fun   s1    e,,]K999}d##r   )listr\   r/   r   rA   )r_   r\   r`   rV   rl   rk   s   `    @r   make_functional_deprecated_v1rn      s    4 5==??##G
7||aI
 
 	
 .e44G[!$ $ $ $ $ $
 C$$r   c                 p     t                     \  }}t                     \  }} 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`.
    c                 z    t          j                  }t          ||            t          ||            || S rD   )rg   rh   rP   r^   )r`   r\   ri   rj   buf_descriptorsr_   weight_descriptorss       r   rl   z7make_functional_with_buffers_deprecated_v1.<locals>.fun   sD    e,,]$6@@@]OW===}d##r   )rA   rH   )r_   r`   rV   r\   rl   rq   rr   s   `    @@r   *make_functional_with_buffers_deprecated_v1rs      sg    2 &5U%;%;"G"1%"8"8G_a$ $ $ $ $ $ $ GS"4oEEr   c                   .    e Zd ZdZdej        deedf         deedf         deee	e         f         deee	e         f         dd	f fd
Z
e	 ddej        deded eedf         eedf         f         fd            Zdee         dee         defdZ xZS )FunctionalModuleWithBufferszW
    This is the callable object returned by :func:`make_functional_with_buffers`.
    stateless_modelparam_names.rb   param_names_mapbuffer_names_mapr   Nc                     t                                                       || _        || _        || _        t          |          | _        | j                            |           d S rD   )super__init__rv   rw   rb   r   all_names_mapupdate)selfrv   rw   rb   rx   ry   	__class__s         r   r|   z$FunctionalModuleWithBuffers.__init__   sa     	.&(!/22!!"233333r   Fr_   disable_autograd_trackingc                     t          j        |           }t          |          \  }}}t          |          \  }}}|r|D ]}	|	                    d           t          |||||          ||fS NF)rg   rh   rA   rH   requires_grad_ru   )
r_   r   
model_copyr:   rw   rx   r\   rb   ry   params
             r   _create_fromz(FunctionalModuleWithBuffers._create_from  s    
 ]5))
/>z/J/J,_2A*2M2M//$ 	, , ,$$U++++'KHX  
 	
r   r:   r\   c                    t          | j        | j        t          |          t          |          z             }	  | j        |i |t          | j        | j        |           S # t          | j        | j        |           w xY wrD   )r[   rv   r}   r+   )r   r:   r\   argskwargs	old_states         r   forwardz#FunctionalModuleWithBuffers.forward  s       &MME'NN*
 
	
	M'4'888 ,d.@)LLLLK,d.@)LLLLs   A" "A?F__name__
__module____qualname____doc__r>   Moduler+   strr   rm   r|   staticmethodboolr	   r   r   r   r   __classcell__r   s   @r   ru   ru      sP        44 38_4 CHo	4
 c49n-4 sDI~.4 
4 4 4 4 4 4  <A
 
y
59
	,eFCK.@%PSBTT	U
 
 
 \
$Mv&M19&1AM	M M M M M M M Mr   ru   c                        e Zd ZdZdej        deedf         deee	e         f         ddf fdZ
e	 dd
ej        deded eedf         f         fd            Zdee         defdZ xZS )FunctionalModulezJ
    This is the callable object returned by :func:`make_functional`.
    rv   rw   .r3   r   Nc                 r    t                                                       || _        || _        || _        d S rD   )r{   r|   rv   rw   r3   )r   rv   rw   r3   r   s       r   r|   zFunctionalModule.__init__3  s6     	.&"r   Fr_   r   c                     t          j        |           }t          |          \  }}}|r|D ]}|                    d           t	          |||          |fS r   )rg   rh   rA   r   r   )r_   r   r   r:   rw   r3   r   s          r   r   zFunctionalModule._create_from>  sl    
 ]5))
)8)D)D&Y$ 	, , ,$$U++++
KCCVKKr   r:   c                     t          | j        | j        |          }	  | j        |i |t          | j        | j        |           S # t          | j        | j        |           w xY wrD   )r[   rv   r3   )r   r:   r   r   r   s        r   r   zFunctionalModule.forwardJ  sl     4dnfMM		I'4'888 ,dniHHHHK,dniHHHHs   A A"r   r   r   s   @r   r   r   .  s        	#	# 38_	# T#Y'		#
 
	# 	# 	# 	# 	# 	# <A	L 	Ly	L59	L	!5#55	6	L 	L 	L \	LIhv. IC I I I I I I I I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   )rm   r\   r/   r   r   r   )r_   r   r\   s      r   make_functionalr   T  sg    z 5==??##G
7||a;
 
 	
 (()B )   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   )ru   r   )r_   r   s     r   make_functional_with_buffersr     s(    t '33)B 4   r   tuple_of_tuple_of_tensorsc                 d    t          t          |            } t          d | D                       }|S )Nc              3   b   K   | ]*}t          j        |                                          V  +d S rD   r,   stackdetachrL   shardss     r   	<genexpr>z"transpose_stack.<locals>.<genexpr>  sI        )/F""$$     r   )r+   r0   )r   resultss     r   transpose_stackr     sJ     !&c+D&E F F  3L    G Nr   modelsc                    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 rD   trainingrL   ms     r   r   z-combine_state_for_ensemble.<locals>.<genexpr>  s$      ++q
++++++r   c              3   &   K   | ]}|j          V  d S rD   r   r   s     r   r   z-combine_state_for_ensemble.<locals>.<genexpr>  s&      2R2Raqz>2R2R2R2R2R2Rr   zTcombine_state_for_ensemble: Expected all models to have the same training/eval mode.c              3   >   K   | ]}t          |          k    V  d S rD   )type)rL   r   
model0_typs     r   r   z-combine_state_for_ensemble.<locals>.<genexpr>  s.      55tAww*$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   rL   r_   s     r   rM   z.combine_state_for_ensemble.<locals>.<listcomp>  s!    	B	B	B%
&u
-
-	B	B	Br   )r/   r   allr   r0   r   )r   funcsr:   r\   r   s       @r   combine_state_for_ensembler     s   P 6{{aM
 
 	
 ++F+++++ 
s2R2R62R2R2R/R/R 
0
 
 	
 fQiJ5555f55555 
V
 
 	
 !	B	B6	B	B	BE67 V$$Fg&&G8VW$$r   cpumodel_classensemble_shaper)   c                       fd}|S )Nc                  *    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 rD   torL   rV   r   r)   r   r   s     r   r   z3functional_init.<locals>.wrapped.<locals>.<genexpr>2  Q       
 
89KK(((++F33
 
 
 
 
 
r   c              3   @   K   | ]}t          |          d          V  dS )r   N)rn   r   s     r   r   z3functional_init.<locals>.wrapped.<locals>.<genexpr>6  s0      TTE5e<<Q?TTTTTTr   c              3   b   K   | ]*}t          j        |                                          V  +d S rD   r   r   s     r   r   z3functional_init.<locals>.wrapped.<locals>.<genexpr>8  8      KKF++2244KKKKKKr   )r/   
ValueErrorr   rn   r+   ranger0   )r   r   r_   
num_modelsr   rV   fnr9   r`   r)   r   r   s   ``       r   wrappedz functional_init.<locals>.wrapped(  s]   ~!##KLLL~!##K00033F;;E0777#A&
??E:EEEFFF 
 
 
 
 
 
 
=B:=N=N
 
 
 
 
 5[[$5Q&5Q5QRR2uTTVTTTTTW&&KK7KKKKKE!!r   r   r   r   r)   r   s   ``` r   functional_initr   #  s/    
" " " " " " "& Nr   c                       fd}|S )Nc                      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 rD   r   r   s     r   r   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>M  r   r   c              3   D   K   | ]}t          |          d d         V  d S )Nr   )rs   r   s     r   r   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>X  sG         ;5AA"1"E     r   c              3   b   K   | ]*}t          j        |                                          V  +d S rD   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 rD   r   r   s     r   r   z@functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>`  r   r   )r/   r   r   rn   r+   r   rs   r0   )r   r   r_   r   r   rV   r   ra   rb   r`   r\   r)   r   r   s   ``         r   r   z-functional_init_with_buffers.<locals>.wrappedC  s   ~!##KLLL~!##K00033F;;E0777#A&
??E:EEEFFF 
 
 
 
 
 
 
=B:=N=N
 
 
 
 
 7{{D7SF7S7STT	
  #    
 W&&KK7KKKKKW&&KK7KKKKK\<??r   r   r   s   ``` r   functional_init_with_buffersr   >  s7    
@ @ @ @ @ @ @@ Nr   r   r*   )r   r   ),rg   collections.abcr   r   typingr   r   r   r   r,   torch.nnr>   r	   %torch.nn.utils._named_member_accessorr
   r   r   r   r+   rm   r"   r   r;   rA   rH   r   rP   r[   r^   rd   rn   rs   ru   r   r   r   r   r   r   inttypesDevicer   r   r   r   r   <module>r      s]    . . . . . . . . 1 1 1 1 1 1 1 1 1 1 1 1              E E E E E EX    ,S&[)8E#v+4F+GGH,T#v+.sF{9K0LLM, 
#tCy., , , ,8$	$C%V*<!==>$ x'($ 5uS#XS$s)^0DDE	$ $ $ $2E	E
5uS#XS$s)^0DDEE E E EA	A
5uS#XS$s)^0DDEA A A A 	( (	(C=( V( 	(
 
( ( ( ("	#CcN3<DV<L	&\   $ 	) )	)C=) f) 	)
 
) ) ) ) !#"$ 9f 3- f	
 3- Y   ('% '% '% '% '%T"Fbi "F "F "F "FJ5M 5M 5M 5M 5M") 5M 5M 5Mp#I #I #I #I #Iry #I #I #IN 9>E E9E15E
U63;//0E E E ER 9>< <9<15<
&fck(:E&#+<NNO< < < <~$U63;%7%<=
63;   ;%RY;%
&fck(:E&#+<NNO;% ;% ;% ;%@ 46!& bi%)U3Z/0 K   : 46!&% %bi%%)U3Z/0% K% % % % % %r   