U
    9%e9                  	   @   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 |f| S N)map_wrapper)selfxsargs r   Z/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/functorch/experimental/_map.py__call__#   s    zMapWrapper.__call__N)__name__
__module____qualname__r   r   r   r   r   r   "   s   r   mapT)Z_deprecated_global_nsmap_implF)Zfw_compilerZbw_compilerZpartition_fnZdecompositionsZnum_params_buffersZaot_idZkeep_inference_input_mutationsc              
      s  |d  }|d  }t   t  dd fddt|d D }fdd|D }t || }tdd |D rtd	d
d |D  dfdd|D }t || }	W 5 Q R X  fdd}
t|t| t|
||| }|	|fW  5 Q R  S Q R X d S )Nc                 S   sB   t | tjr>| jtjkr6tj|  |  | j| jdS | 	 S | S )N)dtyperequires_grad)

isinstancetorchTensorr%   boolZempty_stridedsizeZstrider&   clonetr   r   r   from_funK   s    z$create_fw_bw_graph.<locals>.from_func                    s   g | ]} |qS r   r   .0r   r/   r   r   
<listcomp>X   s     z&create_fw_bw_graph.<locals>.<listcomp>r   c                    s$   g | ]}t |tjr |n|qS r   r'   r(   r)   r1   argr2   r   r   r3   Y   s   c                 s   s$   | ]}|d k	rt |tj V  qd S r   r4   r1   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   )typer7   r   r   r   r3   f   s     .c                    s   g | ]} |qS r   r   r7   r2   r   r   r3   i   s     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'   r(   r)   r&   )r1   retr   r   r   r3   v   s   
zNcreate_fw_bw_graph.<locals>.joint_f.<locals>.fw_with_masks.<locals>.<listcomp>r   )r   Zfw_out)fr   r   fw_with_maskst   s    z:create_fw_bw_graph.<locals>.joint_f.<locals>.fw_with_masks)Z
aot_configc                 S   s   g | ]}|d k	r|j r|qS r   )r&   )r1   Zgradr   r   r   r3      s    z7create_fw_bw_graph.<locals>.joint_f.<locals>.<listcomp>c                 S   s$   h | ]}t |tjrt| qS r   )r'   r(   r)   r   _typed_storager5   r   r   r   	<setcomp>   s   z6create_fw_bw_graph.<locals>.joint_f.<locals>.<setcomp>c                    s(   t | tjr$t|   kr$|  S | S r   )r'   r(   r)   r   r?   r,   r-   Zinput_storager   r   maybe_clone   s    
z8create_fw_bw_graph.<locals>.joint_f.<locals>.maybe_clone)r   dummy_aot_configlistpytreetree_map)
Zexample_argsZjoint_mapped_argsr   Zmapped_inputZmapped_gradsr>   Zjoint_gradsrB   )r=   joint_num_mappednum_mapped_argsrA   r   joint_fm   s"    	z#create_fw_bw_graph.<locals>.joint_f)	r   r   _unstack_pytreerE   rF   anyRuntimeErrorr   len)r=   rJ   r   Z	mapped_xspos_argsZ
example_xsZexample_pos_argsZexample_flat_outZexample_gradfw_graphrK   joint_graphr   )r=   r/   rI   rJ   r   create_fw_bw_graph5   s2    
 
,rS   c                    s   t |\}tdd |D s0td| dt|dd |D }|d d dkrbtdtfd	d|D rtd
| dd  fdd}t t|f|| S )Nc                 s   s   | ]}t |tjV  qd S r   r4   )r1   r.   r   r   r   r9      s     zmap_wrapper.<locals>.<genexpr>z.Mapped xs can only consist of tensors. Got xs r;   c                 S   s   g | ]
}|j qS r   shaper0   r   r   r   r3      s     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   )r1   Z	cur_shapeleading_dim_sizer   r   r9      s     z?Leading dimensions of mapped xs must be consistent. Got shapes c                     s@   t | d  } |f| d   }t |\}}||S r   )rE   tree_unflattentree_flatten)	flat_argsr   Zunflattened_outflat_outZtmp_out_spec)r=   rJ   out_specxs_specr   r   flat_fn   s
    zmap_wrapper.<locals>.flat_fn)rE   rZ   allrN   rO   rM   rY   r$   )r=   r   r   flat_xsZshapesr_   r   )r=   rX   rJ   r]   r^   r   r      s$    
	 r   c                   @   s$   e Zd Zedd Zedd ZdS )MapAutogradOpc              
   G   sJ   | j |  || _|| _tj   t||f| W  5 Q R  S Q R X d S r   )Zsave_for_backward_joint_graph_num_mapped_argsr(   _CZ_AutoDispatchBelowAutogradr$   )ctxrQ   rR   rJ   r[   r   r   r   forward   s
    
zMapAutogradOp.forwardc                 G   sJ   | j }|d | j }|| jd  }t| j| jt| f||| }d|S )N)NNN)Zsaved_tensorsrd   r$   rc   rO   )rf   Z
flat_gradsZfw_argsZfw_mapped_argsrP   rH   r   r   r   backward   s    zMapAutogradOp.backwardN)r    r!   r"   staticmethodrg   rh   r   r   r   r   rb      s   
rb   c              	      s  t |d | }t ||d  }|d jd  t|d }|}t|tjjs\t||| }t * ||| }	 fdd}
t	
|
|	}W 5 Q R X d }d}|sd| }t| jj|r|d7 }q|}q| jj|| ||f|}t	
| jj|}| jjd||i dd}t||d | jd	S )
Nr   c                    s"   t | tjr| j f| j S | S r   )r'   r(   r)   expandrU   r-   rW   r   r   expand_tensor   s    z trace_map.<locals>.expand_tensorZbody_graph_   Zcall_functionr$   )name)Zconstanttracer)rD   rU   rL   r'   r(   ZfxZGraphModuler   r   rE   rF   hasattrrn   rootZregister_moduleZunwrap_proxyZcreate_proxyr   )Z
proxy_modeZfunc_overloadr=   
num_mappedr   r   rP   Zexample_inputZ
body_graphZexample_outsrk   Zexpanded_outsZ	next_namei	candidateZ	node_argsZ
proxy_argsZ	out_proxyr   rW   r   	trace_map   sD    

       rt   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 || ql|S )Nc                 s   s   | ]}t |tjV  qd S r   r4   r0   r   r   r   r9     s     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 rV   rT   r0   ra   r   r   r9     s     z3Leaves of xs must have same leading dimension size c                 S   s   g | ]
}|j qS r   rT   r0   r   r   r   r3     s     z#_unstack_pytree.<locals>.<listcomp>)rE   rZ   r`   rN   zipappendrY   )r   Zinspecapytreestupler   ru   r   rL      s    rL   c                 C   s   g }d }| D ]}t |\}}|| qt| }g }|D ]V}tdd |D rb|t| q:tdd |D r|d  q:td| dq:t ||S )Nc                 s   s   | ]}t |tjV  qd S r   r4   r1   leafr   r   r   r9     s     z _stack_pytree.<locals>.<genexpr>c                 s   s   | ]}|d kV  qd S r   r   r{   r   r   r   r9     s     zCannot stack r;   )	rE   rZ   rw   rv   r`   r(   stackrN   rY   )ry   r\   r]   ptZflat_ptbZstacked_outleavesr   r   r   _stack_pytree  s    r   c                 G   sD   |d | }||d  }g }t |D ]}|| ||  q$t|S r   )rL   rw   r   )r=   rJ   r   r   rP   ry   Zinpr   r   r   	map_dense%  s    r   c                 G   s,   t | |f| \}}tj|||f| }|S r   )rS   rb   apply)r=   rJ   r   rQ   Zbw_graphr\   r   r   r   map_autograd/  s    r   c              
   G   sn   t  }|d k	stdt H}|jrDt|t| |f| W  5 Q R  S t| |f| W  5 Q R  S W 5 Q R X d S )Nz5Mode should always be enabled for python fallback key)r   AssertionErrorr   Zenable_tracingrt   r$   )r=   rq   r   moder   r   r   map_proxy_torch_dispatch_mode6  s     r   c                 G   s   t | |f| S r   )r   )r=   rq   r   r   r   r   map_fake_tensor_modeA  s    r   c              
   G   s   t j }|d | }||d  }t||d}t||d}|rBdnd}tttj~ t| |d}	t	  t
|d |}
W 5 Q R X t| |
rtdt| |
rtdt|	|f|| }t|ddW  5 Q R  S Q R X d S )	Nreapply_viewsmutations_and_views	mutationsremover    torch.map is mutating the input! torch.map is aliasing the input!level)r(   re   Z$_functionalization_reapply_views_tlsr   r   r   r   Functionalizer
   r   rL   r   r   r   r$   r	   )r=   rq   r   r   r   rP   unwrapped_xsunwrapped_argsr   functional_map_fnexample_inputs
map_returnr   r   r   map_funcF  s2    
 

  r   c              
   G   s   |d| }||d }|   }|r(dnd}t||d}t||d}	t||d}
|  v t  t|d |	}W 5 Q R X t||rtdt||rtdt	|
|f||	 }t
||  d	W  5 Q R  S Q R X 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   )Zfunctionalize_add_back_viewsr   r
   lowerr   rL   r   r   r   r$   r	   r   )interpreterr=   rq   r   r   rP   r   r   r   r   r   r   r   r   r   r   map_functionalizeb  s2     


  r   )Cr(   Ztorch.utils._pytreeutilsZ_pytreerE   Ztorch._Cr   r   r   Ztorch._dispatch.pythonr   Ztorch._functorch.aot_autogradr   r   Z!torch._functorch.eager_transformsr   r	   r
   Ztorch._higher_order_ops.condr   r   r   Z
torch._opsr   Ztorch._subclasses.fake_tensorr   Z"torch.fx.experimental.proxy_tensorr   r   r   r   Z torch.multiprocessing.reductionsr   Ztorch.utils._python_dispatchr   r   r   r#   r$   rC   rS   r   ZautogradFunctionrb   rt   rL   r   Zpy_implZCompositeExplicitAutogradr   ZAutogradr   r   r   r   r   re   Z
_functorchZTransformTyper   ZfallthroughZPythonDispatcherZPythonTLSSnapshotZADInplaceOrViewZBackendSelectZAutocastCPUr   r   r   r   <module>   s\   i (

	



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