
    sg]m                        d dl mZmZmZ d dlZd dlmc mZ d dl	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZmZmZmZmZ d dlmZ d dlmZ  G d	 d
e      Z e       Zej=                  ej>                        ej=                  ej@                        d               Z!d Z"dZ#e#fdZ$ G d de      Z%d Z&d Z'ej=                  ejP                        d        Z)d Z*d Z+ej=                  ejX                        d        Z-d Z.d Z/ G d d      Z0 G d de0      Z1 G d de0      Z2	 d$dZ3	 d$d Z4d! Z5 G d" d#e      Z6 e6       Z7y)%    )Any
NamedTupleTupleN)_unwrap_for_grad_wrap_for_gradcurrent_levelTransformType)vmap)%enable_single_level_autograd_function)_add_batch_dim_broadcast_to_and_flattenrestore_vmapunwrap_batchedwrap_batched)HigherOrderOperator)_set_fwd_grad_enabledc                   *     e Zd Zd fdZ fdZ xZS )!CustomFunctionHigherOrderOperatorc                 $    t         |   d       y )Ncustom_function_callsuper__init__self	__class__s    U/var/www/html/venv/lib/python3.12/site-packages/torch/_functorch/autograd_function.pyr   z*CustomFunctionHigherOrderOperator.__init__!   s    /0    c                     t         j                  j                         rt        |   |g|i |S  |j
                  |i |S N)torch_C _are_functorch_transforms_activer   __call__apply)r   autograd_functionargskwargsr   s       r   r$   z*CustomFunctionHigherOrderOperator.__call__$   sI     884467#$5GGGG& &&777r   returnN__name__
__module____qualname__r   r$   __classcell__r   s   @r   r   r       s    18 8r   r   c                 |    t        | |      }t               5   |j                  | }d d d        |S # 1 sw Y   S xY wr    )generate_single_level_functionr   r%   )interpreterr&   operands	Generatedflat_outs        r   custom_function_call_gradr7   X   sA     /{<MNI	.	0 ."9??H-.O.Os   1;c           
      (     j                          fd}fd}fd}fd}j                   d}t        |t        j                  j
                  j                  ft        |      t        |      t        |      t        |      d      }|S )Nc                  n   t        j                  t        j                  fd|       }t        j                         5  t        d      5  j                         5  t        g| }d d d        d d d        d d d        fd}t        || |      S # 1 sw Y   ,xY w# 1 sw Y   0xY w# 1 sw Y   4xY w)Nc                     t        |       S r    )r   )xlevels    r   <lambda>zAgenerate_single_level_function.<locals>.forward.<locals>.<lambda>f   s    $4Q$> r   Tc                     t        |       S r    )r   )outputr<   s    r   wrap_fnz@generate_single_level_function.<locals>.forward.<locals>.wrap_fnq   s    !&%00r   )	pytreetree_map_onlyr!   Tensorenable_gradr   lowerr   !wrap_outputs_maintaining_identity)r4   unwrapped_operandsunwrapped_outputr@   r&   r3   r<   s       r   forwardz/generate_single_level_function.<locals>.forwardd   s    #11LL>
   	"7"= 	{?P?P?R 	3! $6 	 	 		1 10(G
 	
	 	 	 	 	 	s;   B+
BB(B0B+BBB(	$B++B4c                 *    j                  | ||      S r    )setup_context)ctxinputsr?   r&   s      r   rK   z5generate_single_level_function.<locals>.setup_contextx   s     ..sFFCCr   c                 .     j                   | g| }|S r    )backward)rL   gradsresultr&   s      r   rO   z0generate_single_level_function.<locals>.backward|   s     +"++C8%8r   c                 .     j                   | g| }|S r    )jvp)rL   tangentsrQ   r&   s      r   rS   z+generate_single_level_function.<locals>.jvp   s     &"&&s6X6r   r5   )rI   rO   rS   rK   )r<   r,   typer!   autogradfunction_SingleLevelFunctionstaticmethod)	r3   r&   rI   rK   rO   rS   namer5   r<   s	   ``      @r   r2   r2   a   s    E
(D
  (()3D		 	 	5	57#G,$X.$)-8		
	I r   znot specifiedc           	         t        j                  | }t        j                  | }t        ||      D ci c]  \  }}t        |      | }	}}t        j                  |       \  }
}g }|t
        k7  }|r9t        ||      }|+t        d| dt        j                  |      d    d| d      t        |
      D ]  \  }}t        |t        j                        s|j                  |       2t        |      |	v r|j                  |	t        |                ]|r|j                   |||                {|j                   ||              t        j                  ||      S c c}}w )NzoThe autograd.Function's vmap staticmethod returned an incompatible (output, out_dims) tuple. Expected out_dims=zI to be compatible with the structure of `output`. out_dims has structure    z but output has structure zV. For more details, please see https://pytorch.org/docs/main/notes/extending.func.html)rA   arg_tree_leaveszipidtree_flattenNO_OUT_DIMSr   RuntimeError	enumerate
isinstancer!   rC   appendtree_unflatten)outputsunwrapped_inputsorig_inputsr@   out_dimsflat_unwrapped_inputsflat_orig_inputs	unwrappedorigunwrapped_input_to_orig_inputflat_outputsspecrQ   out_dims_specifiedflat_out_dimsir?   s                    r   rF   rF      s    #224DE--{;  ##8:JK%It 	9t%! %
  ,,W5L$F![01(DA  %%-J /**0*=*=h*G*J)K L,,06 2JK	 	 |, 
+	6&%,,/MM&!f:66MM76
CDMM'&-*:;<MM'&/*
+   ..M%s   E c                   "    e Zd ZU eed<   eed<   y)VmapInfo
batch_size
randomnessN)r,   r-   r.   int__annotations__str r   r   rv   rv      s    OOr   rv   c                 b    | j                   t        j                  j                  j                   uS r    )r
   r!   rV   Function)r&   s    r   has_overriden_vmap_ruler     s#    !!)@)@)E)EEEr   c                     d}t        | t              st        |dt        |        dz         t	        |       dk(  st        |dt	        |        dz         y )Nz}Expected the vmap staticmethod to have two returns, an output and out_dims with pytree structure compatible with the output. zGot a z instead   zGot z returns instead)rd   tuplerb   rU   len)rQ   base_error_msgs     r   +validate_vmap_returns_tuple_of_two_elementsr   	  se    	J  fe$>fT&\N(,KKLLv;!>d3v;-?O,PPQQ r   c                    t        d t        j                  j                  j	                  |      d   D              rt        d|       |j                  r1t        |      rt        d|j                   d      t        | |g| S t        |      st        d|j                   d      t        | |j                  |g|i |S )Nc              3   P   K   | ]  }t        |t        j                           y wr    )rd   r!   rC   ).0vals     r   	<genexpr>z,custom_function_call_vmap.<locals>.<genexpr>  s#       	3%s   $&r   z|Run vmap on autograd.Function with kwarg-only Tensor args. Please do not pass kwarg-only Tensors to autograd.Function. Got: zYou tried to vmap over a  , but it has both generate_vmap_rule=True and an overriden vmap staticmethod. Please set generate_vmap_rule=False or delete the overriden vmap staticmethod to avoid ambiguity. For more details, please see https://pytorch.org/docs/main/notes/extending.func.htmlz, but it does not have vmap support. Please override and implement the vmap staticmethod or set generate_vmap_rule=True. For more details, please see https://pytorch.org/docs/main/notes/extending.func.html)anyr!   utils_pytreer`   NotImplementedErrorgenerate_vmap_ruler   rb   r,   'custom_function_call_vmap_generate_rule custom_function_call_vmap_helperr
   )r3   r&   r4   r(   s       r   custom_function_call_vmapr     s   
 ;;&&33F;A>  "8
 	
 ++"#45 )*;*D*D)E FJ K  7*
-5
 	
 ##45 %&7&@&@%A BF G
 	
 ,&++->AIMS r   c                 R   | j                         t        | j                         | j                               }t	        |      \  }}t        j                  d |      re| j                         5  t        |t        j                  j                  j                        rt        |g| cd d d        S  ||i |cd d d        S | j                         5   |||g|i |}d d d        t               |\  }	}
fd}t        |	||||
      S # 1 sw Y   TxY w# 1 sw Y   :xY w)N)rw   rx   c                 
    | d u S r    r|   )dims    r   r=   z2custom_function_call_vmap_helper.<locals>.<lambda>L  s
    3$; r   c                 &    || S t        | |      S r    )r   )r?   out_dimr   s     r   r@   z1custom_function_call_vmap_helper.<locals>.wrap_fnY  s'      	
  ?	
r   )rj   )r<   rv   rw   rx   r   rA   tree_allrE   rd   r!   rV   rW   FunctionMetar   r   rF   )r3   vmap_functionopr4   r(   inforG   in_dimsrQ   rH   rj   r@   r   s               @r   r   r   @  s1     %%'M))+))+D #1="I .8  	/"enn55BBC+B::	/ 	/ 8.v.		/ 	/ 
			 MtWL/ALVLM/7!'h
 -,h( '	/ 	/M Ms   1:D5DDDD&c                 <   t        || j                               \  }}t        ||| j                         | j	                               \  }}| j                         5  t        |g| }d d d         |       }t        || j                               S # 1 sw Y   +xY wr    )r   r<   vmapify_autograd_functionrw   rx   rE   r   r   )	r3   r&   r4   rG   r   vmapped_functionget_out_dimsr?   rj   s	            r   r   r   e  s    "0;;L;L;N"O%>7K$:$:$<k>T>T>V&"l 
			 M%&6L9KLM ~H+*;*;*=>>	M Ms   BBc                     t        d      )Nz0NYI: Functionalize rule for custom_function_call)rb   )r3   r&   r   r4   s       r   "custom_function_call_functionalizer   r  s     I
JJr   c           
      J    d fd} fd} fd} fd}d j                    }t        |t        j                  j                  ft        |      t        |      t        |      t        |      dd      }	fd	}
|	|
fS )
Nznot populatedc                  D     t        j                        |  \  }|S r    )r   rI   )r4   rg   r&   rw   r   rj   rx   s     r   rI   z*vmapify_autograd_function.<locals>.forward  s4    
L%%w
J
 r   c                 Z     d d  fd} t        |
f      ||       	y )Nc                     t        t                     }j                  || |       t        d | D              |j                  y )Nc              3   l   K   | ],  }t        |t        j                        r|j                  nd  . y wr    )rd   r!   rC   shape)r   inps     r   r   zRvmapify_autograd_function.<locals>.setup_context.<locals>.inner.<locals>.<genexpr>  s+      "ILZU\\:		D"s   24)CtxCustomSaver   rK   r   _pt_saved_tensors_bdims)rM   rg   wrapped_ctxr&   rL   input_shapes_saved_tensors_bdims_s      r   innerz?vmapify_autograd_function.<locals>.setup_context.<locals>.inner  sL    
 (]_=K++KI " "PV" M $/#F#F r   )r   )rL   rM   rg   r   r   r   r&   rw   r   input_shapesrj   rx   saved_tensors_bdimss   `   @@r   rK   z0vmapify_autograd_function.<locals>.setup_context  sJ    #	G(	
h		

 '	 %2r   c                      
k7  sJ 
k7  sJ  fd}t        	|      } t        ||f       j                  |      \  }}t        ||      }|S )Nc                 B    t        |       } j                  |g| S r    )CtxWithSavedTensorsrS   )saved_tensorsrT   r   r&   rL   s      r   jvp_no_contextz>vmapify_autograd_function.<locals>.jvp.<locals>.jvp_no_context  s(    -c=AK($((@x@@r   )get_tangents_in_dimsr   r   	reductify)rL   rT   r   tangent_in_dimsout_tangentsout_tangents_dimsrQ   r&   rw   r   init_valrj   rx   r   s   `      r   rS   z&vmapify_autograd_function.<locals>.jvp  s    8###"h...	A /wA+
, /2	+

 

X+''' <):HjQr   c                      	k7  sJ 
	k7  sJ 	k7  sJ  fd} t        |ff       j                  |f      \  }}t        ||
      }|S )Nc                 L    | \  }}t        |      } j                  |g| S r    )r   rO   )rM   r   grad_outputsr   r&   rL   s       r   backward_no_contextzHvmapify_autograd_function.<locals>.backward.<locals>.backward_no_context  s2    *0'M<-c=AK-$--kILIIr   )r   r   r   )rL   r   r   grad_insgrad_ins_dimsrQ   r&   rw   r   r   r   rj   rx   r   s   `     r   rO   z+vmapify_autograd_function.<locals>.backward  s    8###x'''"h...	J
#
,!8,.	#

 l
+#-- 8]GZVr   VmappedT)rI   rO   rS   rK   r   c                       k7  sJ S r    r|   )r   rj   s   r   r   z/vmapify_autograd_function.<locals>.get_out_dims  s    8###r   )r,   rU   r!   rV   r~   rY   )r&   r   rw   rx   rI   rK   rS   rO   rZ   r5   r   r   r   rj   r   s   ````       @@@@r   r   r   y  s     HH L' "3 "3H & & &//01D		 	 "#G,$X.$)-8"&	

I l""r   c                     t        j                  |       \  }}t        j                  | }t        ||      D cg c]  \  }}|d n| }}}t        j                  ||      S c c}}w r    )rA   r`   r]   r^   rf   )
input_dimsrT   flat_in_dimsrq   flat_tangentsin_dimtangentrQ   s           r   r   r     st    ,,Z8L$**H5M  #<?FG V+F    ..	s   A#c                   8    e Zd ZU dZeedf   ed<   d Zd Zd Z	y)
WrappedCtx)_pt_reserved_attrs_pt_inner_ctx.r   c                     t        |t              s7t        |       j                  }|D ]  }t	        ||      st        d| d       || _        y )NzPyTorch reserves the zU field on ctx. Please name your fields on ctx something else to avoid name collision.)rd   r   rU   r   hasattrrb   r   )r   rL   reserved_attrsrZ   s       r   r   zWrappedCtx.__init__0  s`    #z*!$Z::N& sD)"+N+; <! !  !r   c                 .    t        | j                  |      S r    )getattrr   )r   rZ   s     r   __getattr__zWrappedCtx.__getattr__=  s    t))400r   c                 ~    |t        |       j                  v r|| j                  |<   y t        | j                  ||      S r    )rU   r   __dict__setattrr   )r   rZ   values      r   __setattr__zWrappedCtx.__setattr__@  s:    4:000"'DMM$t))477r   N)
r,   r-   r.   r   r   r{   rz   r   r   r   r|   r   r   r   r   -  s$    *Qc3hQ!18r   r   c                   N     e Zd Zdgej                  Z fdZed        Z xZS )r   _pt_new_saved_tensorsc                 2    t         |   |       || _        y r    )r   r   r   )r   rL   new_saved_tensorsr   s      r   r   zCtxWithSavedTensors.__init__K  s    %6"r   c                     | j                   S r    )r   )r   s    r   r   z!CtxWithSavedTensors.saved_tensorsO  s    )))r   )	r,   r-   r.   r   r   r   propertyr   r/   r0   s   @r   r   r   H  s0    1RJ4Q4QR7 * *r   r   c                   L     e Zd Zddgej                  Z fdZd Zd Z xZS )r   r   _pt_current_levelc                 @    t         |   |       d| _        || _        y )Nr|   )r   r   r   r   )r   rL   r   r   s      r   r   zCtxCustomSave.__init__[  s     ')$!.r   c                 v    t        || j                        \  }} | j                  j                  |  || _        y r    )r   r   r   save_for_backwardr   r   tensorsunwrapped_tensorsbdimss       r   r   zCtxCustomSave.save_for_backward`  s9    #1'4;Q;Q#R 5,,,.?@',$r   c                 v    t        || j                        \  }} | j                  j                  |  || _        y r    )r   r   r   save_for_forwardr   r   s       r   r   zCtxCustomSave.save_for_forwarde  s9    #1'4;Q;Q#R 5+++->?',$r   )	r,   r-   r.   r   r   r   r   r   r/   r0   s   @r   r   r   T  s0    ! 
	&	&/
-
-r   r   c           	          t        | t              s| f} t        |t              s|f}t        |t              s|f}|t        |       dz  }t        fdt        | |||      D              }|S )Nr    c              3   F   K   | ]  \  }}}}t        ||||        y wr    )reductify_leaf)r   gigi_bdimi_bdimmaybe_ishaperw   s        r   r   zreductify.<locals>.<genexpr>{  s.      -B 	r7FJEs   !)rd   r   r   r^   )
grad_inputgrad_input_bdim
input_bdimrw   &target_shape_without_bdim_to_reduce_torQ   s      `  r   r   r   k  s}     j%( ]
ou-*,j%( ]
-514Z71J. 142	2
 F Mr   c                 Z   | y ||| S ||| j                  |      S |J |>| j                  |      } t        | j                        }|||<   | j	                  |      } |}|/ t        t        j                  j                  |d f|      | |      S ||k7  r| j                  ||      } | S )N)r   rj   )
sum	unsqueezelistr   expandr
   r!   rC   sum_to_sizemovedim)r   r   r   rw   r   	new_shapes         r   r   r     s     :#5"z'9~~o..0 !!!))*5
))*	 *	*&&y1
$-9
tLL$$$d+
 <	> 	> _$''D
r   c                       fd}|S )Nc                 ,     |i |} | ||       |S r    r|   )rL   r'   r(   r?   original_forwardoriginal_setup_contexts       r   new_forwardz8autograd_function_forward_rewritten.<locals>.new_forward  s#    !4262sD&1r   r|   )r  r  r  s   `` r   #autograd_function_forward_rewrittenr    s    
 r   c                   &     e Zd Zd fdZd Z xZS )AutogradFunctionApplyc                 $    t         |   d       y )Nautograd_function_applyr   r   s    r   r   zAutogradFunctionApply.__init__  s    23r   c                    	
 d 
|d   }|d   	t        |      }d | } G 	
fddt        j                  j                        } |j                  | S )Nargs_tensor_masknon_differentiable_idxc                   >    e Zd Zefd       Ze fd       Zy)5AutogradFunctionApply.__call__.<locals>.ApplyTemplatec                      d g \  }	t              dkD  r:g }t        |      D ]  \  }}|v s|j                  |         | j                  |  |S )Nr   )r   rc   re   mark_non_differentiable)
rL   r'   r?   non_differentiable_outputrt   r;   fwdfwd_argsr  saved_valuess
         r   rI   z=AutogradFunctionApply.__call__.<locals>.ApplyTemplate.forward  sx     (+4';(';$ -.202- )& 1 @1 665<<Q?@ 0C//1JKr   c                      d g| S r    r|   )rL   gradbwdr  s     r   rO   z>AutogradFunctionApply.__call__.<locals>.ApplyTemplate.backward  s    46$666r   N)r,   r-   r.   rY   rI   rO   )r  r  r  r  r  s   r   ApplyTemplater    s)      7 7r   r  )r   r!   rV   r~   r%   )r   r  r  r  
fwd_kwargsr
  length_of_tensor_argsnew_fwd_argsr  r  r  s    ```     @@r   r$   zAutogradFunctionApply.__call__  sl    %&89!+,D!E #$4 5   6!67	7 	7ENN33 	7( #}""L11r   r)   r+   r0   s   @r   r  r    s    42r   r  r    )8typingr   r   r   r!   torch.utils._pytreer   r   rA   torch._C._functorchr   r   r   r	   torch._functorch.apisr
   torch._functorch.utilsr   torch._functorch.vmapr   r   r   r   r   
torch._opsr   torch.autograd.forward_adr   r   r   py_implGradJvpr7   r2   ra   rF   rv   r   r   Vmapr   r   r   Functionalizer   r   r   r   r   r   r   r   r  r  r  r|   r   r   <module>r(     sz   ) )  $ $  ' H  + ;8(; 84 9: < m001m//0 1 23~  ?J,/rz 
FR m001( 2(V"J
? m99:K ;Kp#j/~8 86	** 	*-J -8 ,0B ,08v"2/ "2J 01 r   