o
    Xi[O                     @  sb  d dl mZ g dZd dlZd dlZd dlmZmZmZ d dl	Z
d dlZd dlZd dlmZ d dlZd dlmZ dd Zd	d
 Zdd Zdd ZefddZefddZdd ZdRddZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Z G d*d+ d+Z!d,d- Z"d.d/ Z#d0d1 Z$d2d3 Z%dSd8d9Z&dTd=d>Z'dUdBdCZ(dVdGdHZ)	IdWdXdPdQZ*dS )Y    )annotations)assert_isomorphicassert_isomorphic_graphassert_isomorphic_functionassert_onnx_proto_equalN)Any
CollectionSequence)parser)irc                 C     t t| t|sJ dS )z.Assert two graphs or functions are isomorphic.N)_isomorphic_to_function_or_graph)graph_or_function_1graph_or_function_2 r   O/home/ubuntu/.local/lib/python3.10/site-packages/onnxscript/testing/__init__.pyr      s   r   c                 C  r   )z!Assert two graphs are isomorphic.N)r   _to_graph_proto)graph1graph2r   r   r   r   !      r   c                 C  r   )z$Assert two functions are isomorphic.N)r   _to_function_proto)fn1fn2r   r   r   r   &   r   r   c                 C  s   | |kS Nr   )xyr   r   r   _default_equality_op+   s   r   c                 C  s6   | | r| | o|t|| t|| S | |  S )zCheck two proto object have same value for optional field.
    This is restricted to simple field types where == comparison is sufficient.
    )HasFieldgetattr)fieldobj1obj2equalsr   r   r   _same_optional/   s   
 r$   c                   s0   t | t |kr
dS t fddt| |D S )NFc                 3  s    | ]
\}} ||V  qd S r   r   ).0val1val2r#   r   r   	<genexpr>;   s    z!_same_repeated.<locals>.<genexpr>lenallzip)values1values2r#   r   r(   r   _same_repeated8   s   r0   c                 C  s   dd }|| ||kS )z0Compare repeated StringStringEntryProto as maps.c                 S  s   dd | D S )Nc                 S     i | ]}|j |jqS r   )keyvalue)r%   r   r   r   r   
<dictcomp>B       z;_same_string_string_map.<locals>.to_map.<locals>.<dictcomp>r   )protor   r   r   to_mapA   s   z'_same_string_string_map.<locals>.to_mapr   )proto1proto2r7   r   r   r   _same_string_string_map>   s   r:   tp1onnx.TensorPrototp2c                 C  s   | j |j krdS td| |sdS | ds|drdS | j|j  kr*| jjkrDn nt| }t|}tj	|
 |
 ddsDdS td| |sLdS td| |sTdS t| j|js]dS dS )NF	data_typesegmentT)	equal_nan
doc_stringdata_location)dimsr$   r   rB   DataLocationDEFAULTr   
from_protonparray_equalnumpyr:   external_data)r;   r=   tensor1tensor2r   r   r   _same_tensorG   s$    

rM   c                 C  s   t d| |ot d| |S )N	dim_value	dim_param)r$   )dim1dim2r   r   r   	_same_dim_   s   rR   c                 C  s   t | j|jtS r   )r0   dimrR   )shape1shape2r   r   r   _same_shapec   s   rV   c                 C  s   | j |j kotd| |tS )Nshape)	elem_typer$   rV   )tt1tt2r   r   r   _same_tensor_typeg   s   r[   c                 C  s   t d| |tS )Ntensor_type)r$   r[   )r;   r=   r   r   r   
_same_typek   s   r]   c                 C  s&   t d| |ot d| |tot d| |S )NnametyperA   )r$   r]   )vi1vi2r   r   r   _same_value_infop   s
   
rb   c                 C  s   dD ]}t || |s dS qt d| |tsdS t| j|jts!dS dD ]}t| |t||kr2 dS q#t d| ||s<dS t| j|j|sFdS dD ]}| |sT||rW dS qHdS )N)r_   ref_attr_namefisFt)floatsintsstringsg)sparse_tensortpT)r$   rM   r0   tensorsr   graphsr   )attr1attr2graph_equalityr    r   r   r   
_same_attrx   s*   rs   c                 C  s\   t | t |kr
dS dd | D }|D ]}|j|vr dS ||j }t|||s+ dS qdS )NFc                 S  s   i | ]}|j |qS r   r^   )r%   ar   r   r   r4          z_same_attrs.<locals>.<dictcomp>T)r+   r^   rs   )attrs1attrs2rr   	attrs1maprq   rp   r   r   r   _same_attrs   s   

rz   c                 C  s   t | tjr	| jS | S )z9Return the name of an input/output of a function or graph)
isinstanceonnxValueInfoProtor^   )r   r   r   r   _ioname   s   r~   c                   @  sJ   e Zd ZdZdddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dS )_Matcherz7An isomorphism matcher for two functions or two graphs.returnNonec                 C  s8   dd }||| _ ||| _|| _|| _i | _|| _d S )Nc                 S  s`   i }t | jD ]\}}d|f|t|< qt | jD ]\}}t |jD ]
\}}||f||< q"q|S )zCompute a map from variables v to their definition-sites.
            A definition-site (n, i) indicates the i-th output of n-th node
            The special value (-1, i) is used to indicate the i-th input of a function/graph.
            )	enumerateinputr~   nodeoutput)rd   resultre   r   ninxir   r   r   defmap   s   z!_Matcher.__init__.<locals>.defmap)defmap1defmap2fg1fg2node_mappingouter_scope)selfr   r   r   r   r   r   r   __init__   s   


z_Matcher.__init__c                 C  s   |dkr|dkS |dkrdS || j vs|| jvr0|| j v s'|| jv s'| jdu r)dS | j||S | j | \}}| j| \}}||koG| ||S )zMatch two variables (strings). FN)r   r   r   
same_value	same_node)r   var1var2node1index1node2index2r   r   r   r      s   z_Matcher.same_valuec                 C  s   |dkr
|dkr
dS |dks|dkrdS || j v r | j | |kS | jj| }| jj| }|j|jkr4dS |j|jkr<dS t|j|j| jsGdS | 	|j
|j
sQdS || j |< dS )zDMatch two node-indices. The special node-index -1 represents inputs.r   TF)r   r   r   r   op_typedomainrz   	attributesame_sub_graphsame_value_listr   )r   n1n2r   r   r   r   r   r      s$   

z_Matcher.same_nodec                   s0   t |t |kr
dS t fddt||D S )z@Match two lists of variables (either a string or ValueInfoProto)Fc                 3  s(    | ]\}}  t|t|V  qd S r   )r   r~   )r%   r   r   r   r   r   r)      s   & z+_Matcher.same_value_list.<locals>.<genexpr>r*   )r   list1list2r   r   r   r      s   z_Matcher.same_value_listc                 C  s   t ||| }| S )Match two sub-graphs.)r   
same_graph)r   g1g2sub_graph_matcherr   r   r   r      s   z_Matcher.same_sub_graphc                 C  sX   | j }| j}t|j|jtsdS |js|jrdS |js|jr dS | |j|js*dS dS )r   FT)	r   r   r0   r   rb   initializersparse_initializerr   r   )r   r   r   r   r   r   r      s   z_Matcher.same_graphc                 C  s   t | jjt | jjkrdS t| jjt| jjkrdS dd }|| j|| jkr,dS t | jjt | jjkr:dS | | jj| jjsFdS t | j	t | jjkrSdS t t| j	
 t | jjkrddS dS )z Match (top-level) two functions.Fc                 S  s   dd | j D S )Nc                 S  r1   r   r   version)r%   entryr   r   r   r4     r5   z;_Matcher.same_function.<locals>.imports.<locals>.<dictcomp>opset_importrd   r   r   r   imports  s   z'_Matcher.same_function.<locals>.importsT)r+   r   r   r   setr   r   r   r   r   values)r   r   r   r   r   same_function  s    z_Matcher.same_functionN)r   r   )__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r      s    
r   c                 C  sd   t | |d}t| tjrt|tjstd| S t| tjr.t|tjs*td| S td)zChecks that two function/graph bodies are isomorphic.
    Assumes that the inputs are valid FunctionProto/GraphProto.
    Use a separate check to verify that the inputs satisfy
    FunctionProto/GraphProto requirements (like no duplicate attributes).
    Nz1Both inputs must be same type (function or graph)z3Inputs must be either a FunctionProto or GraphProto)r   r{   r|   FunctionProto	TypeErrorr   
GraphProtor   )r   r   matcherr   r   r   r   *  s   r   c                 C  sL   t | tjr| S t | tjr|  S t | trt| S t	dt
|  d)NCannot convert z to FunctionProto)r{   r|   r   
onnxscriptOnnxFunctionto_function_protostrr
   parse_functionr   r_   r   r   r   r   r   <  s   

r   c                 C  sN   t | tjr| S t | tjr|  jS t | trt	| S t
dt|  d)Nr   z to ModelProto)r{   r|   r   r   r   to_model_protographr   r
   parse_graphr   r_   )rk   r   r   r   r   F  s   


r   c                 C  sZ   t | tjr| S t | tjr| S t | tjr| jS t | tjr#|  S t	dt
|  d)Nr   z to FunctionProto or GraphProto)r{   r|   r   r   
ModelProtor   r   r   r   r   r_   )objr   r   r   r   P  s   r   r   onnx.OperatorSetIdProtor   tuple[str, int]c                 C  s   | j | jfS r   r   r   r   r   r   _opset_import_key\  s   r   
value_infoonnx.ValueInfoProtor   c                 C  s   | j S r   rt   )r   r   r   r   _value_info_key`  s   r   functiononnx.FunctionPrototuple[str, str, str]c                 C  s   | j | jt| ddfS )Noverloadr   )r   r^   r   )r   r   r   r   _function_keyd  s   r   with_duplicatesCollection[Any]	list[Any]c                 C  s4   t  }g }| D ]}||v r|| || q|S )z5Return a list of duplicated elements in a collection.)r   appendadd)r   seen
duplicatesr   r   r   r   _find_duplicatesh  s   
r   Factual%google.protobuf.message.Message | Anyexpectedignore_initializer_value_protoboolr   c                   s  t | t |u sJ dt |  dt | dd |  D }dd | D }tt| t| B }t| tjrSt|tjrSdd | jD  dd |jD nt  t g }|D ] }t	| |}t	||}	t|t
rt|	t
rt|ttfst|	ttfsg }
g }|d	krt|td
}t|	td
}	dd |D }
dd |	D }n^|dkr|rt| tjrt|tjr͇ fdd|D }fdd|	D }	t|td
}t|	td
}	dd |D }
dd |	D }n|dkrt|td
}t|	td
}	dd |D }
dd |	D }|
|kr<t|
t| }t|t|
 }d| d| d| dt | dt|
 dt| }|| q]t|t|	kr_d| dt| dt|	 dt | }|| q]tt|D ]}|| }|	| }t|tjjjrt|tjjjrz
t|||d W qe ty } z,d| d | d!t | d"t | d#| d$| }t|d% | }|| W Y d&}~qed&}~ww ||krt|trt|trt|rt|rqed| d | d!t | d"t | }tt| t| D ]	}|d'| 7 }q|| qeq]t|tjjjr0t|	tjjjr0t||	|d q]||	kr^t|trNt|	trNt|rNt|	rNq]d| d(| d)|	 }|| q]|rvtd*t |  dt | d'd' | d&S )+a?  Assert that two ONNX protos are equal.

    Equality is defined as having the same fields with the same values. When
    a field takes the default value, it is considered equal to the field
    not being set.

    Sequential fields with name `opset_import`, `value_info`, and `functions` are
    compared disregarding the order of their elements.

    Args:
        actual: The first ONNX proto.
        expected: The second ONNX proto.
        ignore_initializer_value_proto: Ignore value protos for initializers if there
            are extra ones in the actual proto.
    zType not equal: z != c                 S     i | ]\}}|j |qS r   rt   r%   r    r3   r   r   r   r4         z+assert_onnx_proto_equal.<locals>.<dictcomp>c                 S  r   r   rt   r   r   r   r   r4     r   c                 S     h | ]}|j qS r   rt   r%   re   r   r   r   	<setcomp>      z*assert_onnx_proto_equal.<locals>.<setcomp>c                 S  r   r   rt   r   r   r   r   r     r   r   )r2   c                 S     g | ]}t |qS r   r   r%   r   r   r   r   
<listcomp>  rv   z+assert_onnx_proto_equal.<locals>.<listcomp>c                 S  r   r   r   r   r   r   r   r     rv   r   c                      g | ]	}|j  vr|qS r   rt   r%   r   )actual_initializer_namesr   r   r     
    
c                   r   r   rt   r   )expected_initializer_namesr   r   r     r   c                 S  r   r   r   r   r   r   r   r     rv   c                 S  r   r   r   r   r   r   r   r     rv   	functionsc                 S  r   r   r   r%   r   r   r   r   r     rv   c                 S  r   r   r   r   r   r   r   r     rv   zField z  not equal: keys_only_in_actual=z, keys_only_in_expected=z. Field type: z. Duplicated a_keys: z, duplicated b_keys: z not equal: len(a)=z	, len(b)=z Field type: )r   z index z. in sequence not equal. type(actual_value_i): z, type(expected_value_i): z, actual_value_i: z, expected_value_i: z

Caused by the above error

N
z not equal. field_actual: z, field_expected: zProtos not equal: )!r_   
ListFieldssortedr   keysr{   r|   r   r   r   r	   r   bytesr   r   r   r   r   r+   rangegoogleprotobufmessageMessager   AssertionErrorfloatmathisnandifflibndiff
splitlinesjoin)r   r   r   a_fieldsb_fields
all_fieldserrorsr    a_valueb_valuea_keysb_keyskeys_only_in_actualkeys_only_in_expectederror_messagere   actual_value_iexpected_value_ieliner   )r   r   r   r   s  s  









0
$


"


"r   )r;   r<   r=   r<   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )F)r   r   r   r   r   r   r   r   )+
__future__r   __all__r  r  typingr   r   r	   google.protobuf.messager   rI   rG   r|   r
   r   r   r   r   r   r   r$   r0   r:   rM   rR   rV   r[   r]   rb   rs   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sN   	
	 





