U
    yh                     @   sz   d dl mZmZmZmZ d dlmZmZ eeef eeeef dddZ	eeeee
 eee
 egef edddZd	S )
    )AnyCallableDictOptional)ContextTreeSpec)user_kwargsspecreturnc                 C   s   |j tkst|jdkst|jd }|j tks4tt| t|jkr`tdt	|  d|j i }|jD ]}| | ||< qj|S )aX  Reorder user-provided kwargs to match the order in `spec`. `spec` is
    expected to be the in_spec of an exported program, i.e. the spec that
    results from flattening `(args, kwargs)`.

    We need this to provide consistent input ordering, such so that users can
    pass in foo(a=a, b=b) OR foo(b=b, a=a) and receive the same result.
          zkwarg key mismatch: Got z but expected )
typetupleAssertionErrorZnum_childrenchildren_specsdictsetcontext
ValueErrorlist)r   r	   Zkwargs_specZreordered_kwargskw r   J/var/www/html/venv/lib/python3.8/site-packages/torch/export/_tree_utils.pyreorder_kwargs   s    	

r   )spec1spec2equivalence_fnr
   c                 C   s`   || j | j|j |jsdS t| jt|jkr2dS t| j|jD ]\}}t|||s@ dS q@dS )a,  Customizable equivalence check for two TreeSpecs.

    Arguments:
        spec1: The first TreeSpec to compare
        spec2: The second TreeSpec to compare
        equivalence_fn: A function to determine the equivalence of two
            TreeSpecs by examining their types and contexts. It will be called like:

                equivalence_fn(spec1.type, spec1.context, spec2.type, spec2.context)

            This function will be applied recursively to all children.

    Returns:
        True if the two TreeSpecs are equivalent, False otherwise.
    FT)r   r   lenr   zipis_equivalent)r   r   r   Zchild_spec1Zchild_spec2r   r   r   r   !   s    r   N)typingr   r   r   r   Ztorch.utils._pytreer   r   strr   r   boolr   r   r   r   r   <module>   s   "