
    Ǆg*.                         d dl Z d dlmc mZ d dlmZ d dlZd Zd Z	d Z
d Zd Zej                  d        Zd	 Zd
 Zd Zd Zd Zy)    N)
namedtuplec                 ,     t                fd}|S )Nc                  b   j                  d      r#j                  d      j                  } || i |S j                  d      sj                  d      rQj                  d      rdnd}|dk(  rdnd}j                  |      j                  }t	        d| d d| d| d	       | i |S )	Nautogradsave_for_backwardbackwardzWe found a 'z' registration for  at z but were unable to find a 'z' registration. To use the CustomOp API to register a backward formula, please provide us both a backward function and a 'save for backward' function via `impl_backward` and `impl_save_for_backward` respectively.)	_has_impl	_get_implfunclocationRuntimeError)argskwargskernelmissingfoundlocautograd_fallback	custom_ops         a/home/mcse/projects/flask_80/flask-venv/lib/python3.12/site-packages/torch/_custom_op/autograd.pyinnerz*autograd_kernel_indirection.<locals>.inner   s    z*((499F4*6**
 23y7J7J:7V'0':'::'F#  ,3j+@'jE%%e,55Cug%84%3G9 =9:; ; !$1&11    )autograd_not_implemented)r   r   r   s   ` @r   autograd_kernel_indirectionr      s    0;2. Lr   c                       fd}|S )Nc                      t        j                         r$t        j                  d | |f      rt	        d      t         j
                  j                         5   | i |cd d d        S # 1 sw Y   y xY w)Nc                 R    t        | t        j                        xr | j                  S N)
isinstancetorchTensorrequires_gradxs    r   <lambda>z:autograd_not_implemented.<locals>.kernel.<locals>.<lambda>4   s    jELL1Eaoo r   z.Autograd has not been implemented for operator)r!   is_grad_enabledpytreetree_anyr   _C_AutoDispatchBelowAutograd)r   r   r   s     r   r   z(autograd_not_implemented.<locals>.kernel2   sc      "vEf~(
 OPPXX002 	.d-f-	. 	. 	.s   A**A3 )r   r   s   ` r   r   r   1   s    . Mr   c                    |t        |t              s|f}n|}t        |      t        |      k(  sJ g }t        t	        ||            D ]z  \  }\  }}t        |t
        j                        r|s|j                  |       7t        |t              r|s|j                  |       [|s^t        d| d| dt        |       d       |r | j                  |  y y y )NzWith output_differentiability=z	. At idx z , we received an object of type za that is not a Tensor, so it cannot have be marked as differentiable in output_differentiability.)r    tuplelen	enumeratezipr!   r"   appendlistextendr   typemark_non_differentiable)ctxoutputoutput_differentiabilitytuple_outputnon_differentiable_tensorsidxdifferentiableouts           r   r6   r6   <   s      +&%("9L!L+,L0AAAA%'"*3C8PR^4_*` 	2&C&.##u||,%.55c:#t$%.55c:"45M4N O!U"B49+ N012 2	2 &'C'')CD &- ,r   c                 &      fd}|S )Nc                      t        j                  |       \  }d 
fd}	fd}t        	j                  dz   ||      } |j                  | }J t        j
                  t        |            S )Nc                    | j                  d       t        j                  t        |            }t        j
                  j                         5   | }d d d        t        t        j                  t        |            }t        |      } |      }t        | ||f       t        | |
       t        j                  |      \  }	t        |      S # 1 sw Y   xY w)NT)set_materialize_gradsr(   tree_unflattenr3   r!   r*   r+   namedtuple_argstree_mapr5   save_pytree_for_backwardr6   tree_flattenr.   )r7   	flat_argsr   r8   	args_infosave_for_backward_fn_inputsto_saveflat_outputop_overloadout_specr9   save_for_backward_fnschemaspecs           r   forwardz9construct_autograd_kernel.<locals>.apply.<locals>.forwardh   s    %%d+((i$?D446 ,$d+, (d35I +:&$*G'*+FOG$S7I*>?#C1IJ %+$7$7$?!K%%, ,s   CCc                     	J t        j                  t        |      	      }t        |       \  }}t	               }t        |t              s|f} ||g| }t        ||       t        ||      S r   )	r(   rC   r3   unpack_savedobjectr    r.   validate_grad_inputs_dictgrad_inputs_dict_to_flat_tuple)
r7   flat_grad_outputgradssavedrI   	inner_ctxgrad_inputs_dictbackward_fnr   rN   s
          r   r   z:construct_autograd_kernel.<locals>.apply.<locals>.backward|   s    '''))$/?*@(KE+C0E9 IeU+*9eDeD &&6	9M12BINNr   	_customop)r(   rG   gen_autograd_function_opnameapplyrC   r3   )r   rH   rR   r   generated_clsrL   rN   rQ   r]   r   rM   r9   rO   rP   s         @@r   ra   z(construct_autograd_kernel.<locals>.applyd   s     --d3	4	& 	&(	O  .+Wh@ *m))95###$$T+%6AAr   r,   )rP   r9   r   rM   rO   r]   ra   s   `````` r   construct_autograd_kernelrc   \   s    -B -B\ Lr   c                 |    t        | t        j                  j                  ft	        |      t	        |      d      }|S )N)rR   r   )r5   r!   r   Functionstaticmethod)namerR   r   rb   s       r   r_   r_      s<    		 	 "#G,$X.	
M r   c                     | j                   j                  D cg c]  }|j                   }}t        | j                        dz   }t	        ||      }|S c c}w )N_args)	argumentsflat_allrg   strr   )rP   argattribsrg   	tuple_clss        r   namedtuple_args_clsrp      sO    #)#3#3#<#<=Csxx=G=v{{g%D4)I	 >s   Ac                 F    t        |t              sJ t        |       } || S r   )r    r.   rp   )rP   r   ro   s      r   rD   rD      s'    dE"""#F+Idr   c                 `   fd}t        | t              s |dt        |               j                  j                  j
                  D ch c](  }|j                  j                         r|j                  * }}| j                         }||k7  r |d| d| d       | j                         D ]v  \  }}t        ||      }	t        |	t              rt        |t        t        f      s |d| dt        |       d       t        |      t        |	      k(  s# |d| d	t        |	       d
t        |              t        t        ||	            D ]n  \  }
\  }}|t        |t         j"                        s |d| dt        |       d|
        t%        |t         j"                        r[ |d| d|
 d|
 d|	        p |t        |t         j"                        s |dt        |       d| d       t%        |	t         j"                        re |d| d| d|	 d       y y c c}w )Nc                 b    j                  d      }t        d d|j                   d|        )Nr   z%In the backward function defined for r	   z using the CustomOp API, )r   r   r   )whatr   
forward_ops     r   errorz(validate_grad_inputs_dict.<locals>.error   sD    ''
33J<t  !!:4&BC 	Cr   zBexpected the output of the backward function to be a dict but got z3expected the returned grad_input dict to have keys z	 but got z. The backward function must return a gradient (can be None) for each arg to the CustomOp that may be a Tensor or Sequence[Tensor]. Args declared to be non-Tensor-like types should not appear in the grad_input dictzfor input 'zR' expected the grad_input dict to hold a list of gradients but got object of type .z1' expected the grad_input dict to hold a list of z gradients but got z\' expected the grad_input dict to hold a list of None or Tensor gradients but got object of z
 at index z(', got a Tensor as the gradient for the z(-th value but expected None because the z(-th value was not a Tensor (it was type zgot object of type z as the gradient for input 'z:', but expected the gradient to be either None or a Tensorz(got a Tensor as the gradient for input 'z3' but expected None as the gradient because input 'z ' was not a Tensor (it was type z).)r    dictr5   _schemarj   rk   is_tensor_likerg   keysitemsgetattrr3   r.   r/   r0   r1   r!   r"   
issubclass)r\   ru   rI   rv   rm   expected_keysactual_keysrg   gradarg_infor<   ginfos    `           r   rV   rV      s   C &- *+,. 	/ *4););)E)E)N)N 3#//1 XX 3M 3"'')K#Cy 6'( 	) ',,. #A
d9d+h%dUDM2D6 *IdA' ( t9H-D6 *((+H6IT% & #,Ch,?"@ .Ya9!!U\\2Kv .''+Awiz#@ A "$5Kv .%%(E *!!$ &""*- .. <$-'T
| 4V LM N (ELL1<TF CBBF H33;*B@ AC#A3s   -H+c                    g }|j                         j                         D ]D  \  }}|| vr'|j                  t        j                  d |             1|j                  | |          F t        t        j                  |            S )Nc                      y r   r,   r$   s    r   r&   z0grad_inputs_dict_to_flat_tuple.<locals>.<lambda>   s    r   )_asdictr|   r2   r(   rE   r.   tree_leaves)r\   rI   resultrg   r   s        r   rW   rW      sy    F#++-335 .h''MM&//.(CD&t,-	.
 ##F+,,r   c                 ^   t        j                  |      \  }}t        |      }t        |      D cg c]!  \  }}t	        |t
        j                        r|# }}}t        |      D cg c]!  \  }}t	        |t
        j                        s|# }}}|D cg c]  }t	        |t
        j                        s|! }	}|D cg c]  }t	        |t
        j                        r|! }
}|| _        || _         | j                  |	  || _
        |
| _        || _        y c c}}w c c}}w c c}w c c}w r   )r(   rG   r/   r0   r    r!   r"   rQ   num_eltsr   tensor_idxssaved_non_tensorsnon_tensor_idxs)r7   stuff
flat_stuffrQ   r   r<   thingr   r   tensorsnon_tensorss              r   rF   rF      s   **51J:H)2:)> 7:3 5  7K 7-6z-B ?zsE(=  ?O ?",P
5%,,0OuPGP&0XU
5%,,8W5XKXCHCLC7#!CO'C)C7?PXs#   &D)&DD%6D% D* D*c                    d g| j                   z  }t        | j                  | j                        D ]
  \  }}|||<    t        | j                  | j
                        D ]
  \  }}|||<    t        j                  || j                        }|S r   )	r   r1   saved_tensorsr   r   r   r(   rC   rQ   )r7   r   tensorr<   
non_tensorr   s         r   rT   rT     s    #,,&J3,,coo> ! 
3!s44c6I6IJ %
C$
3%!!*chh7ELr   )r!   torch.utils._pytreeutils_pytreer(   collectionsr   	functoolsr   r   r6   rc   r_   	lru_cacherp   rD   rV   rW   rF   rT   r,   r   r   <module>r      se     $ $ " >E@6r	  9Ax-*&r   