
    Ph'                     B   d dl Z d dlmZ d dlmZmZmZmZ d dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmc mZ d dlZ edd      Z edd      Z  e jB                  e"      Z#de$de%fdZ&dee$ee$e$f   f   fdZ' G d d      Z(y)    N)defaultdict)TupleDictOptionalList)export)_ExportPassBase)NodeMetadata)
ProxyValue)
FakeTensor)TargetArgument)Library)tree_unflattenatenFRAGMENTIMPLversioned_upgrader_namereturnc                     t        j                  d|       st        d|  d      t        | j	                  d      d         dz   S )zdiv_Scalar_0_3 is the name of the upgrader, meaning it applies to div.Scalar of version 0 to 3 and is
    upgrading to version 4.z^.*_[0-9]+_[0-9]+$zUpgrader name z is invalid_   )rematchRuntimeErrorintsplit)r   s    fC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\torch/_export/serde/upgrade.pyget_target_versionr       sK     88(*AB^,C+DKPQQ&,,S1"56::    c                  ~   t         j                  j                         } t         j                  j                         }t	        t
              }|j                         D ]^  \  }}|st        d|       |d   }|j                  }|j                  }| j                  |d      }|st        d| d|       ||f||<   ` |S )zRGetting upgraders entry map and operator version map and merge them into one dict.z-Op version map has an empty entry for opname r   NzCan't find upgrader for op z and upgrader name )torch_C_get_upgraders_entry_map_get_operator_version_mapr   tupleitemsr   
old_schemaupgrader_nameget)		upgradersop_version_mapoutputopname
entry_listentryr)   r*   upgrader_strs	            r   get_upgradersr3       s    113IXX779N)4U);F,224
!NvhWXX1%%
++ }}]D9!<VHDWXeWfghh!+\ :} 5 Mr!   c                       e Zd ZdZ G d de      Z	 	 	 ddeeee	f      deeee	f      deeee
eef   f      fdZddeeee
eef   f      d	ee
eef      fd
Zedee
eef      d	ee   fd       Zdej"                  d	ej"                  fdZy)GraphModuleOpUpgradera  This upgrader is able to upgrade the old version of ops in a given GraphModule, if all upgraders are available.
    To use it, retrieve upgraders from somewhere (TorchScript API or new API) and pass it into this upgrader. In
    __init__() it does the following:
    1. parse the upgrader list and reorder for upgrading purpose.
    2. register old versions of operators as custom ops.
    3. prepare upgrader passes.

    In `upgrade()` API run these upgrader passes.

    An example of op_upgraders input:
    {
        "aten::div__Scalar_0_3": (                              # versioned op name
            "div._Scalar(self: Tensor, other: Scalar)",         # old schema
            '''
            def div__Scalar_0_3(self: torch.Tensor, other) -> torch.Tensor:     # upgrader in literal string
              if (self.is_floating_point() or isinstance(other, float)):
                return self.true_divide_(other)
              return self.divide_(other, rounding_mode='trunc')
            ''',
        ),
    },

    Note that we require the upgrader function to be runnable in Python (which is a stricter requirement than the
    original TorchScript upgrader).
    c                   X     e Zd Zdedef fdZdeedf   deeef   de	de
f fd	Z xZS )
"GraphModuleOpUpgrader.UpgraderPass
old_target
new_targetc                 >    t         |           || _        || _        y N)super__init__r8   r9   )selfr8   r9   	__class__s      r   r=   z+GraphModuleOpUpgrader.UpgraderPass.__init__N   s    G(DO(DOr!   args.kwargsmetar   c                 ~    || j                   k(  rt        | 	  | j                  |||      S t        | 	  ||||      S r;   )r8   r<   call_operatorr9   )r>   opr@   rA   rB   r?   s        r   rD   z0GraphModuleOpUpgrader.UpgraderPass.call_operatorS   sA     T__$w,T__dFDQQ7(T64@@r!   )__name__
__module____qualname__r   r=   r   r   r   strr
   r   rD   __classcell__)r?   s   @r   UpgraderPassr7   M   s`    	)v 	)6 	)
		A HcM*		A S(]+			A
 #		A 		A 		Ar!   rK   Ncompiler_opset_versionmodel_opset_versionop_upgradersc                     |s
t               n|| _        |r|ni | _        |r|ni | _        t        j                  | j                  | j                              | _        y r;   )r3   rN   rL   rM   r5   _populate_passes_parse_upgradersupgrader_passes)r>   rL   rM   rN   s       r   r=   zGraphModuleOpUpgrader.__init__^   sY     P\am@V&<\^#:M#6SU I^IoIo!!$"3"34J6r!   r   c                    d}|r|| j                   vs|| j                  vrg S | j                   |   }| j                  |   }|j                         D ci c]  \  }}t        |      | }}}g }t	        |dz   |dz         D ]4  }	|	|v r|j                  ||	          t        j                  dd|	i       6 |S c c}}w )zReorder op_upgraders by version number, return an ordered list of tuples, containing old op schema as well
        as the upgrader function string literal.r   r   z0Missing an upgrader to upgrade to version {ver}.ver)extra)rM   rL   r(   r    rangeappendlogwarning)
r>   rN   op_namespace	model_vercurr_vernamevversioned_upgraderstarget_upgradersrT   s
             r   rQ   z&GraphModuleOpUpgrader._parse_upgradersj   s     |43K3KK|cgc~c~O~I,,\:	..|< <H;M;M;O;Q;O \c[_ab;Md;SUV;V;O 	 ;Q24Q15C)) ''(;C(@A NW\^aVbc 6  ;Qs   B:r,   c                    g }dt         dt         dt         fd}| D ]  \  }}|j                  d      d   j                  d      d   }|j                  d      d   j                  d	      d   }|j                  ||      }	  ||||
       t        t        j                  j                  |      j                  }d|vr|dfnt        |j                  d      dd       \  }}	t        t        t        j                  j                  |      |	      }
|j                  t        j                  |
|              |S # t        $ r.}dt        |      v rt	        d| d       nt        |Y d}~d}~ww xY w)a  Given a list of upgraders, loop through it from lower version to higher version and create passes for all
        upgraders. se torch.Library API to register old ops. Op name will be
        <name>_<valid_from_ver>_<valid_till_ver>. Register upgraders as CompositeImplicitAutograd kernels. For example:

        lib = Library("aten", "FRAGMENT")
        lib.define(old_schema)

        impl_lib = Library("aten", "IMPL")
        impl_lib.impl("div__Scalar_0_3", div__Scalar_0_3, "CompositeImplicitAutograd")

        @:var upgraders: a list of tuples. The first element of the tuple is the old schema and the second is the
        upgrader function literal text.
        @:return upgrader passes, order matters
        r]   schemaimpl_strc                     t         j                  |       	 t        |       t
        j                  | t               |    d       y# t        $ r}t	        d|       |d}~ww xY w)zARegisters an old version operator using impl_name as old op name.zInvalid upgrader string: NCompositeImplicitAutograd)libdefineexec	Exceptionr   impl_libimpllocals)r]   rb   rc   es       r   register_old_opz?GraphModuleOpUpgrader._populate_passes.<locals>.register_old_op   s^    JJvRX MM$0KL  R"%>xj#IJPQQRs   A 	A"AA"(r    r   z::)r]   rb   rc   z3with the same name and overload name multiple timeszRegistering z multiple timesN.default   )r8   r9   )rI   r   replacer   printgetattrr#   opsr   rr   r'   rW   r5   rK   )r,   rR   rn   rb   r2   r*   op_namerm   old_op_targetoverload_namenew_op_targets              r   rP   z&GraphModuleOpUpgrader._populate_passes   sx   " 	M# 	Ms 	Mc 	M '0"V\(..s3A6<<SA"EMll3'*006r:G^^G];F.]6LY $EIINNMBJJM >A=Ogy%9UZ[b[h[hil[mnpop[qUr"G]#GEIINNG$DmTM""%22mXe2fh# '0(    .HCPQFRLGH&A- I.s   D;;	E2$E--E2exported_programc           	      |   | j                   s|S |j                  j                  D cg c].  }|j                  dk(  s|j                  j                  dd      0 }}|D cg c]L  }t        |t              r8t        j                  t        |j                               |j                        n|N }}|j                  j                  J t        ||j                  j                        \  }}|i k(  sJ | j                   D ].  }|j!                  |      }t#        |j%                         ||      }0 |S c c}w c c}w )a  Run each upgrader pass and then retrace to decompose it. Each upgrader pass replaces the old version of
        operators with a custom operator. The custom operator contains a CompositeImplicitAutograd kernel (the
        upgrading function itself). After retrace, this custom operator will be decomposed into the ops used in the
        upgrader. After all passes are applied, the exported program will be upgraded to the target version.placeholdervalN)dtype)rR   graphnodesrE   rB   r+   
isinstancer   r#   onesr'   sizer   	call_specin_specr   
_transformr   module)	r>   r|   nr@   argargs_real_tensorsrA   _passupgraded_programs	            r   upgradezGraphModuleOpUpgrader.upgrade   s/   
 ####1A1G1G1M1Mg1MAQRQUQUYfQf

5$'1Mg$(*$(S PZZ]_iOjUZZchhj(9Kpss$( 	 *))11===%&79I9S9S9[9[\f||))E/::5A%&6&=&=&?vN *
   h*s   D4D4 AD9)NNNr;   )rF   rG   rH   __doc__r	   rK   r   r   rI   r   r   r=   r   rQ   staticmethodrP   epExportedProgramr    r!   r   r5   r5   2   s   4A A& @D<@AE	
6$,T#s(^$<
6 "*$sCx.!9
6 #4U38_(<#=>	
6 Xd3c3h;O6P-Q  ]abghkmphpbq]r  2 /DsCx$9 /d<>P / /b (:(:  r?Q?Q  r!   r5   ))loggingcollectionsr   typingr   r   r   r   r#   torch._exportr   torch._export.pass_baser	   &torch._export.pass_infra.node_metadatar
   $torch._export.pass_infra.proxy_valuer   torch._subclassesr   torch.fx.noder   r   torch.libraryr   torch.utils._pytreer   torch._export.exported_program_exportr|   r   r   rf   rj   	getLoggerrF   rX   rI   r   r    r3   r5   r   r!   r   <module>r      s     # . .    3 ? ; ( * ! . + + 	fj!66"g!; ; ;tCsCx01 $W  W r!   