U
    Kc                     @   sz   U d dl mZ ddlmZ ddlZddlZddlZdddgZe Z	ee
 ed< d	gZG d
d dZdddZdddZdS )   )
OpOverload    )SetNLibraryimpldefine_implsZprimc                   @   s>   e Zd ZdZdddZdd ZdddZdd	d
Zdd ZdS )r   ar  
    A class to create libraries that can be used to register new operators or
    override operators in existing libraries from Python.
    A user can optionally pass in a dispatch keyname if they only want to register
    kernels corresponding to only one specific dispatch key.

    To create a library to override operators in an existing library (with name ns), set the kind to "IMPL".
    To create a new library (with name ns) to register new operators, set the kind to "DEF".
    Args:
        ns: library name
        kind: "DEF", "IMPL" (default: "IMPL")
        dispatch_key: PyTorch dispatch key (default: "")
     c                 C   s   t jdddkrtd|dkr4|dkr4td||tkrN|dkrNt|dtjd	d
d }|j|j	 }}t
j|||||| _|| _t | _|| _|| _d S )NZPYTORCH_DISABLE_LIBRARY01zBTrying to use torch.library in an environment where it is disabledZIMPLZDEFzUnsupported kind: zJ is a reserved namespace. Please try creating a library with another name.   )limitr   )osenvirongetRuntimeError
ValueError_reserved_namespaces	tracebackextract_stackfilenamelinenotorch_CZ_dispatch_librarymnsset	_op_implskinddispatch_key)selfr   r   r   framer   r    r"   1/tmp/pip-unpacked-wheel-gikjz4vx/torch/library.py__init__    s    

zLibrary.__init__c                 C   s   d | j| j| jS )Nz)Library(kind={}, ns={}, dispatch_key={})>)formatr   r   r   )r    r"   r"   r#   __repr__2   s    zLibrary.__repr__c                 C   s$   |dkrt d|| j||S )a9  Defines a new operator and its semantics in the ns namespace.

        Args:
            schema: function schema to define a new operator.
            alias_analysis (optional): Indicates if the aliasing properties of the operator arguments can be
                                       inferred from the schema (default behavior) or not ("CONSERVATIVE").
        Returns:
            name of the operator as inferred from the schema.

        Example::
            >>> my_lib = Library("foo", "DEF")
            >>> my_lib.define("sum(Tensor self) -> Tensor")
        )r	   ZFROM_SCHEMAZCONSERVATIVEzInvalid alias_analysis type {})r   r%   r   r   )r    schemaalias_analysisr"   r"   r#   r   5   s    zLibrary.definec           	      C   s(  t |stdt||dkr(| j}t|tr8|}n8t|trh|jj	}|jj
}|dkrp|d | }ntd| jd |dd  d | }|tkrtd|dd || j|d	kr|}d|kr| j d| }tj|}d
|krtd| d| j||| t| | j| dS )a  Registers the function implementation for an operator defined in the library.

        Args:
            op_name: operator name (along with the overload) or OpOverload object.
            fn: function that's the operator implementation for the input dispatch key.
            dispatch_key: dispatch key that the input function should be registered for. By default, it uses
                          the dispatch key that the library was created with.

        Example::
            >>> # xdoctest: +SKIP
            >>> my_lib = Library("aten", "IMPL")
            >>> def div_cpu(self, other):
            >>>    return self * (1 / other)
            >>> my_lib.impl("div.Tensor", "CPU")
        z=Input function is required to be a callable but found type {}r	   .zQimpl should be passed either a name or an OpOverload object as the first argument/z::zThis is not allowed since there's already a kernel registered from python overriding {}'s behavior for {} dispatch key and {} namespace.ZMetaZCompositeImplicitAutogradz?We should not register a meta kernel directly to the operator 'z', because it has a CompositeImplicitAutograd kernel in core. Instead we should let the operator decompose, and ensure that we have meta kernels for the base ops that it decomposes into.N)callable	TypeErrorr%   typer   
isinstancestrr   Z_schemanameoverload_namer   r   splitr   r   r   Z_dispatch_dumpr   r   addr   )	r    Zop_namefnr   r1   r2   keyZdispatcher_op_nameZdispatch_key_registrationr"   r"   r#   r   I   s>    

   

zLibrary.implc                 C   s.   t | dd }|r*| jD ]}t| q| `d S )Nr   )getattrr   r   remover   )r    Z
_op_impls_r6   r"   r"   r#   __del__   s
    
zLibrary.__del__N)r	   )r	   )r	   )	__name__
__module____qualname____doc__r$   r&   r   r   r9   r"   r"   r"   r#   r      s   


=r	   c                    s    fdd}|S )Nc                    s    |   | S N)r   )fr   libr1   r"   r#   wrap   s    zimpl.<locals>.wrapr"   )rA   r1   r   rB   r"   r@   r#   r      s    c                    s    fdd}|S )Nc                    s     }||  | S r>   )r   r   )r?   r1   r(   rA   r'   r"   r#   rB      s    zdefine.<locals>.wrapr"   )rA   r'   r(   rB   r"   rC   r#   r      s    )r	   )r	   )Z_opsr   typingr   r   r   r   __all__r   r   r0   __annotations__r   r   r   r   r"   r"   r"   r#   <module>   s    
~
