U
    9%e@+                     @   s(  d Z ddlZddlmZmZmZmZmZmZm	Z	m
Z
mZ ddlmZmZ ddlmZ eZeee ee dddZe
d	Ze
d
ZG dd deeef ee ZG dd dZG dd dZejdeeeee f eee  eedddZejdeeeee f eee  edddZe adS )z3Module for handling symbolic function registration.    N)	Callable
CollectionDictGenericOptionalSequenceSetTypeVarUnion)
_constantserrors)	_beartype)targetregistered_opsetsreturnc                 C   sp   |sdS t |dd}| tjkr<|D ]}|| kr"|  S q"dS t|D ]&}| |  kr^tjkrDn qD|  S qDdS )zFinds the registered opset given a target opset version and the available opsets.

    Args:
        target: The target opset version.
        registered_opsets: The available opsets.

    Returns:
        The registered opset version.
    NT)reverse)sortedr   ZONNX_BASE_OPSETreversed)r   r   Zdescending_registered_versionsversion r   `/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/onnx/_internal/registration.py_dispatch_opset_version   s    


r   _K_Vc                   @   s   e Zd ZdZdd ZeeddddZeedd	d
Z	eeddddZ
eddddZeedddZeedddZd!eee dddZeedddZdd ZedddZedddZeddd ZdS )"OverrideDictzA dictionary that merges built-in and custom symbolic functions.

    It supports overriding and un-overriding built-in symbolic functions with custom
    ones.
    c                 C   s   i | _ i | _i | _d S N_base
_overrides_mergedselfr   r   r   __init__G   s    zOverrideDict.__init__N)keyvaluer   c                 C   s"   || j |< || jkr|| j|< d S r   r   r!   r#   r$   r   r   r   set_baseL   s    

zOverrideDict.set_baser#   r   c                 C   s
   || j kS )z*Checks if a key is in the base dictionary.)r   r!   r#   r   r   r   in_baseQ   s    zOverrideDict.in_basec                 C   s   || j |< || j|< dS )z+Overrides a base key-value with a new pair.N)r   r   r%   r   r   r   overrideU   s    
zOverrideDict.overridec                 C   s:   | j |d | j|d || jkr6| j| | j|< dS )zUn-overrides a key-value pair.N)r   popr   r   r(   r   r   r   remove_overrideZ   s    
zOverrideDict.remove_overridec                 C   s
   || j kS )z)Checks if a key-value pair is overridden.)r   r(   r   r   r   
overriddena   s    zOverrideDict.overriddenc                 C   s
   | j | S r   r   r(   r   r   r   __getitem__e   s    zOverrideDict.__getitem__)r#   defaultc                 C   s   | j ||S r   )r   get)r!   r#   r0   r   r   r   r1   h   s    zOverrideDict.getc                 C   s
   || j kS r   r.   r(   r   r   r   __contains__k   s    zOverrideDict.__contains__c                 C   s
   t | jS r   )iterr   r    r   r   r   __iter__n   s    zOverrideDict.__iter__r   c                 C   s
   t | jS r   )lenr   r    r   r   r   __len__q   s    zOverrideDict.__len__c                 C   s   d| j  d| j dS )NzOverrideDict(base=z, overrides=))r   r   r    r   r   r   __repr__t   s    zOverrideDict.__repr__c                 C   s
   t | jS r   )boolr   r    r   r   r   __bool__w   s    zOverrideDict.__bool__)N)__name__
__module____qualname____doc__r"   r   r   r&   r:   r)   r*   r,   r-   r/   r   r1   objectr2   r4   intr7   strr9   r;   r   r   r   r   r   @   s   r   c                   @   s   e Zd ZdZeddddZedddZeed	d
dZ	ee
e dddZeeddddZeeddddZeddddZedddZdS )_SymbolicFunctionGroupap  Different versions of symbolic functions registered to the same name.

    O(number of registered versions of an op) search is performed to find the most
    recent version of the op.

    The registration is delayed until op is used to improve startup time.

    Function overloads with different arguments are not allowed.
    Custom op overrides are supported.
    Nnamer   c                 C   s   || _ t | _d S r   )_namer   
_functionsr!   rE   r   r   r   r"      s    z_SymbolicFunctionGroup.__init__r5   c                 C   s   d| j  d| j dS )Nz_SymbolicFunctionGroup(z, registered=r8   )rF   rG   r    r   r   r   r9      s    z_SymbolicFunctionGroup.__repr__r'   c                 C   s   |  |}|d krt||S r   )r1   KeyError)r!   r#   resultr   r   r   r/      s    
z"_SymbolicFunctionGroup.__getitem__)opsetr   c                 C   s"   t || j}|dkrdS | j| S )z-Find the most recent version of the function.N)r   rG   )r!   rK   r   r   r   r   r1      s    z_SymbolicFunctionGroup.get)funcrK   r   c              	   C   sD   | j |r2td| j d| dtj dtj | j 	|| dS )zAdds a symbolic function.

        Args:
            func: The function to add.
            opset: The opset version of the function to add.
        zSymbolic function 'z' already registered for opset z]. Replacing the existing function with new function. This is unexpected. Please report it on .N)
rG   r)   warningswarnrF   r   ZPYTORCH_GITHUB_ISSUES_URLr   ZOnnxExporterWarningr&   r!   rL   rK   r   r   r   add   s    z_SymbolicFunctionGroup.addc                 C   s   | j || dS )zAdds a custom symbolic function.

        Args:
            func: The symbolic function to register.
            opset: The corresponding opset version.
        N)rG   r*   rP   r   r   r   
add_custom   s    z!_SymbolicFunctionGroup.add_customc                 C   s8   | j |s(td| j d|  dS | j | dS )zRemoves a custom symbolic function.

        Args:
            opset: The opset version of the custom function to remove.
        z#No custom function registered for 'z' opset N)rG   r-   rN   rO   rF   r,   )r!   rK   r   r   r   remove_custom   s    z$_SymbolicFunctionGroup.remove_customc                 C   s
   t | jS )zDReturns the lowest built-in opset version supported by the function.)minrG   r    r   r   r   get_min_supported   s    z(_SymbolicFunctionGroup.get_min_supported)r<   r=   r>   r?   rB   r"   r9   OpsetVersionr   r/   r   r1   rQ   rR   rS   rU   r   r   r   r   rC   {   s   	rC   c                   @   s   e Zd ZdZddddZdeeeedddd	Z	eedd
ddZ
eee dddZeeedddZee dddZdS )SymbolicRegistryzRegistry for symbolic functions.

    The registry maintains a mapping from qualified names to symbolic functions.
    It is used to register new symbolic functions and to dispatch calls to
    the appropriate function.
    Nr5   c                 C   s
   i | _ d S r   )	_registryr    r   r   r   r"      s    zSymbolicRegistry.__init__F)rE   rK   rL   customr   c                 C   sL   d|krt d| d| j|t|}|r<||| n||| dS )a  Registers a symbolic function.

        Args:
            name: The qualified name of the function to register. In the form of 'domain::op'.
                E.g. 'aten::add'.
            opset: The opset version of the function to register.
            func: The symbolic function to register.
            custom: Whether the function is a custom function that overrides existing ones.

        Raises:
            ValueError: If the separator '::' is not in the name.
        z::z3The name must be in the form of 'domain::op', not ''N)
ValueErrorrX   
setdefaultrC   rR   rQ   )r!   rE   rK   rL   rY   Zsymbolic_functionsr   r   r   register   s    
 zSymbolicRegistry.register)rE   rK   r   c                 C   s"   || j krdS | j | | dS )zUnregisters a symbolic function.

        Args:
            name: The qualified name of the function to unregister.
            opset: The opset version of the function to unregister.
        N)rX   rS   )r!   rE   rK   r   r   r   
unregister   s    
zSymbolicRegistry.unregisterrD   c                 C   s   | j |S )z.Returns the function group for the given name.)rX   r1   rH   r   r   r   get_function_group   s    z#SymbolicRegistry.get_function_group)rE   r   r   c                 C   s$   |  |}|dkrdS ||dk	S )zGReturns whether the given op is registered for the given opset version.NF)r_   r1   )r!   rE   r   Z	functionsr   r   r   is_registered_op   s    
z!SymbolicRegistry.is_registered_opc                 C   s
   t | jS )z1Returns the set of all registered function names.)setrX   r    r   r   r   all_functions  s    zSymbolicRegistry.all_functions)F)r<   r=   r>   r?   r"   rB   rV   r   r:   r]   r^   r   rC   r_   rA   r`   r   rb   r   r   r   r   rW      s       rW   F)rE   rK   decoraterY   r   c                    s   t t d fdd}|S )a  Registers a symbolic function.

    Usage::

    ```
    @onnx_symbolic("aten::symbolic_b", opset=10, decorate=[quantized_aten_handler(scale=1/128, zero_point=0)])
    @symbolic_helper.parse_args("v", "v", "b")
    def symbolic_b(g: _C.Graph, x: _C.Value, y: _C.Value, arg1: bool) -> _C.Value:
        ...
    ```

    Args:
        name: The qualified name of the function in the form of 'domain::op'.
            E.g. 'aten::add'.
        opset: The opset versions of the function to register at.
        decorate: A sequence of decorators to apply to the function.
        custom: Whether the function is a custom symbolic function.

    Raises:
        ValueError: If the separator '::' is not in the name.
    )rL   r   c                    sN   | }d k	rD ]}||}qt tr.fD ]}tj|| d q2| S )NrY   )
isinstancerV   registryr]   )rL   Z	decoratedZdecorate_funcZopset_versionrY   rc   rE   rK   r   r   wrapper(  s    

zonnx_symbolic.<locals>.wrapper)r   )rE   rK   rc   rY   rh   r   rg   r   onnx_symbolic  s    ri   )rE   rK   rc   r   c                 C   s   t | ||ddS )aN  Registers a custom symbolic function.

    Args:
        name: the qualified name of the function.
        opset: the opset version of the function.
        decorate: a sequence of decorators to apply to the function.

    Returns:
        The decorator.

    Raises:
        ValueError: If the separator '::' is not in the name.
    Trd   )ri   )rE   rK   rc   r   r   r   custom_onnx_symbolic<  s    rj   )NF)N)r?   rN   typingr   r   r   r   r   r   r   r	   r
   Z
torch.onnxr   r   Ztorch.onnx._internalr   rA   rV   r   r   r   r   rC   rW   ZbeartyperB   r:   ri   rj   rf   r   r   r   r   <module>   sB   , &;OA  
0 
