o
    h9                  	   @   s  d dl Z d dlm  mZ d dlmZmZmZ d dl	m
Z
 d dlmZmZ d dlmZmZmZ d dl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 d d
lm Z  d dl!m"Z"m#Z# G dd deZ$e$dddZ%edddZ&edddi d d ddZ'dd Z(dd Z)G dd de j*j+Z,dd Z-dd Z.dd Z/e&0ej1d d! Z2e&0ej3d"d# Z4e&0ed$d% Z5e&0ed&d' Z6e&0ej7d(d) Z8e&0e j9j:j;j7d*d+ Z<e&=ej> e&=ej? e&=ej@ e&=ejA e&=ejB dS ),    N)_ExcludeDispatchKeyGuardDispatchKeyDispatchKeySet)suspend_functionalization)	AOTConfigcreate_joint)#_unwrap_all_tensors_from_functional_wrap_all_tensors_to_functionalfunctionalize)!_has_potential_branch_input_alias$_has_potential_branch_input_mutation!UnsupportedAliasMutationException)HigherOrderOperator)FakeTensorMode)disable_proxy_modes_tracingmake_fxProxyTorchDispatchModetrack_tensor_tree)StorageWeakRef)_get_current_dispatch_mode_pop_mode_temporarilyc                   @   s   e Zd Zdd ZdS )
MapWrapperc                 G   s   t |g|R  S N)map_wrapper)selfxsargs r   Q/var/www/html/ai/venv/lib/python3.10/site-packages/functorch/experimental/_map.py__call__#   s   zMapWrapper.__call__N)__name__
__module____qualname__r   r   r   r   r   r   "   s    r   mapT)_deprecated_global_nsmap_implF)fw_compilerbw_compilerpartition_fndecompositionsnum_params_buffersaot_idkeep_inference_input_mutationsc              	      sL  |d  }|d  }t   t Y dd fddt|d D }fdd|D }t g ||R  }tdd |D rQtd	d
d |D  dfdd|D }t g ||R  }	W d    n1 sow   Y   fdd}
t|t| t|
g |||R  }|	|fW  d    S 1 sw   Y  d S )Nc                 S   sB   t | tjr| jtjkrtj|  |  | j| jdS | 	 S | S )N)dtyperequires_grad)

isinstancetorchTensorr-   boolempty_stridedsizestrider.   clonetr   r   r   from_funK   s   z$create_fw_bw_graph.<locals>.from_func                       g | ]} |qS r   r   .0r   r9   r   r   
<listcomp>X       z&create_fw_bw_graph.<locals>.<listcomp>r   c                    s$   g | ]}t |tjr |n|qS r   r/   r0   r1   r<   argr=   r   r   r>   Y   s    c                 s   s&    | ]}|d urt |tj V  qd S r   r@   r<   outr   r   r   	<genexpr>`   s    z%create_fw_bw_graph.<locals>.<genexpr>z?Expect outputs of map only contains tensors or None. Got types c                 S   s   g | ]}t |qS r   )typerC   r   r   r   r>   g   r?   .c                    r:   r   r   rC   r=   r   r   r>   i   r?   c            
         s   | d  }| d  }|d  }|d  }fdd}t |td}|t|t| dd |D \}}dd | D   fdd	}	t|	|S )
Nc                     s    |  }|dd |D fS )Nc                 S   s&   g | ]}t |tjr|jrd ndqS )TF)r/   r0   r1   r.   )r<   retr   r   r   r>   v   s    
zNcreate_fw_bw_graph.<locals>.joint_f.<locals>.fw_with_masks.<locals>.<listcomp>r   )r   fw_out)fr   r   fw_with_maskst   s   z:create_fw_bw_graph.<locals>.joint_f.<locals>.fw_with_masks)
aot_configc                 S   s   g | ]}|d ur|j r|qS r   )r.   )r<   gradr   r   r   r>      s
    z7create_fw_bw_graph.<locals>.joint_f.<locals>.<listcomp>c                 S   s$   h | ]}t |tjrt| qS r   )r/   r0   r1   r   _typed_storagerA   r   r   r   	<setcomp>   s    

z6create_fw_bw_graph.<locals>.joint_f.<locals>.<setcomp>c                    s(   t | tjrt|   v r|  S | S r   )r/   r0   r1   r   rN   r6   r7   input_storager   r   maybe_clone   s
   
z8create_fw_bw_graph.<locals>.joint_f.<locals>.maybe_clone)r   dummy_aot_configlistpytreetree_map)
example_argsjoint_mapped_argsr   mapped_inputmapped_gradsrK   joint_gradsrR   )rJ   joint_num_mappednum_mapped_argsrP   r   joint_fm   s"   	z#create_fw_bw_graph.<locals>.joint_f)	r   r   _unstack_pytreerU   rV   anyRuntimeErrorr   len)rJ   r_   r   	mapped_xspos_args
example_xsexample_pos_argsexample_flat_outexample_gradfw_graphr`   joint_graphr   )rJ   r9   r^   r_   r   create_fw_bw_graph5   s8   
$,$rm   c                    s   t |\}tdd |D std| dt|dd |D }|d d dkr1tdtfd	d|D rDtd
| dd  fdd}t t|g||R  S )Nc                 s       | ]	}t |tjV  qd S r   r@   )r<   r8   r   r   r   rE          zmap_wrapper.<locals>.<genexpr>z.Mapped xs can only consist of tensors. Got xs rG   c                 S      g | ]}|j qS r   shaper;   r   r   r   r>          zmap_wrapper.<locals>.<listcomp>r   z,Leading dimensions of mapped xs cannot be 0.c                 3   s    | ]	}|d   kV  qdS r   Nr   )r<   	cur_shapeleading_dim_sizer   r   rE      ro   z?Leading dimensions of mapped xs must be consistent. Got shapes c                     sB   t | d  } |g| d  R  }t |\}}||S r   )rU   tree_unflattentree_flatten)	flat_argsr   unflattened_outflat_outtmp_out_spec)rJ   r_   out_specxs_specr   r   flat_fn   s
   zmap_wrapper.<locals>.flat_fn)rU   ry   allrc   rd   rb   rx   r%   )rJ   r   r   flat_xsshapesr   r   )rJ   rw   r_   r~   r   r   r      s"   
	r   c                   @   s$   e Zd Zedd Zedd ZdS )MapAutogradOpc                 G   s\   | j |  || _|| _tj  g t||g|R  R W  d    S 1 s'w   Y  d S r   )save_for_backward_joint_graph_num_mapped_argsr0   _C_AutoDispatchBelowAutogradr%   )ctxrk   rl   r_   rz   r   r   r   forward   s   
$zMapAutogradOp.forwardc                 G   sX   | j }|d | j }|| jd  }t| j| jt| g|||R  }d d d g|R S r   )saved_tensorsr   r%   r   rd   )r   
flat_gradsfw_argsfw_mapped_argsrf   r]   r   r   r   backward   s   zMapAutogradOp.backwardN)r    r!   r"   staticmethodr   r   r   r   r   r   r      s
    
r   c                    s>  t |d | }t ||d  }|d jd  t|d }|}t|tjjs1t|g ||R  }t  |g ||R  }	 fdd}
t	
|
|	}W d    n1 sTw   Y  d }d}|std| }t| jj|rp|d7 }n|}|r_| jj|| ||g|R }t	
| jj|}| jjd||i dd}t||d | jd	S )
Nr   c                    s$   t | tjr| j g| jR  S | S r   )r/   r0   r1   expandrr   r7   rv   r   r   expand_tensor   s   z trace_map.<locals>.expand_tensorbody_graph_   call_functionr%   )name)constanttracer)rT   rr   ra   r/   r0   fxGraphModuler   r   rU   rV   hasattrr   rootregister_moduleunwrap_proxycreate_proxyr   )
proxy_modefunc_overloadrJ   
num_mappedr   r   rf   example_input
body_graphexample_outsr   expanded_outs	next_namei	candidate	node_args
proxy_args	out_proxyr   rv   r   	trace_map   s:   




r   c                    s   t | \ }tdd  D std  t fdd D s.tddd  D  t  }g }|D ]}|t || q6|S )Nc                 s   rn   r   r@   r;   r   r   r   rE     ro   z"_unstack_pytree.<locals>.<genexpr>zLeaves of xs must be Tensor c                 3   s(    | ]}|j d   d  j d  kV  qdS rt   rq   r;   r   r   r   rE     s   & z3Leaves of xs must have same leading dimension size c                 S   rp   r   rq   r;   r   r   r   r>     rs   z#_unstack_pytree.<locals>.<listcomp>)rU   ry   r   rc   zipappendrx   )r   inspecapytreestupler   r   r   ra      s   ra   c                 C   s   g }d }| D ]}t |\}}|| qt| }g }|D ]*}tdd |D r1|t| qtdd |D r@|d  qtd| dt ||S )Nc                 s   rn   r   r@   r<   leafr   r   r   rE     ro   z _stack_pytree.<locals>.<genexpr>c                 s   s    | ]}|d u V  qd S r   r   r   r   r   r   rE     s    zCannot stack rG   )	rU   ry   r   r   r   r0   stackrc   rx   )r   r|   r~   ptflat_ptbstacked_outleavesr   r   r   _stack_pytree  s   r   c                 G   sJ   |d | }||d  }g }t |D ]}|| g ||R   qt|S r   )ra   r   r   )rJ   r_   r   r   rf   r   inpr   r   r   	map_dense%  s   r   c                 G   s0   t | |g|R  \}}tj|||g|R  }|S r   )rm   r   apply)rJ   r_   r   rk   bw_graphr|   r   r   r   map_autograd/  s   r   c                 G   s|   t  }|d usJ dt &}|jr$t|t| |g|R  W  d    S t| |g|R  W  d    S 1 s7w   Y  d S )Nz5Mode should always be enabled for python fallback key)r   r   enable_tracingr   r%   )rJ   r   r   moder   r   r   map_proxy_torch_dispatch_mode6  s   $r   c                 G   s   t | |g|R  S r   )r   )rJ   r   r   r   r   r   map_fake_tensor_modeA  s   r   c              	   G   s  t j }|d | }||d  }t||d}t||d}|r!dnd}tttjO t| |d}	t	  g t
|d |R }
W d    n1 sJw   Y  t| |
rXtdt| |
ratdt|	|g||R  }t|ddW  d    S 1 s|w   Y  d S )	Nreapply_viewsmutations_and_views	mutationsremover    torch.map is mutating the input! torch.map is aliasing the input!level)r0   r   $_functionalization_reapply_views_tlsr   r   r   r   Functionalizer
   r   ra   r   r   r   r%   r	   )rJ   r   r   r   r   rf   unwrapped_xsunwrapped_argsr   functional_map_fnexample_inputs
map_returnr   r   r   map_funcF  s4   



$r   c              	   G   s  |d| }||d }|   }|rdnd}t||d}t||d}	t||d}
|  K t  g t|d |	R }W d   n1 sFw   Y  t||rTtdt||r]tdt	|
|g||	R  }t
||  d	W  d   S 1 szw   Y  dS )
z
    Functionalization implementation for torch.map. Currently:
      1. We don't allow any input mutation inside the map function
      2. Our check for above condition is not exhaustive
    Nr   r   r   r   r   r   r   r   )functionalize_add_back_viewsr   r
   lowerr   ra   r   r   r   r%   r	   r   )interpreterrJ   r   r   r   rf   r   r   r   r   r   r   r   r   r   r   map_functionalizeb  s4   


$r   )Cr0   torch.utils._pytreeutils_pytreerU   torch._Cr   r   r   torch._dispatch.pythonr   torch._functorch.aot_autogradr   r   !torch._functorch.eager_transformsr   r	   r
   torch._higher_order_ops.condr   r   r   
torch._opsr   torch._subclasses.fake_tensorr   "torch.fx.experimental.proxy_tensorr   r   r   r    torch.multiprocessing.reductionsr   torch.utils._python_dispatchr   r   r   r#   r%   rS   rm   r   autogradFunctionr   r   ra   r   py_implCompositeExplicitAutogradr   Autogradr   r   r   r   r   r   
_functorchTransformTyper   fallthroughPythonDispatcherPythonTLSSnapshotADInplaceOrViewBackendSelectAutocastCPUr   r   r   r   <module>   s^    i (


	






"