
    Si^                        S SK Jr  S SKJr  S SKJr  S SKrS SKrS SK	rS SK
JrJrJrJrJrJr  S SKJr  S SKJr   " S S	5      rg)
    )annotations)BytesIO)AnyN)FunctionProto
GraphProto
ModelProto	NodeProtoTensorProto	TypeProto)op_run)optimized_operatorsc                  $   \ rS rSrSr     S             SS jjrSS jrSS jrSS jr\	S 5       r
\	S	 5       r\	S
 5       r\	S 5       r\	S 5       r\	S 5       rSS jrSSS jjrSS jr S     SS jjr  S       S S jjrSrg)!ReferenceEvaluator   a  Computes the outputs of an ONNX proto (`ModelProto`, `FunctionProto`, `GraphProto`, `NodeProto`).

This is a pure python implementation of ONNX specifications.
Mismatches may remain between the official specifications and the implementation here.
In the case of such a mismatch, the official spec overrides this implementation.

Args:
    proto: :class:`onnx.ModelProto`, :class:`onnx.GraphProto`,
        :class:`onnx.FunctionProto`, :class:`onnx.NodeProto`,
        filename or bytes
    verbose: display intermediate results on the standard output
        during the execution
    opsets: if *proto* is an instance of *GraphProto*, opsets must
        be defined by a dictionary of
    functions: known onnx functions
    new_ops: this runtime can be used to test the implementations of
        new operators, *new_ops* is a list of classes derived from
        :class:`OpRun <onnx.reference.op_run.OpRun>`, every class
        must define the static attribute `domain`, there may be
        multiple implementations for the same operator, the first
        one in the list is used.
    optimized: some operators have two implementations, a naive one
        corresponding to definition of the mathematical definition
        of the operator, another one more efficient. This is the
        case for operator Conv. The naive version is ten times
        slower than the optimized one using a decomposition into
        *Conv = im2col + Gemm*. If True, all optimized kernels are
        added in `new_ops` and are used instead of the inner
        implementation if list *new_ops* does not already contain
        one.

The class maps every node to its associated implementation.
When a subgraph of a function is met,
it uses this class to execute the subgraph or the function.
Next example shows how to run `ReferenceEvaluator` with an onnx model
stored in file `model.onnx`.

::

    import numpy as np
    from onnx.reference import ReferenceEvaluator

    X = np.array(...)
    sess = ReferenceEvaluator("model.onnx")
    results = sess.run(None, {"X": X})
    print(results[0])  # display the first result

Parameter *verbose* may be used to show intermediate results.

::

    import numpy as np
    from onnx.reference import ReferenceEvaluator

    X = np.array(...)
    sess = ReferenceEvaluator("model.onnx", verbose=1)
    results = sess.run(None, {"X": X})
    print(results[0])  # display the first result

The class can use any implementation available in folder
`ops <https://github.com/onnx/onnx/tree/main/onnx/reference/ops>`_.
Adding an implementation requires two changes. The first one is
the implementation itself. Any existing node can be used as a template.
The second is one line in file `_op_list.py
<https://github.com/onnx/onnx/tree/main/onnx/reference/ops/_op_list.py>`_
to import the file and let the reference evaluator know it exists.

This class can also be used to test an implementation of
a custom operator. Let's assume this new operator
is `InvAlpha` from domain `custom`. The implementation
must take place in a class inheriting from
:class:`OpRun <onnx.reference.op_run.OpRun>`.
It must also define attribute `op_domain`.
Here is an example which computes :math:`\\frac{1}{X + \\alpha}`.

.. exec_code::

    from onnx.reference.op_run import OpRun

    class InvAlpha(OpRun):

        op_domain = "custom"

        def _run(self, x, alpha=None):
            # None must be the default value, it is automatically
            # replaced by class OpRun with either the default value
            # specified in the NodeProto or an attribute value defined
            # in a `FunctionProto`.
            return (1 / (x + alpha),)

`alpha` is an attribute. It can be defined by the onnx node or
be defined by the function using this node. It is safe to assume
that attributes are known at the same time as the input.
Class `ReferenceEvaluator` must know about this new implementation
and this can be done by specified argument *new_ops*.

::

    sess = ReferenceEvaluator(onnx_model, new_ops=[InvAlpha])
    got = sess.run(None, {"X": x})[0]

A specific node can be simply evaluated.

.. exec_code::

    import numpy as np
    from onnx.reference.ops._op_list import Celu

    x = np.array([[0, 1], [-1, 2]], dtype=np.float32)
    y = Celu.eval(x, alpha=0.5)
    print(y)

This can also be expressed as:

.. exec_code::

    import numpy as np
    from onnx.reference.ops import load_op

    Celu = load_op("", "Celu")  # domain is ""
    x = np.array([[0, 1], [-1, 2]], dtype=np.float32)
    y = Celu.eval(x, alpha=0.5)
    print(y)

It is possible to overwrite an existing operator.
The class name must be the same. The domain does not have
to be specified for the default domain. However, by default,
class `OpRun` will load the most recent for this operator.
It can be explicitly specified by adding static attribute
`op_schema` of type :class:`OpSchema
<onnx.onnx_cpp2py_export.defs.OpSchema>`.

::

    from onnx.reference.op_run.op_conv import Conv as _Conv

    class Conv(_Conv):

        op_schema = instance_of_OpSchema()

        def _run(self, ...):
            ...

    An operator may be different in a later opset. In that case,
    a new implementation needs to be registered. `Pad_11`, `Pad_18`.
    `Pad_11` is the implementation chose for opset in [11, 17].
    `Pad_18` is selected for any greater opset. Both classes must be
    imported into file `_op_list.py` to register their existence to the
    runtime.

    An operator may have a reference implementation such as `CastLike`
    and still be defined as a function. By default, the reference implementation
    is used. This behavior can be changed by adding a class to the list
    of overwritten operators. It must inherit from :class:`OpRunExpand`.

    ::

        from onnx.reference.op_run import OpRunExpand

        class CastLike(OpRunExpand):
            op_domain = ""

        ref = ReferenceEvaluator(model, new_ops=[CastLike])
        # ...

        This mechanism is used in unit test to check the function
        implementation a schema may define.
Nc           	        U(       aI  Uc  [         R                  " 5       nO0[        U5      n[          H  nX;  d  M
  UR                  U5        M     S U l        S U l        [        U[        R                  R                  5      (       a  Xl
        U R                  R                  nOS U l
        [        U[        5      (       a,  [        US5       n	[        R                  " U	5      nS S S 5        O4[        U[        5      (       a  [        R                  " [!        U5      5      nXl        0 U l        / U l        [        U[(        5      (       aq  UR*                  U l        UR.                   V
s0 s H  oR0                  U
R2                  _M     sn
U l        Ub  [7        S5      eUb  [7        S5      eUR8                  nGO3[        U[:        5      (       a-  Xl        [        U[<        5      (       d  [?        S5      eX l        O[        U[@        5      (       af  S U l        UR.                   V
s0 s H  oR0                  U
R2                  _M     sn
U l        Ub  [7        S5      e[C        URD                  5      U l        Ov[        U[F        5      (       aI  S U l        UR0                  UR0                  S:w  a  SO[        RH                  RK                  5       0U l        O[?        S[M        U5       S	35      eU R,                  (       Ga  U R,                  RN                   Vs/ s H  oRP                  PM     snU l)        U R,                  RN                   Vs/ s H  oRL                  PM     snU l        U R,                  RT                   Vs/ s H  oRP                  PM     snU l+        U R,                  RT                   Vs/ s H  oRL                  PM     snU l        [C        U R,                  RX                  5      [C        U R,                  RZ                  5      -   U l.        U R,                  R^                  U l0        U R,                  RN                   Vs0 s H  oRP                  URL                  _M     nn[c        U R"                  S
5      (       a5  U R"                  Rd                   H  nURL                  XRP                  '   M     Xl3        Oj[C        URN                  5      U l)        [C        URT                  5      U l+        / U l.        [        U[F        5      (       a	  U/U l0        OUR^                  U l0        Ub  U H  n	[        U	[@        5      (       aV  U Ri                  X[C        U R$                  Rk                  5       5      S9U R$                  U	R0                  U	RP                  4'   Mn  [        U	[l        5      (       a2  U	R"                  nXR$                  UR0                  URP                  4'   M  [?        S[M        U	5      < S35      e   X@l7        0 U l8        Ub  U H  n[c        US5      (       d  [s        SU S35      e[u        U[v        Rx                  5      (       d  [?        SU S35      eURz                  UR|                  4nUU Rp                  ;   a  M{  UU Rp                  U'   M     U R                  5         g ! , (       d  f       GN= fs  sn
f s  sn
f s  snf s  snf s  snf s  snf s  snf )Nrbz+opsets must be None if proto is ModelProto.z.functions must be None if proto is ModelProto.z3opsets must be a dictionary if proto is GraphProto.z.opsets must be None if proto is FunctionProto.    zUnexpected type z for proto.
value_info)verbose	functionsz for a function.	op_domainzClass z# must define attribute 'op_domain'.z& must inherit from OpRun (in new_ops).)@r   copysetappendoutput_types_input_types_
isinstanceonnxmodel_containerModelContainer
container_model_protostropenloadbytesr   proto_
functions_attributes_r   graphonnx_graph_opset_importdomainversionopsets_
ValueErrorr   r   dict	TypeErrorr   list	attributer	   defsonnx_opset_versiontypeinputnameinput_names_outputoutput_names_initializersparse_initializerinits_nodenodes_hasattrr   
all_types_	__class__valuesr   r   new_ops_AttributeError
issubclassr   OpRunr   __name___init)selfprotoopsetsr   r   new_ops	optimizedset_new_opsopfdio	all_types
shape_typeonxclkeys                     a/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnx/reference/reference_evaluator.py__init__ReferenceEvaluator.__init__   sd    -224!'l-B,r* . " eT11@@AAJOOOO//E"DOeS!!eT"a		! #"u%%IIgen-EEG&(eZ((${{D9>9K9KL9KAHHaii/9KLDL! !NOO$ !QRRIz**$fd++ UVV!L}--#D9>9K9KL9KAHHaii/9KLDL! !QRR#EOO4Dy))#D<<2%  YY113DL .tE{m;GHH151A1A1G1G H1GA1G HD151A1A1G1G H1GA1G HD262B2B2I2I!J2IQ&&2I!JD262B2B2I2I!J2IQ&&2I!JDt//;;<t  33@ DK **//DK151A1A1G1GH1GA1GIHt{{L11"&++"8"8J1;Ioo. #9'O $U[[ 1D!%ell!3DDK%++$g#jj a//8<d4??;Q;Q;S6T 9G 9DOOAHHaff$45  #566((C<=OOCJJ$89#&6tAwkAQ$RSS  CEr;//( $GH  ""fll33#fRD0V$WXXllBKK/$--'%'c"  	

g #" M M !I H!J!J
 Is6   Z4) [' [[[[7[ [$4
[c                   [         R                  R                  U5      nUR                  nU R                  (       a/  U R                  R                  U5      (       a  U R                  U   $ U R                  b  [        S5      e[        S5      e)z#Returns a tensor saved as external.zPReferenceEvaluator assumes a LargeContainer was loaded with its external tensor.zPAn instance of LargeContainer should be created before using ReferenceEvaluator.)r   external_data_helperExternalDataInfolocationr"   !is_in_memory_external_initializerRuntimeError)rM   r>   inforc   s       r]   retrieve_external_data)ReferenceEvaluator.retrieve_external_data3  s~    ((99+F==??tPP 
  
 ??8,,??&b  ^
 	
    c           
        [        U[        [        [        45      (       a  U$ [        U[        R
                  5      (       Ga  U R                  S:  aj  UR                  S:X  a  UR                   SUR                   S3$ UR                   SUR                   SUR                  5        SUR                  5        S3$ UR                  5       R                  5       n[        U5      S:  aA  US S nUR                   SUR                   SS	R                  [!        [        U5      5       S
3$ UR                   SUR                   SU 3$ [#        US5      (       a%  SR                  [!        U R$                  U5      5      $ U$ )N   r   :z (empty)z in [, ]   ,z...r   )r   r$   intfloatnpndarrayr   sizedtypeshapeminmaxraveltolistlenjoinmaprC   _log_arg)rM   aelementss      r]   r   ReferenceEvaluator._log_argE  s9   a#sE*++Ha$$||a66Q;ggYay99''!AGG9E!%%'"QUUWIQGGwwy'')H8}q #BQ<''!AGG9Achhs37I.J-K3OOggYay(441h99S233ri   c                    XR                   :  a8  U Vs/ s H  o@R                  U5      PM     nn[        U[        U5      -  5        g g s  snf N)r   r   printtuple)rM   levelpatternargsr   new_argss         r]   _logReferenceEvaluator._logV  s@    <<267$Qa($H7'E(O+,  7s   A	c                    U R                   $ )zReturns the input names.)r;   rM   s    r]   input_namesReferenceEvaluator.input_names[          ri   c                    U R                   $ )z)Returns the input types if any specified.)r   r   s    r]   input_typesReferenceEvaluator.input_types`  r   ri   c                    U R                   $ )zReturns the output names.)r=   r   s    r]   output_namesReferenceEvaluator.output_namese       !!!ri   c                    U R                   $ )zReturns the output types.)r   r   s    r]   output_typesReferenceEvaluator.output_typesj  r   ri   c                    U R                   $ )zReturns the opsets.)r0   r   s    r]   rO   ReferenceEvaluator.opsetso  s     ||ri   c                :    [        S U R                   5       5      $ )zkChecks if the graph has a linked attribute (= an attribute whose value is defined
by a function attribute.
c              3  8   #    U  H  oR                   v   M     g 7fr   )has_linked_attribute).0rA   s     r]   	<genexpr>:ReferenceEvaluator.has_linked_attribute.<locals>.<genexpr>y  s     H,,s   )any	rt_nodes_r   s    r]   r   'ReferenceEvaluator.has_linked_attributet  s    
 HHHHri   c                    U R                   R                   SSR                  U R                  5       SSR                  U R                  5       3$ )N(rm   z) -> )rE   rK   r}   r   r   r   s    r]   __str__ReferenceEvaluator.__str__{  sE    ..))*!DIId6F6F,G+HdiiX\XiXiNjMkllri   c                    U R                   c  [        SU< S35      eXR                   ;  a.  U(       a&  [        SU< S[        U R                   5       S35      eg U R                   U   $ )NzUnable to return type for name z. Run shape_inference first.z, it was not found in .)rD   re   sorted)rM   r:   excs      r]   get_result_types#ReferenceEvaluator.get_result_types~  sx    ??"1$9UV  &"5dX=STZ[_[j[jTkSllmn  t$$ri   c                l  ^  0 T l         / T l        T R                   Hn  n[        R                  R                  U5      (       a  T R                  U5      O[        R                  R                  U5      T R                   UR                  '   Mp     U 4S jT R                  T R                  T R                  T R                  R                  5       T R                  S.nT R                   (       a  T R"                  R$                   Vs0 s H  o3R                  UR&                  _M     nn[)        T R*                  S5      (       a5  T R*                  R,                   H  nUR&                  XER                  '   M     UT l        OST l        T R0                   H9  n T R3                  U5      n U" Xb5      n
T R                  RA                  U
5        M;     gs  snf ! [4        R6                   a  nT R.                  (       aX  UR$                   Vs/ s H  nT R9                  USS9PM     Os  snf n	nSU	;   a  T S.S jn SnANT R3                  Xi5      n SnAN[4        R6                  " S	UR:                  < S
UR<                  < S35      UeSnAff = f! [>         a  n[?        SU< SU SU S35      UeSnAff = f)z5Loads the implementation for every node in the graph.c                ,   > TR                   " SU /UQ76 $ )N
   )r   )r   r   rM   s     r]   <lambda>*ReferenceEvaluator._init.<locals>.<lambda>  s    $))B*G$*Gri   )logrO   r   rP   existing_functionsevaluator_clsr   NF)r   )parentc                .    [         R                  " USU 06$ )Nr   )r   OpFunctionContextDependant)r   r   s     r]   r[   $ReferenceEvaluator._init.<locals>.cl  s     #)#D#D!%$.4$ ri   z*No implementation was found for node type  from domain z~. If this node has a context dependent implementation, you should run function infer_shapes before calling ReferenceEvaluator.zUnable to instantiate class z with run_params=z
 and node=r   )!	rt_inits_r   r@   r   ra   uses_external_datarg   numpy_helperto_arrayr:   rO   r   rG   r)   r   rE   r   r,   r9   r8   rC   r(   r   rD   rB   
_load_implr   RuntimeContextErrorr   op_typer.   r3   r   )rM   init
run_paramsrV   rX   rY   rA   r[   eitinsts   `          r]   rL   ReferenceEvaluator._init  s[   KKD ,,??EE ++D1&&//5 NN499%   Hkk||}}"&//"6"6"8!^^

 151A1A1G1GH1GA1GIHt{{L11"&++"8"8J1;Ioo. #9'DO"DOKKD__T*($+ NN!!$';   I --  ??GKzzRz!$//u/=zRBRrz-1  
 "__T6 44DT\\DTTabfbmbmap q= > 	*  22& 9"",ZvQ@ sN    GG'JJ
(JH"!J;J4JJ

J3J..J3c                >   UR                   U R                  ;  a6  [        SUR                   < SUR                  < SU R                  < S35      eU R                  UR                      nUR                   UR                  4nSnX@R                  ;   a2  U R                  U   n[        U[        R                  5      (       d  U$ SnUR                   S:X  a/  SS	KJ	n   U" UR                   UR                  UUU R                  S
9$ U(       a&  [        SUR                    SUR                   S35      eUR                   S:X  a$  SS	KJ	n  U" UR                   UR                  U5      $ UR                   S:X  a$  SS	KJ	n	  U	" UR                   UR                  U5      $ UR                   S:X  a$  SS	KJ	n
  U
" UR                   UR                  U5      $ X@R                   ;   a=  SS	KJ	n  U R                   U   nU" UR                   UR                  UUU R                  S9$ [        SUR                  < SUR                   < S[#        U R                   5       S35      e! [        R                   a1    Uc  e U" UR                   UR                  UUUUU R                  S9s $ f = f)z1Loads the implementation for a specified runtime.zDomain z (node type: z") is not specified. Known opsets: r   FTr   r   )load_op)expandr   )rA   r   r   r   zkExpanding an operator with its function definition is only implemented for the main opset. Remove operator rp   z# from the list of inlined operator.zai.onnx.preview.trainingexperimentalz
ai.onnx.ml)customr   z
Node type r   z is unknown, known functions: )r.   rO   re   r   rG   rI   r   OpRunExpandonnx.reference.opsr   rE   r   NotImplementedError*onnx.reference.ops.aionnx_preview_trainingonnx.reference.ops.experimentalonnx.reference.ops.aionnxmlr)   r   )rM   rA   r   r/   r\   r   r[   r   
load_op_ptload_op_exp
load_op_mlimpls               r]   r   ReferenceEvaluator._load_impl  sw    ;;dkk)$++dll5E F337;;/D  ++dkk*kk4<<'-- s#Bb&"4"455	F;;"2KKLL!"&.. ( %K;;-q.QS 
 ;;44 dkk4<<AA;;.( t{{DLL'BB;;,& dkk4<<AA //!2??3'D"nn  "(dkk_ E,,24??,C+DAG
 	
i -- &KKLL +!"&.. s   'I AJJc                   Uc  U R                   n[        U R                  [        5      (       a  Uc
  [	        5       eSS0nUR                  U R                  5        UR                  U5        U R                  R                  5        H  u  pgU R                  SSXg5        M     UR                  5        H  u  pgU R                  SSXg5        M     U R                   GH:  nU R                  SSUR                  UR                  UR                  5        UR                   HF  n	X;  d  M
  [        SU	< S	[        U5       S
[        U R                  5       S[        U5       S3	5      e   UR                   V	s/ s H  oU	   PM	     n
n	0 nUR                  (       a  U(       a  X;S'   UR!                  5       (       a  UR"                  " U
SU0UD6nOUR"                  " U
0 UD6n[%        UR                  USS9 H  u  pU R                  SSX5        XU'   M     GM=     U(       a  U$ U H0  nX;  d  M
  [        SU< S[        U5       SU R                   35      e   U Vs/ s H  oU   PM	     sn$ s  sn	f s  snf )a  Executes the onnx model.

Args:
    output_names: requested outputs by names, None for all
    feed_inputs: dictionary `{ input name: input value }`
    attributes: attributes value if the instance runs a
        FunctionProto
    intermediate: if True, the function returns all the results,
        final ones and intermediates one in a same dictionary,
        if False, only the final results are returned in a list

Returns:
    list of requested outputs if intermediate is False,
    named results in a dictionary otherwise
Nr      z
 +C %s: %sz
 +I %s: %sr   z%s(%s) -> %szUnable to find input z in known results z, self.rt_inits_ has z, feed_inputs has r   linked_attributescontextF)strictz	 + %s: %szUnable to find output name z in z, proto is
)r   r   r(   r   r3   updater   itemsr   r   r   r9   r<   re   r   r   need_contextrunzip)rM   r   feed_inputs
attributesintermediateresultskvrA   rV   inputsr   outputsr:   values                  r]   r   ReferenceEvaluator.run  sJ   , ,,Ldkk=11j6H+ t*t~~&{#NN((*DAIIaq, +%%'DAIIaq, ( NNDIIatzz4;;OZZ#&/u4FvgFW X..4T^^.D-E F++1++>*?qB    +/**5*Qaj*F5 "((Z9C"56  ""((FQGQ?PQ((F@.?@"4;;F		![$6 %  G# #, N D""1$fWo=Nl[_[f[fZgh  !
 +77,$,77+ 6* 8s   5I-I2)rD   r*   r"   r)   r@   r;   r   rG   rB   r,   r0   r=   r   r(   r   r   r   )NNr   NT)rN   r   rO   zdict[str, int] | Noner   z/list[ReferenceEvaluator | FunctionProto] | Noner   rq   rP   zlist[type[op_run.OpRun]] | NonerQ   boolreturnNone)r>   r
   r   z
np.ndarray)r   r   r   r   )r   rq   r   r$   r   z	list[Any]r   r   )r   r$   )T)r:   r$   r   r   r   r   )r   r   r   )rA   r	   r   zTypeProto | Noner   r   )NF)r   zdict[str, Any]r   zdict[str, Any] | Noner   r   r   zdict[str, Any] | list[Any])rK   
__module____qualname____firstlineno____doc__r^   rg   r   r   propertyr   r   r   r   rO   r   r   r   rL   r   r   __static_attributes__ ri   r]   r   r      sp   gX )-EI37nn &n C	n
 n 1n n 
n`
$"-
 ! ! ! ! " " " "   I Im%8(v @DX
X
,<X
	X
| -1"C8 $C8 *	C8
 C8 
$C8 C8ri   r   )
__future__r   ior   typingr   numpyrs   r   onnx.model_containeronnx.onnx_pbr   r   r   r	   r
   r   onnx.referencer   onnx.reference.ops_optimizedr   r   r   ri   r]   <module>r     s7    #       " <I	8 I	8ri   