+
    G-jµ  ã                   ó†   € ^ RI Ht ^ RIHt ^ RIHt ^ RIHtHtH	t	 ^ RI
Ht ]! ]4      t ! R R]4      t ! R R	]4      tR
# )é    )Ú	getLogger)ÚFusion)ÚFusionUtils)Ú	NodeProtoÚTensorProtoÚhelper©Ú	OnnxModelc                   óP   a a€ ] tR t^t oV3R lV 3R lltV3R lR ltRtVtV ;t# )ÚFusionTransposec                ó    <€ V ^8„  d   QhRS[ /# ©é   Úmodelr	   )ÚformatÚ__classdict__s   "€Úz/Volumes/fast/ai/experiments/nudenet-smoke/.venv/lib/python3.14/site-packages/onnxruntime/transformers/fusion_transpose.pyÚ__annotate__ÚFusionTranspose.__annotate__   s   ø€ ÷ :ñ :™iñ :ó    c                ó*   <€ \         SV `  VR R 4       R# )Ú	TransposeN©ÚsuperÚ__init__©Úselfr   Ú	__class__s   &&€r   r   ÚFusionTranspose.__init__   s   ø€ Ü‰Ñ˜ ¨[Ö9r   c                óh   <€ V ^8„  d   QhRS[ RS[S[S[S[ ,          3,          RS[S[S[ 3,          /# )r   Útranspose_nodeÚinput_name_to_nodesÚoutput_name_to_node©r   ÚdictÚstrÚlist)r   r   s   "€r   r   r      sJ   ø€ ÷ AZñ AZá!ðAZñ "¡#¡t©I¥Ð"6Õ7ðAZñ "¡#¡y .Õ1ñ	AZr   c                óx  € TpVP                   ^ ,          V9  d   R# W4P                   ^ ,          ,          pVP                  R8w  d   RpMjTpV P                  P                  Wb4      pV'       d   \	        V4      ^8”  d   R# VP                   ^ ,          V9  d   R# W6P                   ^ ,          ,          pVP                  R8w  d   R# \
        P                  ! VR4      p\        V\        4      '       g   Q h\
        P                  ! VR4      p	\        V	\        4      '       g   Q h\	        V	4      \	        V4      8X  g   Q h. p
\        V4       F  w  r¼V
P                  Wœ,          4       K  	  VfE   \        P                  ! V P                  WEV4      '       d   V P                  P                  V4       MC\        P                  ! V P                  WeV4      '       d   V P                  P                  V4       VP                  R4       VP                  P!                  \"        P$                  ! RV
4      .4       R# )a‹  
Note that onnxruntime will do comprehensive transpose optimization after loading model.
The purpose of this fusion is to make graph clean before running onnxruntime.

Case 1:
      (input)-->Transpose(perm=a)-->Transpose(perm=b)-->
After:
      (input)-->Transpose(perm=a)-->  (this path can be removed if the output is not used anymore)
        |
        +----->Transpose(perm=a*b)-->

Case 2 (Cast has only one child):
      (input)-->Transpose(perm=a)--> Cast -->Transpose(perm=b)-->
After:
      (input)-->Transpose(perm=a)-->  (this path can be removed if the output is not used anymore)
        |
        +----->Cast --> Transpose(perm=a*b)-->
NÚCastr   ÚpermÚ	attribute)ÚinputÚop_typer   Úget_childrenÚlenr
   Úget_node_attributeÚ
isinstancer'   Ú	enumerateÚappendr   Úskip_parentÚnodes_to_removeÚ
ClearFieldr+   Úextendr   Úmake_attribute)r   r!   r"   r#   Útranspose_bÚtranspose_aÚ	cast_nodeÚcast_childrenÚpermutationÚparent_permutationÚoutput_permutationÚ_jÚindexs   &&&&         r   ÚfuseÚFusionTranspose.fuse   sÎ  € ð0 %ˆØ×Ñ˜QÕÐ':Ô:Ùà)×*;Ñ*;¸AÕ*>Õ?ˆØ×Ñ &Ô(Ø‰Ià#ˆIà ŸJ™J×3Ñ3°IÓSˆMß¤ ]Ó!3°aÔ!7Ùà�‰˜qÕ!Ð)<Ô<Ùà-¯o©o¸aÕ.@ÕAˆKà×Ñ +Ô-Ùä×2Ò2°;ÀÓGˆÜ˜+¤t×,Ò,Ð,Ð,ä&×9Ò9¸+ÀvÓNÐÜÐ,¬d×3Ò3Ð3Ð3äÐ%Ó&¬#¨kÓ*:Ô:Ð:Ð:àÐÜ" ;Ö/‰IˆBØ×%Ñ%Ð&8Õ&?Ö@ñ 0ð ÒÜ×&Ò& t§z¡z°;ÐM`×aÒaØ×$Ñ$×+Ñ+¨KÔ8øä×&Ò& t§z¡z°9ÐK^×_Ò_Ø×$Ñ$×+Ñ+¨KÔ8Ø×Ñ˜{Ô+Ø×Ñ×$Ñ$¤f×&;Ò&;¸FÐDVÓ&WÐ%XÖYr   © )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   rB   Ú__static_attributes__Ú__classdictcell__Ú__classcell__©r   r   s   @@r   r   r      s$   ù‡ € ÷:ó :÷AZ÷ AZð AZr   r   c                   óf   a a€ ] tR t^Xt oV3R lV 3R lltRV3R lR lltV3R lR ltRtVtV ;t	# )	ÚFusionInsertTransposec                ó    <€ V ^8„  d   QhRS[ /# r   r	   )r   r   s   "€r   r   Ú"FusionInsertTranspose.__annotate__Y   s   ø€ ÷ 1ñ 1™iñ 1r   c                ó*   <€ \         SV `  VR R4       R# )Ú Ú	GroupNormNr   r   s   &&€r   r   ÚFusionInsertTranspose.__init__Y   s   ø€ Ü‰Ñ˜  KÖ0r   c                ó6   <€ V ^8„  d   QhRS[ RS[S[,          /# )r   Ú
input_namer*   )r&   r'   Úint)r   r   s   "€r   r   rP   \   s   ø€ ÷ ñ ±ð ¹4Á½9ñ r   c                ó  € V P                   P                  R4      pVf   VR,           R,           V,           p\        P                  ! RV.V.VR7      pVP                  P                  \        P                  ! RV4      .4       V# )z&Append a Transpose node after an inputr   Ú_outÚ-)ÚinputsÚoutputsÚnamer*   )r   Úcreate_node_namer   Ú	make_noder+   r7   r8   )r   rV   r*   Úoutput_nameÚ	node_namer!   s   &&&&  r   Úcreate_transpose_nodeÚ+FusionInsertTranspose.create_transpose_node\   sw   € à—J‘J×/Ñ/°Ó<ˆ	ØÒØ# fÕ,¨sÕ2°ZÕ?ˆKÜ×)Ò)¨+¸z¸lÐU`ÐTaÐhqÔrˆØ× Ñ ×'Ñ'¬×)>Ò)>¸vÀtÓ)LÐ(MÔNØÐr   c                óh   <€ V ^8„  d   QhRS[ RS[S[S[S[ ,          3,          RS[S[S[ 3,          /# )r   Úgroup_norm_noder"   r#   r$   )r   r   s   "€r   r   rP   e   sE   ø€ ÷ B2ñ B2á"ðB2ñ "¡#¡t©I¥Ð"6Õ7ðB2ñ "¡#¡y .Õ1ñ	B2r   c                ó  € V P                   P                  V. R
O. RO4      pVf   R# Vw  rVrxp	V P                   P                  VP                  ^ ,          4      '       d   R# \        P
                  ! VR4      p
\        V
\        4      '       g   Q hV
. RO8w  d   R# \        VP                  4      ^8X  dø   V P                   P                  VP                  ^,          4      ^8X  dÇ   \        VP                  4      ^8X  d­   V P                   P                  VP                  ^,          4      ^8X  d|   \        V P                   P                  W’4      4      ^8X  dS   \        V P                   P                  Wr4      4      ^8X  d*   \        V P                   P                  W‚4      4      ^8X  g   R# RpV P                   P                  V4      f'   V P                  V\        P                  ^.^.RR7       RpV P                   P                  V4      f'   V P                  V\        P                  ^.^.RR7       RVP                  ^&   RVP                  ^&   V P                   P!                  R4      R,           pV P                   P#                  VP                  ^ ,          V4       V P%                  VP                  ^ ,          . ROV4      pV P                   P'                  WàP(                  4       V P+                  R	4       R# )aÓ  
This optimization will insert an Transpose, and onnxruntime transpose optimizer will remove it together with
another Transpose so that we can get effect of reducing one Transpose after onnxruntime optimization.
Before:
    --> Gemm --> Unsqueeze(axes=[2]) --> Unsqueeze(axes=[3]) --> Add --> Transpose([0,2,3,1]) --> GroupNorm
After:
    --> Gemm --> Unsqueeze(axes=[1]) --> Unsqueeze(axes=[2]) -->Transpose([0,3,1,2]) --> Add --> Transpose([0,2,3,1]) --> GroupNorm
r   Nr*   Úort_const_unsqueeze_axes_1F)r]   Ú	data_typeÚdimsÚvalsÚrawÚort_const_unsqueeze_axes_2Ú_NCHWzInsert Transpose)r   ÚAddÚ	Unsqueezero   ÚGemm)r   r   Nr   r   )r   r   é   é   )r   rq   rr   r   )r   Úmatch_parent_pathÚfind_graph_outputÚoutputr
   r0   r1   r'   r/   r,   Úget_constant_valuer.   Úget_initializerÚadd_initializerr   ÚINT64r^   Úreplace_input_of_all_nodesrb   Úadd_nodeÚthis_graph_nameÚincrease_counter)r   re   r"   r#   Ú	gemm_pathÚ	transposeÚaddÚunsqueeze_3Úunsqueeze_2Úgemmr=   Úaxes_1Úaxes_2Útranspose_output_nameÚnew_transposes   &&&&           r   rB   ÚFusionInsertTranspose.fusee   sƒ  € ð —J‘J×0Ñ0ØÒSÒUgó
ˆ	ð ÒÙØ9BÑ6ˆ	˜°$Ø�:‰:×'Ñ'¨×(:Ñ(:¸1Õ(=×>Ò>Ùä×2Ò2°9¸fÓEˆÜ˜+¤t×,Ò,Ð,Ð,Øš,Ô&Ùô �×!Ñ!Ó" aÔ'Ø—
‘
×-Ñ-¨k×.?Ñ.?ÀÕ.BÓCÀqÔHÜ�K×%Ñ%Ó&¨!Ô+Ø—
‘
×-Ñ-¨k×.?Ñ.?ÀÕ.BÓCÀqÔHÜ�D—J‘J×+Ñ+¨DÓFÓGÈ1ÔLÜ�D—J‘J×+Ñ+¨KÓMÓNÐRSÔSÜ�D—J‘J×+Ñ+¨KÓMÓNÐRSÔSáð .ˆØ�:‰:×%Ñ% fÓ-Ò5Ø× Ñ ØÜ%×+Ñ+Ø�SØ�SØð !ô ð .ˆØ�:‰:×%Ñ% fÓ-Ò5Ø× Ñ ØÜ%×+Ñ+Ø�SØ�SØð !ô ð  <ˆ×Ñ˜!ÑØ;ˆ×Ñ˜!ÑØ $§
¡
× ;Ñ ;¸KÓ HÈ7Õ RÐØ�
‰
×-Ñ-¨k×.@Ñ.@ÀÕ.CÐEZÔ[Ø×2Ñ2°;×3EÑ3EÀaÕ3HÊ,ÐXmÓnˆØ�
‰
×Ñ˜M×+?Ñ+?Ô@Ø×ÑÐ0Ö1r   rD   )N)
rE   rF   rG   rH   r   rb   rB   rI   rJ   rK   rL   s   @@r   rN   rN   X   s+   ù‡ € ÷1ó 1÷ò ÷B2÷ B2ð B2r   rN   N)Úloggingr   Úfusion_baser   Úfusion_utilsr   Úonnxr   r   r   Ú
onnx_modelr
   rE   Úloggerr   rN   rD   r   r   Ú<module>r�      sB   ðõ å Ý $ß /Ñ /Ý  á	�8Ó	€ôEZ�fô EZôPO2˜Fö O2r   