a
    h$                     @   s@  d dl mZ d dlZd dlZd dl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 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 G dd deZe Zeedd Zeedd Z ej!dd Z"eej#eedd eej$dd Z%dd Z&edd Z'dd Z(dd Z)d d! Z*dS )"    )contextmanagerN)DispatchKey)_ConstantFunction
flat_applyto_graphablestrict_mode)autograd_not_implemented)HigherOrderOperator)FakeTensorMode)get_proxy_slotPreDispatchTorchFunctionModeProxyTorchDispatchModetrack_tensor_tree)_pytree)"is_traceable_wrapper_subclass_typec                       s(   e Zd Z fddZ fddZ  ZS )ExportTracepointc                    s   t  d d S )N_export_tracepoint)super__init__)self	__class__ D/var/www/auris/lib/python3.9/site-packages/torch/_export/wrappers.pyr      s    zExportTracepoint.__init__c                    s   t  j|i |S N)r   __call__)r   argskwargsr   r   r   r      s    zExportTracepoint.__call__)__name__
__module____qualname__r   r   __classcell__r   r   r   r   r      s   r   c                 O   s<   t | jj||f\}}| jdt||}t||d | jdS )Ncall_functionZconstanttracer)pytreeZtree_mapr%   Zunwrap_proxycreate_proxyr   r   )moder   r   Zp_argsZp_kwargsproxyr   r   r   export_tracepoint_dispatch_mode%   s
    r*   c                 O   s,   |  |W  d    S 1 s0    Y  d S r   r   )r(   r   r   r   r   r   "export_tracepoint_fake_tensor_mode.   s    r+   c                 O   sR   |  |}|  |}|  " t|i | |W  d    S 1 sD0    Y  d S r   )Zunwrap_tensorsZredispatch_to_nextr   )ctxr   r   Zunwrapped_argsZunwrapped_kwargsr   r   r   export_tracepoint_functional4   s
    


r-   T)Zdeferred_errorc                  O   s   | S r   r   )r   r   r   r   r   export_tracepoint_cpuC   s    r.   c                    s   t | tjjsJ dksJ tjj| }fdddd   fdd} fdd	}|j|d
d}|j|d
d}||fS )N c                    sB   |  v r0 |  d |ksJ  |  d |ks0J ||d | < d S )Nin_specout_spec)r0   r1   r   )pathr0   r1   )module_call_specsr   r   update_module_call_signaturesM   s    z6_wrap_submodule.<locals>.update_module_call_signaturesc                 S   s:   | D ]0}t |tjttttfs|d u std| qd S )NzGOnly Tensors or scalars are supported as pytree flattened inputs, got: )
isinstancetorchTensorstrintfloatboolAssertionError)	flat_argsar   r   r   check_flattenedS   s
    z(_wrap_submodule.<locals>.check_flattenedc                    sB   t ||f\}} | t|dd}t ||\}}||fS )NZmodule_call_inputskindr2   r&   tree_flattenr   Ztree_unflatten)moduler   r   r=   r0   )r?   r2   r   r   pre_hookZ   s
    z!_wrap_submodule.<locals>.pre_hookc                    sP   t ||f\}}t |\}} | t|dd}|| t ||S )NZmodule_call_outputsr@   rB   )rD   r   r   res_r0   Zflat_resr1   )r?   r2   r4   r   r   	post_hooka   s    z"_wrap_submodule.<locals>.post_hookT)Zwith_kwargs)	r5   r6   nnModuleZfxZgraph_moduleZ	_get_attrZregister_forward_pre_hookZregister_forward_hook)modr2   r3   	submodulerE   rH   Z
pre_handleZpost_handler   )r?   r3   r2   r4   r   _wrap_submoduleH   s    rM   c              	   c   sV   g }z8|D ]}| t| || q
d V  W |D ]}|  q.n|D ]}|  qB0 d S r   )extendrM   remove)fZpreserve_signatureZmodule_call_signaturesZhandlesr2   handler   r   r   _wrap_submodulesn   s    rR   c                 C   s   dd }|| _ | S )Nc                 W   s
   t | |S r   r   )r   r   r   r   r   call|   s    z'_mark_strict_experimental.<locals>.call)r   )clsrS   r   r   r   _mark_strict_experimental{   s    rU   c                 C   s`   |d }t | j|r8t| j||ks(J | d|di S | |}t| j|| | d|di S )a  
    This is a wrapper utility method on top of tracer to cache the
    already registered subclass spec attribute. This is useful because
    Subclass.__init__ will be same for each subclass. By default, fx will
    create multiple attributes/proxies for given attribute.
    0get_attrr   )hasattrrootgetattrr'   get_fresh_qualnamesetattr)r%   namespecZfx_namequalnamer   r   r   '_register_subclass_spec_proxy_in_tracer   s    
r`   c                    s2   dd }| s"t d j d fdd}|S )a)  
    Experimental decorator that makes subclass to be traceable in export
    with pre-dispatch IR. To make your subclass traceble in export, you need to:
        1. Implement __init__ method for your subclass (Look at DTensor implementation)
        2. Decorate your __init__ method with _mark_constructor_exportable_experimental
        3. Put torch._dynamo_disable decorator to prevent dynamo from peeking into its' impl

    Example:

    class FooTensor(torch.Tensor):
        @staticmethod
        def __new__(cls, elem, *, requires_grad=False):
            # ...
            return torch.Tensor._make_subclass(cls, elem, requires_grad=requires_grad)

        @torch._dynamo_disable
        @mark_subclass_constructor_exportable_experimental
        def __init__(self, elem, ...):
            # ...
    c                 S   s   t | o| jdkS )Nr   )callabler   )fnr   r   r   _is_init   s    zCmark_subclass_constructor_exportable_experimental.<locals>._is_initztorch._export.wrappers.mark_constructor_exportable_experimental can only be applied on subclass tensor.__init__But, you are adding it on z which is not supported. If __init__ doesn't exist on your subclass, please add it. Look at DTensor.__init__ implementation for examplec                     s  t t| d sDjds J jd td  }td| d| i | tj s`d S tj	
 }dd |D }t|dksJ dt| t|dkrd S |d }|j | d }tt| dd  |f\}}d	j d
}	 |	}
t j|
|  d|
di }ttj fdd|}tjjtt|\}}t|j d }t ||} dt||g|R i }t||d  d d S )Nr   r   z5Applying mark_constructor_exportable_experimental on z is not valid as it is not a traceable tensor subclass. Please look at DTensor.__init__ implementation as an example of proper usage of this API.c                 S   s   g | ]}t |tr|qS r   )r5   r   ).0r(   r   r   r   
<listcomp>   s   
zVmark_subclass_constructor_exportable_experimental.<locals>.wrapper.<locals>.<listcomp>   z6Expected only one PreDispatchTorchFunctionMode, found rG   .rW   r   c                    s   t |  jS r   )r   r)   )xr%   r   r   <lambda>       zTmark_subclass_constructor_exportable_experimental.<locals>.wrapper.<locals>.<lambda>Z_const_func_specr#   r$   ) r   typer!   endswithlenRuntimeErrorr6   Z_CZ_is_torch_function_mode_enabledZ	overridesZ _get_current_function_mode_stackr%   r   tuplejoinlowersplitr[   r\   rY   r'   r&   Ztree_map_onlyr7   utilsr   rC   r   r   r`   r   r   )r   r   Zobj_nameZtorch_function_mode_stackZpre_dispatch_tf_modesr(   subclassr=   r0   Zconstructor_spec_namer_   Z
spec_proxyZflat_proxy_argsrG   Z	func_specZ!fxable_constructor_call_spec_nameZfunc_spec_proxyZinner_proxyconstructor_subclassri   r   wrapper   s`    





	zBmark_subclass_constructor_exportable_experimental.<locals>.wrapper)ro   r   )rw   rc   rx   r   rv   r   1mark_subclass_constructor_exportable_experimental   s    Gry   )+
contextlibr   r6   Ztorch._custom_opsZtorch._Cr   Z"torch._higher_order_ops.flat_applyr   r   r   Z#torch._higher_order_ops.strict_moder   Ztorch._higher_order_ops.utilsr	   Z
torch._opsr
   Ztorch._subclasses.fake_tensorr   Z"torch.fx.experimental.proxy_tensorr   r   r   r   Ztorch.utilsr   r&   Ztorch.utils._python_dispatchr   r   r   Zpy_implr*   r+   Zpy_functionalize_implr-   ZAutogradZCPUr.   rM   rR   rU   r`   ry   r   r   r   r   <module>   s<   


	



&
