o
    Xi%                     @  s   d Z ddlmZ ddlZddlZddlmZmZ ddlmZ ddl	m
Z
mZ ddlmZmZ edZed	ZdddZG dd dZdS )zLogic for cloning graphs.    )annotationsN)CallableMapping)TypeVar)Concatenate	ParamSpec)_core_enumsPRfunc#Callable[Concatenate[Cloner, P], R]returnc                   s   t  d fd	d
}|S )z2Decorator to capture error context during cloning.selfClonerargsP.argskwargsP.kwargsr   r   c              
     sP   z | g|R i |W S  t y' } ztd j d|d||d }~ww )NzIn z with args z and kwargs )	ExceptionRuntimeError__name__)r   r   r   er    C/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/_cloner.pywrapper   s   z'_capture_error_context.<locals>.wrapperN)r   r   r   r   r   r   r   r   )	functoolswraps)r   r   r   r   r   _capture_error_context   s   r   c                   @  sn   e Zd ZdZdd dddd-ddZed.ddZed/ddZed0d!d"Zed1d%d&Z	ed2d*d+Z
d,S )3r   z[Utilities for creating a copy of IR objects with substitutions for attributes/input values.c                 C  s   d S Nr   )_r   r   r   <lambda>.   s    zCloner.<lambda>F)post_processresolve_ref_attrsallow_outer_scope_valuesattr_mapMapping[str, _core.Attr]	value_map%dict[_core.Value, _core.Value | None]metadata_propsdict[str, str]r#   Callable[[_core.Node], None]r$   boolr%   r   Nonec                C  s(   || _ || _|| _|| _|| _|| _dS )a  Initializes the cloner.

        Args:
            attr_map: A mapping from attribute names to attributes to substitute, used when
                inlining functions.
            value_map: A mapping from original values to cloned values. If a value is not in
                this map, it is assumed to be a graph input and will be cloned as a new value.
            metadata_props: Metadata properties to add to cloned nodes.
            post_process: A callback invoked after cloning each node, allowing for additional
                processing on the cloned node.
            resolve_ref_attrs: Whether to resolve reference attributes using the attr_map.
                Set to True when inlining functions.
            allow_outer_scope_values: When True, values that are from outer scopes
                (not defined in this graph) will not be cloned. Instead, the cloned
                graph will reference the same outer scope values. This is useful
                when cloning subgraphs that reference values from the outer graph.
                When False (default), values from outer scopes will cause an error if they
                are referenced in the cloned graph.
        N)
_value_map	_attr_map_metadata_props_post_process_resolve_ref_attrs_allow_outer_scope_values)r   r&   r(   r*   r#   r$   r%   r   r   r   __init__(   s   
zCloner.__init__value_core.Value_core.Value | Nonec                 C  s
   | j | S r    )r/   )r   r6   r   r   r   
_get_valueL   s   
zCloner._get_valuec                 C  s   || j v r| j | }|d usJ d| d|S tj|j|j|jd ur(|j nd |j|jd}|j	r:|j	
|j	 |jrD|j
|j || j |< |S )NzBUG: Value z mapped to None in value map)nametypeshape
doc_stringconst_value)r/   r   Valuer:   r;   r<   copyr=   r>   r*   updatemeta)r   r6   known_value	new_valuer   r   r   _clone_or_get_valueP   s"   


zCloner._clone_or_get_valuekeystrattr
_core.Attr_core.Attr | Nonec                   s  |  s>|jtjjkr | }tj|tjj||j	dS |jtjj
kr< fdd| D }tj|tjj
||j	dS |S |  sDJ  jsI|S |j}|d u rTtd| jv r j| }|  sntj||j|j|j	dS |jd usuJ tj||j|j|j	dS d S )N)r=   c                      g | ]}  |qS r   )clone_graph).0graphr   r   r   
<listcomp>o       z%Cloner.clone_attr.<locals>.<listcomp>z$Reference attribute must have a name)is_refr;   r	   AttributeTypeGRAPHrL   as_graphr   Attrr=   GRAPHS	as_graphsr3   ref_attr_name
ValueErrorr0   r6   RefAttr)r   rF   rH   rN   graphsrY   ref_attrr   rO   r   
clone_attrf   s:   

zCloner.clone_attrnode
_core.Nodec           
        s  g }|j D ];}|d u r|| q|jvr8js2|jr"|jjp!dnd}td| d| d| d|| q|| q fdd|j	 D }i j
|j}tj|j|j|||jt|j|j|j|j|d	
}|jrx|j|j t|j|jD ]:\}}	|	j|< |j|	_|jd ur|j nd |	_|j|	_|j|	_|j|	_|jr|	j|j |jr|	j|j q| |S )
Nz<anonymous>z	<unknown>zValue 'z' used by node 'z'' is an outer-scope value (from graph 'z'), but 'allow_outer_scope_values' is set to False. Consider creating a GraphView and add the value to its inputs then clone, or setting 'allow_outer_scope_values' to True to allow referencing outer-scope values.c                   s(   g | ]\}} ||  d ur qS r    )r^   )rM   rF   r6   rD   r   r   r   rP      s
    z%Cloner.clone_node.<locals>.<listcomp>)overloadnum_outputsversionr:   r=   r*   )inputsappendr/   r4   rN   r:   rZ   r9   
attributesitemsr1   r*   r   Nodedomainop_typerb   lenoutputsrd   r=   rB   rA   zipr<   r@   r;   r>   r2   )
r   r_   
new_inputsinput
graph_namenew_attributesnew_metadatanew_nodeoutput
new_outputr   ra   r   
clone_node   s^   

 

zCloner.clone_noderN   _core.Graph | _core.GraphView_core.Graphc              	     s    fdd|j D } fdd|j D } fdd|D }ttd  fdd|jD }tj|||||j	|j
 |jd}|jrJ|j|j |jrT|j|j |S )z+Clones a graph with shared TensorProtocols.c                   rK   r   rE   rM   vrO   r   r   rP      rQ   z&Cloner.clone_graph.<locals>.<listcomp>c                   rK   r   rz   r{   rO   r   r   rP      rQ   c                   rK   r   )rw   )rM   r_   rO   r   r   rP      rQ   r7   c                   rK   r   )r9   r{   rO   r   r   rP      rQ   )nodesinitializersr=   opset_importsr:   )re   r~   valuestypingcastlistrm   r   Graphr=   r   r@   r:   r*   rA   rB   )r   rN   input_valuesr~   r}   output_values	new_graphr   rO   r   rL      s(   	zCloner.clone_graphN)r&   r'   r(   r)   r*   r+   r#   r,   r$   r-   r%   r-   r   r.   )r6   r7   r   r8   )r6   r7   r   r7   )rF   rG   rH   rI   r   rJ   )r_   r`   r   r`   )rN   rx   r   ry   )r   
__module____qualname____doc__r5   r   r9   rE   r^   rw   rL   r   r   r   r   r   %   s     $'>r   )r   r   r   r   )r   
__future__r   r   r   collections.abcr   r   r   typing_extensionsr   r   onnx_irr   r	   r
   r   r   r   r   r   r   r   <module>   s   
