o
    e«Ïià0  ã                   @   sþ  U d 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 ddlZdd	lmZmZ d
dlmZ G dd„ deƒZedƒG dd„ dƒƒZdZe
dejjƒZeG dd„ dƒƒZeƒ Zeeef ed< i Ze e!ef ed< dede!fdd„Z"ddddœdede!dede e!ef dB ddf
d d!„Z#d"e$dee fd#d$„Z%dede&fd%d&„Z'dede&fd'd(„Z(dede&fd)d*„Z)dede&fd+d,„Z*dede&fd-d.„Z+d/ede,e!e e!e-f f fd0d1„Z.dedee fd2d3„Z/ded4e!dee fd5d6„Z0dS )7aM  
Note [Opaque Objects]

Opaque objects are the way we allow custom operators to accept a user-defined
"black box" object as an input.

There are two kinds of opaque types: VALUE type and REFERENCE type.
The distinction determines how torch.compile handles the object.

REFERENCE TYPES (default):

Reference-typed opaque objects represent mutable stateful objects and are
treated as black boxes. In torch.compile, since torch.compile cannot optimize
the anything (including tensors) within the object, the object must be an
input to the graph.

You can register a custom class as being a reference-based opaque object class
through `register_opaque_type(MyClass, typ="reference")`.

VALUE TYPES:

Value-typed opaque objects represent constant values.
In torch.compile, the graph specializes on the object like how other constants
are. Therefore there are a couple of methods on the class that must be
implemented before registering it as a value-typed opaque object class:
  - __eq__: torch.compile will create guards based on the equality of this
  object, meaning that a recompilation will happen if __eq__ returns False.
  - __hash__: This must be implemented for Fake Tensor caching
  - __fx_repr__: This must be implemented to provide an evaluable representation
    for FX graph codegen. It should return a tuple of (repr_string, dict[str, type])
    where repr_string can reconstruct the object and the dict maps names used in
    repr_string to their corresponding types.

You can register a custom class as being a reference-based opaque object class
through `register_opaque_type(MyClass, typ="value")`.
é    )ÚCallable)Ú	dataclass)ÚEnum)ÚAnyÚLiteralÚNewTypeÚOptional)ÚTypeIs)ÚWeakKeyDictionaryN)Ú
OpaqueBaseÚOpaqueBaseMetaé   )Úregister_fake_classc                   @   s   e Zd ZdZdZdZdS )Ú
MemberTypez{
    Defines how a member (attribute/property/method) of an opaque object is handled
    during torch.compile tracing.
    Úuse_realÚinlinedN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚUSE_REALÚINLINED© r   r   úf/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/_library/opaque_object.pyr   3   s    r   zaten::OpaqueObjectc                   @   s4   e Zd Zddd„Zedeeef ddfdd„ƒZdS )	ÚFakeOpaqueObjectÚreturnNc                 C   s   d S ©Nr   )Úselfr   r   r   Ú__init__A   s   zFakeOpaqueObject.__init__Úflattened_ctxc                 C   s   t dƒ‚)NzFakeOpaqueObject should not be created through __obj_unflatten__ and should be special handled. Please file an issue to Github.)ÚRuntimeError)Úclsr   r   r   r   Ú__obj_unflatten__D   s   ÿz"FakeOpaqueObject.__obj_unflatten__)r   N)	r   r   r   r   ÚclassmethodÚdictÚstrr   r"   r   r   r   r   r   ?   s    
 r   z)__torch__.torch.classes.aten.OpaqueObjectÚ
OpaqueTypec                   @   sP   e Zd ZU eed< ed ed< eegee f ed< e	ee
f ed< eed< dS )Ú_OpaqueTypeInfoÚ
class_name©Ú	referenceÚvalueÚ
opaque_typÚguard_fnÚmembersÚhoistN)r   r   r   r%   Ú__annotations__r   r   r   Úlistr$   r   Úboolr   r   r   r   r'   Q   s   
 ÿr'   Ú_OPAQUE_TYPESÚ_OPAQUE_TYPES_BY_NAMEr!   r   c                 C   s*   | t vrtd| › d| j› dƒ‚t |  jS )a  
    Gets the registered opaque type name for a given class.

    Args:
        cls (type): The class to get the type name for.

    Returns:
        str: The registered type name for the class.

    Raises:
        ValueError: If the class is not registered as an opaque type.
    zClass z@ is not registered as an opaque type. Call register_opaque_type(z) first.)r3   Ú
ValueErrorr   r(   ©r!   r   r   r   Úget_opaque_type_nameb   s   ÿÿ
r7   F)r/   r-   r.   Útypr-   r.   c                C   s4  ddl m  m} | jdks| tju rtd| › dƒ‚| |jv r't| › dƒ‚t| t	ƒs4t
d| › dƒ‚|d	vr?td
|›ƒ‚|dkrw| jtju rQt
d| › dƒ‚| jdu r^t
d| › dƒ‚t| dƒskt
d| › dƒ‚|durwt
d| › dƒ‚| j› d| j› }t||||p‡i |ƒ}|t| < |t|< tj |¡ dS )aœ  
    Registers the given type as an opaque type which allows this to be consumed
    by a custom operator.

    The type name will be automatically generated from the class's fully
    qualified name (ex. my_module.MyClass).

    Args:
        cls (type): The class to register as an opaque type.
        typ (str): Either "reference" or "value". See Note [Opaque Objects] for
            more details.
        hoist (bool): Only applies to value types. A hoist=True value type
            object is lifted as an input to the torch.compile'd graph, instead
            of being a constant baked into the graph. This is useful to
            improve compilation times in hierarchical compilation
            (e.g., change your custom ops to use hoisted strings to avoid
            baking the string into the Dynamo/AOTAutograd/FX graphs).
            This flag does nothing for reference types.
        guard_fn (callable | None): A function that takes an instance of the opaque
            object and returns a list of values to guard on. These values will be compared
            for equality on each function call, triggering recompilation if they change.
            Only applicable for reference types.
            Example: lambda obj: [obj.x, obj.y]
        members (dict[str, MemberType] | None): Dictionary mapping member names
            (attributes, properties, or methods) to their MemberType, which controls
            how they are handled during torch.compile tracing:
            - MemberType.USE_REAL: Evaluates with the real object at compile time and
              bakes the result as a constant
            - MemberType.INLINED: Inlines the method call into the trace
    r   NÚbuiltinsz!Unable to register built-in type z] as an opaque type. Please wrap it in a custom class and register the custom class as opaque.zv cannot be registered as an opaque object as it has been registered as a pytree. Opaque objects must be pytree leaves.zOpaque type zõ must subclass torch._opaque_base.OpaqueBase or 'metaclass=torch._opaque_base.OpaqueBaseMeta'. This is required so that FakeScriptObject can be registered as a virtual subclass, allowing isinstance() checks to work during torch.compile tracing. r)   z7Opaque type must be either 'reference' or 'value', got r+   ú!Value-type opaque object of type z„ is expected to have a non-default `__eq__` implementation as we will use this in torch.compile to guard on the equality of objects.zy is expected to have a non-default `__hash__` implementation as we will use this in torch.compile for FakeTensor caching.Ú__fx_repr__z½ is expected to have a `__fx_repr__` method implementation as we will use this to reconstruct the object in the FX codegen. __fx_repr__ should return a tuple of (repr_string, set_of_types).z:No need to specify `guard_fn` for value-type opaque class z) as it will be guarded based on `__eq__`.Ú.)Útorch.utils._pytreeÚutilsÚ_pytreer   ÚtorchÚTensorr5   ÚSUPPORTED_NODESÚ
isinstancer   Ú	TypeErrorÚAssertionErrorÚ__eq__ÚobjectÚ__hash__Úhasattrr   r'   r3   r4   Ú_CÚ_register_opaque_type)r!   r8   r/   r-   r.   ÚpytreeÚnameÚ	type_infor   r   r   Úregister_opaque_typew   sR   &
ÿ
ÿ

ÿÿ
ÿ
	
ÿ

ÿÿÿrO   r+   c                 C   s   t t| ƒƒS r   )Úis_opaque_typeÚtype)r+   r   r   r   Úis_opaque_valueç   s   rR   c                 C   s   | t vrdS t |  jS )NF)r3   r/   r6   r   r   r   Úshould_hoistë   s   
rS   c                 C   s   | t vrdS tt |  jƒdkS )NFr   )r3   Úlenr.   r6   r   r   r   Úhas_membersñ   s   rU   c                 C   s4   t | tƒrtj | ¡S | tvrdS tj t|  j¡S )z5
    Checks if the given type is an opaque type.
    F)rC   r%   r@   rJ   Ú_is_opaque_type_registeredr3   r(   r6   r   r   r   rP   ÷   s
   
rP   c                 C   ó2   t | ƒsdS t| tƒrt|  jdkS t|  jdkS )zs
    Checks if the given type is an opaque **value** type.
    See Note [Opaque Objects] for more information.
    Fr+   ©rP   rC   r%   r4   r,   r3   r6   r   r   r   Úis_opaque_value_type  ó
   
rY   c                 C   rW   )zw
    Checks if the given type is an opaque **reference** type.
    See Note [Opaque Objects] for more information.
    Fr*   rX   r6   r   r   r   Úis_opaque_reference_type  rZ   r[   Úobjc                 C   s‚   t | dƒstd| › dƒ‚|  ¡ \}}t|tƒs(tdt| ƒj› dt|ƒj› ƒ‚t|tƒs=tdt| ƒj› dt|ƒj› ƒ‚||fS )aÄ  
    Get the FX-evaluable repr for an opaque object and collect required globals.

    Objects must implement __fx_repr__() which should return:
        (repr_string, dict_mapping_name_to_type)

    where repr_string is an evaluable string representation and
    dict_mapping_name_to_type maps the names used in repr_string to their types.

    For example, if repr_string is "Foo(bar=Bar(1))", the dict should be:
        {"Foo": Foo, "Bar": Bar}
    r;   r:   zÀ is expected to have a `__fx_repr__` method implementation as we will use this to reconstruct the object in the FX codegen. __fx_repr__ should return a tuple of (repr_string, dict[str, type]).z__fx_repr__ for z0 must return a string as the first element, got z/ must return a dict as the second element, got )rI   rD   r;   rC   r%   rQ   r   r$   )r\   Úrepr_strÚglobals_dictr   r   r   Úget_opaque_obj_repr   s$   

ÿ
ÿÿ
ÿÿr_   c                 C   s&   t | ƒsd S t| tƒrt|  S t|  S r   )rP   rC   r%   r4   r3   r6   r   r   r   Úget_opaque_obj_infoG  s
   
r`   Úmember_namec                 C   s    t | ƒ}|du r
dS |j |¡S )a  
    Get the MemberType for a specific member of an opaque object class.

    Args:
        cls: The opaque object class (or its string name)
        member_name: The name of the member to query

    Returns:
        MemberType if the member is registered, None otherwise
    N)r`   r.   Úget)r!   ra   Úinfor   r   r   Úget_member_typeQ  s   rd   )1r   Úcollections.abcr   Údataclassesr   Úenumr   Útypingr   r   r   r   Útyping_extensionsr	   Úweakrefr
   r@   Útorch._opaque_baser   r   Úfake_class_registryr   r   r   ÚOpaqueTypeStrrJ   ÚScriptObjectr&   r'   r3   r0   r4   r$   r%   r7   rO   rG   rR   r2   rS   rU   rP   rY   r[   ÚtuplerQ   r_   r`   rd   r   r   r   r   Ú<module>   sV    %úÿýûú
ùp"'
