o
    Xi                     @  sF  d dl mZ d dlmZmZmZ d dlZd dlZd dlm	Z	m
Z
mZmZmZ d dlZd dlmZ dZdZh dZd	d
 ZdQddZdd Zdd Zdd ZdRddZdd ZdSd d!ZdTd"d#ZdUd)d*ZdVd-d.ZdWd1d2Z dXd3d4Z!dYd7d8Z"dZd:d;Z#d[d<d=Z$d\d>d?Z%G d@dA dAZ&d]dEdFZ'	d^dGdGdGdGdHd_dOdPZ(dS )`    )annotations)AnyOptionalSequenceN)FunctionProto
GraphProto
ModelProtoTensorProtoValueInfoProto)type_annotationz       >#   asifinisoranddefdelfornottryNoneTrueelifelsefrompasswithFalseasyncawaitbreakclassraisewhileyieldassertexceptglobalimportlambdareturnfinallycontinuenonlocalc                 C  s   | j dks	J d| jd }|dsdS |j}|jtjtjhv rPt|j	}|dkr9t
j|d}t|d S |dkrP|j	d dk rPt
j|}t| S dS )a<  Given an ONNX Constant-op node, returns a string representation of
    the constant-value in ONNXScript, if a compact representation is possible.
    Returns None otherwise.
    Supports only FLOAT/INT64 values and scalars and small rank-1 tensors.
    This needs to be reconciled with the ONNXScript converter.
    ConstantzExpected a constant noder   tN      )op_type	attributeHasFieldr1   	data_typer	   FLOATINT64lendimsonnxnumpy_helperto_arrayreshapestrreprtolist)
const_nodeattrtensor_protorankarraynparray rI   R/home/ubuntu/.local/lib/python3.10/site-packages/onnxscript/backend/onnx_export.py_get_const_repr9   s   


rK   nameValueInfoProto | strr,   r@   c                   s~   t | tr| j} t | tsJ | dksJ | tv rd|  S | d }| s/|dks/d|  } dd  d fdd	| D S )
ac  Converts given name into a valid python variable names.
    Handles names that clash with python keywords and common issues seen in ONNX models:
    * Identifiers like "5" (that do not start with an alpha character)
    * Identifiers that contain a dot like "layers.0.foo"
    This is a simple heuristic, and doesn't guarantee it avoids name-clashes.
     r_r   ___c                 S  s   |   s| dkr
| S dS )z(Replace invalid character by underscore.rP   )isalnum)charrI   rI   rJ   rename_charb   s   z+_cleanup_variable_name.<locals>.rename_charc                      g | ]} |qS rI   rI   ).0crT   rI   rJ   
<listcomp>f       z*_cleanup_variable_name.<locals>.<listcomp>)
isinstancer
   rL   r@   kwlistisalphajoin)rL   firstrI   rX   rJ   _cleanup_variable_nameP   s   


r`   c                    s   i   fdd} | S )zSReturns a renamer used to create short new names  (like v0, v1, ...) for variables.c                   sB   t | }| v r | S dt d  }|d usJ | |< |S )Nvr2   )r`   r:   )rL   var_namenew_namevariable_namesrI   rJ   renamerm   s   z(_make_short_name_mapper.<locals>.renamerrI   )rf   rI   rd   rJ   _make_short_name_mapperi   s   
rg   c                 C  s   t jj| ddS )z9Converts a onnx type into a type defined by *onnxscript*.F)
reversible)
onnxscript
onnx_typesonnx_type_to_onnxscript_repr)	onnx_typerI   rI   rJ   _translate_typez   s   rm   c                   sf   ddd dd  fdd| D  d	}|r.t|d
 tr.|dd dd |D  d	7 }| dS )z'Produce the script-functions signature.inprM   c                 S  s,   t | trt| j dt| j S t| S Nz: )r[   r
   r`   rL   rm   type)rn   rI   rI   rJ   	input_sig   s   
z'_translate_signature.<locals>.input_sig(, c                   rU   rI   rI   rV   xrq   rI   rJ   rY      rZ   z(_translate_signature.<locals>.<listcomp>)r   z -> (c                 S  s   g | ]}t |jqS rI   )rm   rp   rt   rI   rI   rJ   rY          :N)rn   rM   )r^   r[   r
   )inputsoutputsresultrI   rv   rJ   _translate_signature   s
   
  
r}   value_infosSequence[ValueInfoProto]c                   s2   ddd  fdd| D }d	 |}d
| d S )N
value_infor
   r,   r@   c                 S  s"   t  dt| j dt| j dS )N'z': ,)_SINGLE_INDENTr`   rL   rm   rp   )r   rI   rI   rJ   _translate_value_info   s   "z5_translate_value_infos.<locals>._translate_value_infoc                   rU   rI   rI   rt   r   rI   rJ   rY      rZ   z*_translate_value_infos.<locals>.<listcomp>
z{
z
})r   r
   r,   r@   r^   )r~   lineslines_joinedrI   r   rJ   _translate_value_infos   s   

r   c                 C  s0   t | trz| dW S  ty   Y | S w | S )Nzutf-8)r[   bytesdecodeUnicodeDecodeError)srI   rI   rJ   _to_str   s   
r   rD   onnx.AttributeProtoboolc                 C  s   |  do	| jdkS )Nref_attr_namerN   )r6   r   )rD   rI   rI   rJ   _is_attribute_ref      r   c                 C  s   | j tjjkr
| jS | j tjjkr| jS | j tjjkr t| j	S | j tjj
kr8| j}tj|r2|S tj|S | j tjjkrDt| jS | j tjjkrPt| jS | j tjjkr_ttt| jS td| d)Nz'Unable to return a value for attribute .)rp   r<   AttributeProtor8   fINTiSTRINGr   r   TENSORr1   external_data_helperuses_external_datar=   r>   FLOATSlistfloatsINTSintsSTRINGSmapstringsNotImplementedError)rD   rE   rI   rI   rJ   _attribute_value   s$   


r   namesset[str]graphr   r   c                 C  s\   |  dd |jD  |  dd |jD  |  dd |jD  |jD ]}t| | q$dS )z,Adds the names used in a graph to given set.c                 s      | ]}|j V  qd S NrL   rt   rI   rI   rJ   	<genexpr>       z._update_names_used_in_graph.<locals>.<genexpr>c                 s  r   r   r   rt   rI   rI   rJ   r      r   c                 s  r   r   r   rt   rI   rI   rJ   r      r   N)updateinputoutputinitializernode_update_names_used_in_node)r   r   r   rI   rI   rJ   _update_names_used_in_graph   s   
r   r   onnx.NodeProtoc                 C  sT   |  |j |  |j |jD ]}|drt| |j |jD ]}t| | qqd S )Ng)r   r   r   r5   r6   r   r   graphs)r   r   rD   r   rI   rI   rJ   r      s   


r   funr   c                 C  s2   |  |j |  |j |jD ]}t| | qd S r   )r   r   r   r   r   )r   r   r   rI   rI   rJ   _update_names_used_in_function   s
   
r   c                 C  s   t  }t||  |S r   )setr   )r   r   rI   rI   rJ   _names_used_in_function   s   
r   indexintc                 C  s   |t | jk o| j| dkS )z6Returns True iff the node has an input at given index.rN   )r:   r   )r   r   rI   rI   rJ   	has_input   s   r   r4   c                 C  s   | j |ko	| jdv S )N   ai.onnxrN   )r4   domain)r   r4   rI   rI   rJ   
is_onnx_op   r   r   c                 C  s$   t  }|jD ]}t|| q| |v S )z:Returns True iff the given name is used in the graph body.)r   r   r   )rL   r   r   r   rI   rI   rJ   _is_used_in_graph_body   s   
r   c                 C  s   | j d j}| jd j}| jD ]7}t|dr3t|j dkr3t|jdkr3|j d |kr3|jd |kr3qt }t|| ||v sC||v rF dS qdS )z+Returns True iff loop requires a condition.r2   r   IdentityTF)r   rL   r   r   r   r:   r   r   )r   cond_incond_outr   r   rI   rI   rJ   _cond_is_used_in_loop_body   s   
&
r   c                   @  s   e Zd ZdZdMd	d
Zdd Zdd Zdd ZdNddZdd Z	dOddZ
dPddZdd ZdPdd Zd!d" ZdPd#d$ZdPd%d&ZdPd'd(ZdQd+d,ZdRd/d0ZdSd3d4ZdTd7d8ZdTd9d:ZdUd?d@ZdVdDdEZdWdGdHZdXdJdKZdLS )Y	_Exporterz7Class used for recursive traversal of Proto structures.renamer   use_operatorsinline_constskip_initializersr,   r   c                C  sR   || _ |r	t }nt}| || _|| _i | _i | _t | _	g | _
|| _i | _d S r   )r   rg   r`   _handle_attrname_conflict_rename_variabler   	constants_attr_renamingr   _names_used_name_remappingsr   skipped_initializers)selfr   r   r   r   rename_functionrI   rI   rJ   __init__  s   
z_Exporter.__init__c                   s    fdd}|S )z?Add ref-attr-name-conflict handling logic to renaming function.c                   sx    | }|j vr|S j | }|d ur|S d}|}|jv r/| d| }|d7 }|jv s|j |< j| |S )Nr   rP   r2   )r   r   add)rL   rc   	alternatecounter	candidaterf   r   rI   rJ   new_renamer!  s   




z8_Exporter._handle_attrname_conflict.<locals>.new_renamerrI   )r   rf   r   rI   r   rJ   r     s   z#_Exporter._handle_attrname_conflictc                 C  sJ   t |tr|j}|dkrdS t| jD ]}||v r||   S q| |S )z9Converts an ONNX variable name to a python variable name.rN   r   )r[   r
   rL   reversedr   r   )r   varscoperI   rI   rJ   _translate_onnx_var4  s   

z_Exporter._translate_onnx_varc                 C  s   || j v r
| j | S | |S )z6Translates a reference to an ONNX variable (a r-value))r   r   )r   r   rI   rI   rJ   _translate_onnx_var_ref?  s   


z!_Exporter._translate_onnx_var_refr   r@   c                 C  s   |dv rdS t |S )Nr   opset)r`   )r   r   rI   rI   rJ   _rename_domainF  s   z_Exporter._rename_domainc                 C  s   |  | | S r   )r   )r   r   versionrI   rI   rJ   _make_opset_nameK  s   z_Exporter._make_opset_nameFc                 C  s\   t |}|r,|du rd}t|tstd|d|d|d| ||}| d| S |S )z]Generate name to be used for called op/function in a node or for a generated script function.Nr2   zversion must be an integer not z for domain=z
 and name=r   )r`   r[   r   	TypeErrorr   )r   r   r   rL   r   r   rI   rI   rJ   _make_callee_nameN  s   
z_Exporter._make_callee_namer   c                 C  s  g }t |drX|jD ]M}| jr9d}|jD ]}||9 }q|tkr9| |j}|| jv r3td|jd|| j|< q
t	j
jdg | |jg|d}	| j|	||d}
|
rW||
 q
t |drht|jd	krhtd
|jD ]}	| j|	||d}|r|	jr|d|	j 7 }|| qkd|}|S )zTranslates a graph body into python.
        The graph may be the main graph (of a model) or a subgraph (of a Loop or If node).
        r   r2   zInitializer z, is already present in skipped_initializers.r0   )valueindentsparse_initializerr   z0Unable to convert sparse_initilizer into python.  # r   )hasattrr   r   r;   _SMALL_TENSOR_SIZEr   rL   r   RuntimeErrorr<   helper	make_node_translate_nodeappendr:   r   r   r   r^   )r   r   opsetsr   codeinitsizedinit_py_namer   pyinitpynodefinalrI   rI   rJ   _translate_graph_body^  sH   









z_Exporter._translate_graph_bodyc           	   
   C  s  g }|j D ]}t|r||j|jf qt|}t|ttfr+||jt	|f qt|t
jrx|jj}t|jdkrRd| dt	| dddd d}nd| d	t|jd
t	|  dddd d}||j|f qt|trtj|}|jpd}d}||d|j dt|j7 }|d|j7 }|jr|d|j7 }|jr|d|j7 }|d7 }||j|f q||jt	|f qddd |D S )Nr   zmake_tensor("value", z, dims=[], vals=[nanznp.naninfznp.infz])z, dims=z, vals=rw   r   zexternal_tensor(rs   z	, offset=z	, length=c                 s  s"    | ]\}}| d | V  qdS )=NrI   )rV   kra   rI   rI   rJ   r          z2_Exporter._translate_attributes.<locals>.<genexpr>)r5   r   r   rL   r   r   r[   r@   r   rA   npndarrayr1   r7   r:   shaperB   replacer   ravelr	   r<   r   ExternalDataInfor;   locationoffsetlengthr^   )	r   r   
attributesatr   
onnx_dtypetextmetadatarL   rI   rI   rJ   _translate_attributes  sJ   


 z_Exporter._translate_attributesc           
      C  s  t | }| |jd }| d| dg}t|jdkr+td|jdt|j d|j}|d jdkrA|d j|d	 j}}	n|d	 j|d j}}	|	| j
|	||d	 d
 || |j|	j|d	  |	| d |	| j
|||d	 d
 || |j|j|d	  d|S )z!Translates a node If into python.r   zif ry      zNode z expected two attributes not r   else_branchr2   r   zelse:r   )r   r   r   r:   r5   r   r4   rL   r   r   r   extend_emit_assignr   r^   )
r   r   r   r   sindentcondr   attsr  then_branchrI   rI   rJ   _translate_if  s:   
z_Exporter._translate_ifc                   sV   fddt | d
fdd t|ttfr ||gS  fdd	t||D S )Nc                   s   t | tr| j}  | S r   )r[   r
   rL   r   )ru   r   rI   rJ   to_var  s   

z&_Exporter._emit_assign.<locals>.to_varlhs_varr@   rhs_varc                   s     |  d| S )N = rI   )r  r   )r  r  rI   rJ   assign  s   z&_Exporter._emit_assign.<locals>.assignc                   s   g | ]	\}} ||qS rI   rI   )rV   ru   y)r"  rI   rJ   rY     s    z*_Exporter._emit_assign.<locals>.<listcomp>)r  r@   r   r@   )r   r[   r@   r
   zip)r   lhsrhsr   rI   )r"  r   r  r  rJ   r    s   z_Exporter._emit_assignc              	   C  sh  |j d j}t| }g }|jd j}t|dr"d}| |jd }	nt||}d}	| |}
|jd j}|jd j}| |}d}t|drT|	| 
||jd | nt|}tt|jd d}|jdd }|jdd }|jd|d  }|jd| }|	| 
||| |jrd|j }nd}|r|s|| d|
 d	|	 d
|  | || jd |< nI|s|r|| d| d|  n7|r|r|| d|
 d	|	 d
|  || t d| d || td  d n	td|jd|| j|||d d |r|	| 
|||d  |	| 
|||d  |	| 
||| d|S )z#Translates a node Loop into python.r   TNr2   r  r   rN   zfor z
 in range():zwhile ry   zif not r"   zUnable to export loop type z0 into python because there is no stop condition.r   r   )r5   r   r   r   rL   r   r   r   r   r  r  r   maxr:   r   r   r   r4   r   r^   )r   r   r   r   bodyr  rowsonnx_iter_varuse_iter_varn_iteriter_varr   r   py_conduse_loop_condnum_state_vars
actual_ins
formal_insformal_outsactual_outs	node_namerI   rI   rJ   _translate_loop  sd   




  
z_Exporter._translate_loopc                 C  s   t  )z#Translates a node Scan into python.)r   )r   r   r   r   rI   rI   rJ   _translate_scan.  s   z_Exporter._translate_scanc                   s`  t |tr
|d }n|} jr(|jdkr(t|}|d ur(t| j|jd < dS |jdv r]|jdkr: j|||dS |jdkrG j	|||dS |jd	krT j
|||dS td
|jdtdd |jD rptd
|jddddddddddddddd}t| } jr|j|v r|  |jd  dd||j  dt j|j S  j|j||j |jdd} |}	t|jdkrt|	dkrd |	 }	g }
t|jD ]\}}|d!v r|
d"|  q|
 | qև fd#d$|jD }|jd%krt|jd&krt|jd&kr|
d |d krdS |d |
d|d'd ||	d(g}d|S ))N	onnx_noder0   r   rN   >   IfLoopScanr;  r   r<  r=  zUnable to export node type z into python.c                 s  s.    | ]}t |d o|jo|j dkV  qdS )r   r   N)r   r   ByteSize)rV   attrI   rI   rJ   r   E  s   , z,_Exporter._translate_node.<locals>.<genexpr>+-*@/z**&|>z==<z>=z<=)AddSubMulMatMulDivPowAndOrGreaterEqualLesserGreaterOrEqualLessOrEqualr!   Tr   rs   )rN   NrP   c                      g | ]}  |qS rI   )r   rt   r  rI   rJ   rY   i  rx   z-_Exporter._translate_node.<locals>.<listcomp>r   r2   rr   rw   )r[   dictr   r4   rK   r@   r   r   r  r8  r9  r   anyr5   r   r   r   r^   r   r   r   r   r   r  r:   	enumerater   )r   r:  r   r   r   valopsr  callee_nameattributes_stroutput_namesr   oinput_namesr  rI   r  rJ   r   2  s~   





 

,

z_Exporter._translate_noder   r   c                 C  s6   |dv r
d| dS |  ||}| d| d| dS )Nr   z'from onnxscript.onnx_opset import opsetr   z
 = Opset('z', )
)r   )r   r   r   varnamerI   rI   rJ   _translate_opset_import|  s   z!_Exporter._translate_opset_importopset_imports!Sequence[onnx.OperatorSetIdProto]c                   s   d  fdd|D S )NrN   c                   s   g | ]
}  |j|jqS rI   )re  r   r   rt   r  rI   rJ   rY     s    z6_Exporter._translate_opset_imports.<locals>.<listcomp>r   )r   rf  rI   r  rJ   _translate_opset_imports  s   z"_Exporter._translate_opset_importsproto'ModelProto | FunctionProto | GraphProtoc                   sR   t  dr'|  j}t tr%t fdd jD s%||  jd7 }|S dS )Nopset_importc                 3  s    | ]	}|j  j kV  qd S r   )r   rt   ri  rI   rJ   r     s    z8_Exporter._translate_opset_imports_of.<locals>.<genexpr>r2   rN   )r   rh  rk  r[   r   rZ  re  r   )r   ri  r  rI   rl  rJ   _translate_opset_imports_of  s   

z%_Exporter._translate_opset_imports_offunprotoonnx.FunctionProtoc                   sv   t |dfdd fdd|jD } fdd|jD }d	|| }t|jd
kr1d}nd}d| d| S )z%Generate signature for FunctionProto.	attr_namer@   r,   c                   s>   d  j | <  j|  | tjj}t|}|  d| S ro   )	r   r   r   getr<   r   r   r   !onnx_attr_type_to_onnxscript_repr)rp  rp   typerep)r   type_maprI   rJ   attr_sig  s
   

z9_Exporter._translate_function_signature.<locals>.attr_sigc                   rX  rI   r   rt   r  rI   rJ   rY     rx   z;_Exporter._translate_function_signature.<locals>.<listcomp>c                   rU   rI   rI   rt   )ru  rI   rJ   rY     rZ   rs   r   z:
   # Attribute parameters default-values not handled yet.rN   rr   r'  N)rp  r@   r,   r@   )_attribute_param_typesr   r5   r^   r:   attribute_proto)r   rn  rz   attrsinput_and_attrsmessagerI   )ru  r   rt  rJ   _translate_function_signature  s   z'_Exporter._translate_function_signaturec                   s$  i }|j D ]}|j||j< qi _t|}fdd|D }t|_g  d fdd}|jd	}|d
| d |jd	|j	}
|}	|d| |	  |jr^|d|j d ji  |jD ]}
|j|
|d	d qgdfdd|jD }|d|  j  d S )z'Generate python code for FunctionProto.c                   rX  rI   rv  rt   r  rI   rJ   rY     rx   z1_Exporter._translate_function.<locals>.<listcomp>liner@   r,   r   c                        |  d S r   r   r}  r|   rI   rJ   add_line     z/_Exporter._translate_function.<locals>.add_liner2   z@script(rw   def z    """"""r   rs   c                 3      | ]}  |V  qd S r   rv  rt   r  rI   rJ   r         z0_Exporter._translate_function.<locals>.<genexpr>z    return r   Nr}  r@   r,   r   )rk  r   r   r   r   r   r   r   r   rL   r|  
doc_stringr   r   r   r   r^   r   pop)r   rn  r   importedused_proto_namesrenamed_names_usedr  
opset_namefun_namefun_sigr   return_valuesrI   r|   r   rJ   _translate_function  s.   





z_Exporter._translate_functionmodelonnx.ModelProtofunction_nameOptional[str]c                   s  |j }i }|jD ]}|j||j< q|d u rt|j}g  d fdd}jr+d}t}nd}d	}|| d
 || d| t|j	|j
  |t }|j}	|	rY|| d|	 d |j|||d dfdd|j
D }
|| d|
  d }jrt|j}|||S |S )Nr}  r@   r,   r   c                   r~  r   r  r  r  rI   rJ   r     r  z'_Exporter._translate_graph.<locals>.addr  r2   rN   z	@script()r  r  r   rs   c                 3  r  r   rv  rt   r  rI   rJ   r     r  z-_Exporter._translate_graph.<locals>.<genexpr>zreturn r   r  )r   rk  r   r   r`   rL   r   r   r}   r   r   r  r   r^   r   r   r   _substitute_initializers)r   r  r  r   r   r  r   indent_levelr   docr  scriptr~   rI   r  rJ   _translate_graph  s6   

 

z_Exporter._translate_graphr  script_function_namer~   c                   s   | j  }t d fdd|D }d fd	d
dfdd| j  D }d fdd|D }d| d| d| d  d| d  d| d  d| d  d  dS )Nr   c                 3  s    | ]
}  | d V  qdS r   NrI   rt   rQ   rI   rJ   r     s    z5_Exporter._substitute_initializers.<locals>.<genexpr>rL   r@   r   r	   r,   c                   sh   d dd |jD }|jtjkr  |  d| dS |jtjkr+  |  d| dS td|j d	)
Nr   c                 s  s    | ]}t |V  qd S r   )r@   )rV   r   rI   rI   rJ   r     s    zL_Exporter._substitute_initializers.<locals>.generate_rand.<locals>.<genexpr>z = np.random.rand(z).astype(np.float32)z& = np.random.randint(-128, 127, size=(z,), dtype=np.int8)z4Unable to generate random initializer for data type r   )r^   r;   r7   r	   r8   INT8r   )rL   r   r  r  rI   rJ   generate_rand  s   z9_Exporter._substitute_initializers.<locals>.generate_randc                 3  s    | ]
\}} ||V  qd S r   rI   )rV   keyr   )r  rI   rJ   r     s    
c                 3  s"    | ]}    | d V  qdS r  rI   rt   r  rI   rJ   r     r  z
value_infos = z

def make_model(
z
):
z

zmodel = z).to_model_proto(value_infos=value_infos)
z4return model

def make_model_with_random_weights():
zmodel = make_model(
rc  zreturn model
)rL   r@   r   r	   r,   r@   )r   keysr   r^   items)r   r  r  r~   
init_namesinitializers_as_paramsrandom_initializer_valuesindented_initializers_as_paramsrI   )rQ   r  rJ   r    s>   

	z"_Exporter._substitute_initializers6onnx.ModelProto | onnx.GraphProto | onnx.FunctionProtoc                 C  s   t |tr	|j}n|}t }t|jt|j D ]}t|dr2t|j	}|j
dddd }|| qt|}|r@dd| S dS )	z7Generate import statements for types used in the graph.rp   [r2   )maxsplitr   z"from onnxscript.onnx_types import rs   rN   )r[   r   r   r   r   r   r   r   rm   rp   splitr   sortedr^   )r   ri  graph_or_function
used_typesr1   tsitssorted_typesrI   rI   rJ   _import_onnx_types  s   



z_Exporter._import_onnx_types$onnx.ModelProto | onnx.FunctionProtoc                   s   g  d fdd}|d |d |d	 |d
 |d | | t|tr=fdd|jD }||| nt|tsDJ |g}||  	| |d d
 }d|v rjtd| |S )Nr}  r@   r,   r   c                   r~  r   r  r  r  rI   rJ   r   ,  r  z_Exporter.export.<locals>.addzimport numpy as npzfrom onnx import TensorProtoz#from onnx.helper import make_tensorz.from onnxscript import script, external_tensorz#from onnxscript.values import Opsetc                   rX  rI   )r  )rV   r   r  rI   rJ   rY   8  rx   z$_Exporter.export.<locals>.<listcomp>rN   r   z
returnzThe produced code is wrong.
r  )r  r[   r   	functionsr   r  r   r  rm  r  r^   SyntaxError)r   ri  r  r   translated_functionsr   rI   r  rJ   export'  s(   


z_Exporter.exportN)
r   r   r   r   r   r   r   r   r,   r   )r   r@   r,   r@   )F)r   )r   r@   r   r   r,   r@   )rf  rg  r,   r@   )ri  rj  r,   r@   )rn  ro  r,   r@   )r  r  r  r  r,   r@   )r  r@   r  r@   r~   r@   r,   r@   )ri  r  r,   r@   )ri  r  r  r  r,   r@   )__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r  r  r  r8  r9  r   re  rh  rm  r|  r  r  r  r  r  rI   rI   rI   rJ   r     s2    



(
)#

M

J





"
*r   rn  ro  ,dict[str, onnx.AttributeProto.AttributeType]c                   s:   i  d fdddfd	d
| j D ]}| q S )zPCompute mapping from (names of) attribute parameters of function to their types.r   r   r,   r   c                   sb   | j D ]+}t|r|j |j< q|jtjjkr|j q|jtjjkr.|j	D ]}| q'qd S r   )
r5   r   rp   r   r<   r   GRAPHr   GRAPHSr   )r   rD   r   )rt  visit_graphrI   rJ   
visit_nodeQ  s   


z*_attribute_param_types.<locals>.visit_noder   onnx.GraphProtoc                   s   | j D ]} | qd S r   rW  )r   r   )r  rI   rJ   r  [  s   

z+_attribute_param_types.<locals>.visit_graphN)r   r   r,   r   )r   r  r,   r   rW  )rn  r   rI   )rt  r  r  rJ   rw  K  s   


rw  Fr   r   r   r   r  r  r   r   r   r   c                C  sR   t | tr
t| } t | ttfstdt| dt||||d}|	| |S )a  Exports an ONNX model to the *python* syntax.

    Args:
        model_onnx: string or ONNX graph
        rename: rename the names to get shorter names
        function_name: main function name
        use_operators: use Python operators.
        inline_const: replace ONNX constants inline if compact
        skip_initializers: generated script will not include initializers.
          Instead, a function that generates the model, given initializer values, is generated,
          along with one that generates random values for the initializers.

    Returns:
        python code
    The following example shows what a python code creating a graph
    implementing the KMeans would look like.
    .. runpython::
        :showcode:
        :process:
        import numpy as np
        from sklearn.cluster import KMeans
        from mlprodict.onnx_conv import to_onnx
        from mlprodict.onnx_tools.onnx_export import export2python
        X = np.arange(20).reshape(10, 2).astype(np.float32)
        tr = KMeans(n_clusters=2)
        tr.fit(X)
        onx = to_onnx(tr, X, target_opset=14)
        code = export2python(onx)
        print(code)
    z&The function expects a ModelProto not r   r  )
r[   r@   r<   loadr   r   r   rp   r   r  )
model_onnxr  r   r   r   r   exporterrI   rI   rJ   export2pythond  s   
'
r  )rL   rM   r,   r@   )r~   r   r,   r@   )rD   r   r,   r   )rD   r   )r   r   r   r   r,   r   )r   r   r   r   r,   r   )r   r   r   r   r,   r   )r   r   r,   r   )r   r   r   r   r,   r   )r   r   r4   r@   r,   r   )rL   r@   r   r   r,   r   )r   r   r,   r   )rn  ro  r,   r  r   )
r  r  r   r   r   r   r   r   r   r   ))
__future__r   typingr   r   r   numpyr  r<   r   r   r   r	   r
   onnxscript.onnx_typesri   onnxscript._internalr   r   r   r\   rK   r`   rg   rm   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   rw  r  rI   rI   rI   rJ   <module>   sP   '

	
	


	






	    
G