Ë
    cQêjB^  ã                   óv   — d dl mZ d dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZ d dlmZ  ee«      Z G d„ de«      Zy)	é    )Ú	getLoggerN)ÚFusion)ÚFusionUtils)Ú	NodeProtoÚhelperÚnumpy_helper)Ú	OnnxModelc                   ó  ‡ — e Zd ZdZdefˆ fd„Zdededz  fd„Zdede	dz  fd„Z
d	ed
ede	fd„Zdede	fd„Zd	ede	fd„Zdedede	fd„Zdededefd„Zdedefd„Zdedefd„Z	 ddedededede	dedz  defd„Zd„ Zˆ xZS ) ÚFusionMultiHeadAttentionDiTu‰  
    Fuse MultiHeadAttention for Diffusion Transformer (DiT) models like F5-TTS.

    Recognizes attention patterns where Q, K, V are pre-computed (e.g., after RoPE)
    and K is pre-transposed, with optional Cast nodes for mixed-precision (FP16) inference
    and a custom scalar scale factor before Softmax.

    Supported patterns (anchored at Softmax):

        MatMul(Q, K^T) â†’ [Cast(FP16â†’FP32)] â†’ Mul(scale) â†’ Softmax â†’ [Cast(FP32â†’FP16)] â†’ MatMul(attn, V)
            â†’ Transpose(perm=0,2,1,3) â†’ Reshape â†’ output

    Where:
        - Q is in BNSH format (post-RoPE or post-projection)
        - K is pre-transposed to BNHS format (via Transpose(perm=0,1,3,2) or natively)
        - V is in BNSH format
        - Scale is an arbitrary scalar constant (e.g., 100.0 for DiT, or 1/sqrt(d_k))
        - Cast nodes are optional (present in FP16 models for FP32 Softmax stability)
    Úmodelc                 ó,   •— t         ‰| �  |ddg¬«       y )NÚMultiHeadAttentionÚSoftmax)Úfused_op_typeÚsearch_op_types)ÚsuperÚ__init__)Úselfr   Ú	__class__s     €úl/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/onnxruntime/transformers/fusion_mha_dit.pyr   z$FusionMultiHeadAttentionDiT.__init__%   s   ø€ Ü‰Ñ˜Ð.BÐU^ÐT_ÐÕ`ó    Úmul_nodeÚreturnNc                 óJ  — t        d«      D ]•  }| j                  j                  |j                  |   «      }|€Œ.t	        |t
        j                  «      r+|j                  dk(  sŒXt        |j                  «       «      c S t	        |t        t        f«      sŒŠt        |«      c S  y)zÁExtract the scalar scale constant from a Mul node.

        The scale can be in either input[0] or input[1].

        Returns:
            float: the scale value, or None if not found.
        é   Né   )Úranger   Úget_constant_valueÚinputÚ
isinstanceÚnpÚndarrayÚsizeÚfloatÚitemÚint)r   r   ÚiÚvalues       r   Úget_scale_from_mulz.FusionMultiHeadAttentionDiT.get_scale_from_mul(   s�   € ô �q“ò 	(ˆAØ—J‘J×1Ñ1°(·.±.ÀÑ2CÓDˆEØÑ Ü˜e¤R§Z¡ZÔ0Ø—z‘z Q“Ü$ U§Z¡Z£\Ó2Ò2Ü ¬¬U |Õ4Ü  ›<Ò'ð	(ð r   c                 ó@  — ddg}t        d«      D ]v  }| j                  j                  |j                  |   «      }|€Œ.t	        |t
        j                  «      r|j                  dk(  ||<   Œ[t	        |t        t        f«      sŒrd||<   Œx |d   r|d   sy|d   r|d   syy)z¬Determine which input of Mul is the data (non-constant) input.

        Returns:
            int: the input index (0 or 1) of the data input, or None if ambiguous.
        Fr   Nr   Tr   )
r   r   r   r   r    r!   r"   r#   r&   r$   )r   r   Úis_scalar_constantr'   r(   s        r   Úget_data_input_of_mulz1FusionMultiHeadAttentionDiT.get_data_input_of_mul:   s©   € ð $ U˜^ÐÜ�q“ò 	1ˆAØ—J‘J×1Ñ1°(·.±.ÀÑ2CÓDˆEØÑ Ü˜e¤R§Z¡ZÔ0Ø,1¯J©J¸!©OÐ& qÒ)Ü ¬¬U |Õ4Ø,0Ð& qÒ)ð	1ð ˜aÒ Ð);¸AÒ)>ØØ˜aÒ Ð);¸AÒ)>ØØr   Útensor_nameÚoutput_name_to_nodec                 óf  — ||vry||   }d}d}|�¡||k  rœ|j                   dk(  rZt        j                  |d«      }|g d¢k(  r=|j                  d   |v r*||j                  d      }| j	                  |«      }|dkD  r|S 	 y|j                  d   |v r||j                  d      }n	 y|dz  }|�||k  rŒœy)u‡  Detect num_heads by walking upstream from a BNSH tensor looking for a Reshape node.

        Typical upstream patterns:
            Reshape(shape=[B, S, N, H]) â†’ Transpose(perm=0,2,1,3) â†’ ... â†’ tensor_BNSH
            Reshape(shape=Concat(..., N, H)) â†’ Transpose(perm=0,2,1,3) â†’ ... â†’ tensor_BNSH

        Returns:
            int: number of heads, or 0 if not detected.
        r   é
   Ú	TransposeÚperm©r   r   r   é   r   )Úop_typer	   Úget_node_attributer   Ú_get_num_heads_from_reshape)	r   r-   r.   ÚcurrentÚdepthÚ	max_depthr2   ÚparentÚ	num_headss	            r   Údetect_num_headsz,FusionMultiHeadAttentionDiT.detect_num_headsO   sñ   € ð Ð1Ñ1Øð & kÑ2ˆØˆØˆ	àÐ! e¨iÒ&7Ø�‰ +Ò-Ü ×3Ñ3°G¸VÓD�Øš<Ò'à—}‘} QÑ'Ð+>Ñ>Ø!4°W·]±]À1Ñ5EÑ!F˜Ø$(×$DÑ$DÀVÓ$L˜	Ø$ qš=Ø#,Ð,àð ð �}‰}˜QÑÐ#6Ñ6Ø-¨g¯m©m¸AÑ.>Ñ?‘àð ð �Q‰JˆEð% Ð! e¨iÓ&7ð( r   Únodec                 óŽ  — |j                   dk7  ryt        |j                  «      dk\  ra| j                  j	                  |j                  d   «      }|�7t        |t        j                  «      r|j                  dk(  rt        |d   «      S t        |j                  «      dk\  �r|j                  d   | j                  j                  d«      D �ch c]  }|j                  d   ’Œ c}v rÔ| j                  j                  d«      D �cg c]$  }|j                  d   |j                  d   k(  sŒ#|‘Œ& }}|rŠt        |d   j                  «      dk(  ro| j                  j	                  |d   j                  d   «      }|�Bt        |t        j                  «      r(|j                  dk(  rt        |j                  «       «      S yc c}w c c}w )zèExtract num_heads from a Reshape node's shape parameter.

        Handles:
            - Static shape constant: [B, S, num_heads, head_dim]
            - Concat-based shape: Concat([B_dim], [S_dim], [num_heads], [head_dim])
        ÚReshaper   r   r   é   ÚConcat)r5   Úlenr   r   r   r    r!   r"   r#   r&   Úget_nodes_by_op_typeÚoutputr%   )r   r>   Úshape_valueÚnÚconcat_nodesr(   s         r   r7   z7FusionMultiHeadAttentionDiT._get_num_heads_from_reshapew   sp  € ð �<‰<˜9Ò$Øô ˆt�z‰z‹?˜aÒØŸ*™*×7Ñ7¸¿
¹
À1¹ÓFˆKØÐ&¬:°kÄ2Ç:Á:Ô+NÐS^×ScÑScÐghÒShÜ˜; q™>Ó*Ð*ô ˆt�z‰z‹?˜aÓ D§J¡J¨q¡MÈ4Ï:É:×KjÑKjÐksÓKtÖ5uÀa°a·h±h¸q³kÒ5uÑ$uØ'+§z¡z×'FÑ'FÀxÓ'PÖq !ÐTU×T\ÑT\Ð]^ÑT_Ðcg×cmÑcmÐnoÑcpÓTpšAÐqˆLÐqÙ¤ L°¡O×$9Ñ$9Ó :¸aÒ ?ØŸ
™
×5Ñ5°lÀ1±o×6KÑ6KÈAÑ6NÓO�ØÐ$Ü! %¬¯©Ô4¸¿¹ÀqºÜ" 5§:¡:£<Ó0Ð0àùò 6vùÚqs   ÃF=Ä$GÄ*Gc                 ó   — | j                   j                   j                  j                  D ]z  }|j                  |k(  sŒ|j                  j
                  j                  }|sŒ6t        |j                  «      dk(  sŒO|j                  d   }|j                  dkD  sŒn|j                  c S  | j                   j                   j                  j                  D ]z  }|j                  |k(  sŒ|j                  j
                  j                  }|sŒ6t        |j                  «      dk(  sŒO|j                  d   }|j                  dkD  sŒn|j                  c S  y)z�Try to detect num_heads from a BNSH tensor's shape in graph inputs or value_info.

        For BNSH tensors, the N dimension (index 1) is num_heads.
        rA   r   r   )r   Úgraphr   ÚnameÚtypeÚtensor_typeÚshaperC   ÚdimÚ	dim_valueÚ
value_info)r   r-   ÚinprN   Údim_nÚvis         r   Ú!detect_num_heads_from_input_shapez=FusionMultiHeadAttentionDiT.detect_num_heads_from_input_shape’   s  € ð —:‘:×#Ñ#×)Ñ)×/Ñ/ò 	/ˆCØ�x‰x˜;Ó&ØŸ™×,Ñ,×2Ñ2�ÚœS §¡›^¨qÓ0Ø!ŸI™I a™L�EØ—‘¨Ó*Ø$Ÿ™Ò.ð	/ð —*‘*×"Ñ"×(Ñ(×3Ñ3ò 	/ˆBØ�w‰w˜+Ó%ØŸ™×+Ñ+×1Ñ1�ÚœS §¡›^¨qÓ0Ø!ŸI™I a™L�EØ—‘¨Ó*Ø$Ÿ™Ò.ð	/ð r   Úreshape_outÚtranspose_outc                 ó>   — | j                  |j                  d   «      S )z›Try to detect num_heads from the output Transpose's input shape.

        The Transpose converts BNSH -> BSNH. The N dimension gives us num_heads.
        r   )rU   r   )r   rV   rW   s      r   Údetect_num_heads_from_outputz8FusionMultiHeadAttentionDiT.detect_num_heads_from_outputª   s    € ð
 ×5Ñ5°m×6IÑ6IÈ!Ñ6LÓMÐMr   Ú
input_nameÚoutput_namec                 óÒ  — d}| j                   j                  |«      }|€Tt        j                  t	        j
                  g d¢d¬«      |¬«      }| j                   j                  || j                  «       t        j                  d||g|g| j                   j                  d«      ¬«      }| j                  j                  |«       | j                  | j                  |j                  <   |S )a  Add a Reshape node to convert 4D BxSxNxH to 3D BxSxD.

        Args:
            input_name: input name for the 4D tensor of shape BxSxNxH.
            output_name: output name for the 3D tensor of shape BxSxD.

        Returns:
            str: the output name.
        Úbsnh_to_bsd_reshape_dims)r   r   éÿÿÿÿÚint64)Údtype)rK   r@   ©ÚinputsÚoutputsrK   )r   Úget_initializerr   Ú
from_arrayr!   ÚarrayÚadd_initializerÚthis_graph_namer   Ú	make_nodeÚcreate_node_nameÚnodes_to_addÚappendÚnode_name_to_graph_namerK   )r   rZ   r[   Únew_dims_nameÚnew_dimsÚreshape_nodes         r   Úreshape_to_3dz)FusionMultiHeadAttentionDiT.reshape_to_3d±   sÅ   € ð 3ˆØ—:‘:×-Ñ-¨mÓ<ˆØÐÜ#×.Ñ.¬r¯x©xº
È'Ô/RÐYfÔgˆHØ�J‰J×&Ñ& x°×1EÑ1EÔFÜ×'Ñ'ØØ Ð.Ø �MØ—‘×,Ñ,¨YÓ7ô	
ˆð 	×Ñ× Ñ  Ô.Ø:>×:NÑ:Nˆ×$Ñ$ \×%6Ñ%6Ñ7ØÐr   c           	      óþ   — |dz   }t        j                  d|g|g| j                  j                  dd¬«      g d¢¬«      }| j                  j                  |«       | j                  | j                  |j                  <   |S )z4Add a Transpose node to convert BNSH to BSNH format.Ú_BSNHr1   ÚTranspose_BNSH_to_BSNH©Úname_prefixr3   ©rK   r2   ©	r   ri   r   rj   rk   rl   rh   rm   rK   ©r   rZ   r[   Útranspose_nodes       r   Útranspose_bnsh_to_bsnhz2FusionMultiHeadAttentionDiT.transpose_bnsh_to_bsnhÊ   ó|   € à  7Ñ*ˆÜ×)Ñ)ØØˆLØˆMØ—‘×,Ñ,¨[ÐF^Ð,Ó_Úô
ˆð 	×Ñ× Ñ  Ô0Ø<@×<PÑ<Pˆ×$Ñ$ ^×%8Ñ%8Ñ9ØÐr   c           	      óþ   — |dz   }t        j                  d|g|g| j                  j                  dd¬«      g d¢¬«      }| j                  j                  |«       | j                  | j                  |j                  <   |S )z4Add a Transpose node to convert BNHS to BNSH format.Ú_BNSHr1   ÚTranspose_BNHS_to_BNSHru   ©r   r   r4   r   rw   rx   ry   s       r   Útranspose_bnhs_to_bnshz2FusionMultiHeadAttentionDiT.transpose_bnhs_to_bnshØ   r|   r   ÚqÚkÚvrE   r<   Úscalec                 óZ  — |dkD  sJ ‚|||g}|g}t        j                  d||| j                  j                  d«      ¬«      }	d|	_        |	j
                  j                  t        j                  d|«      g«       |�0|	j
                  j                  t        j                  d|«      g«       |	S )a³  Create a MultiHeadAttention node.

        Args:
            q: name of query input (BSD format, 3D).
            k: name of key input (BNSH format, 4D).
            v: name of value input (BNSH format, 4D).
            output: output name of MHA.
            num_heads: number of attention heads.
            scale: optional custom scale factor for attention logits.

        Returns:
            NodeProto: the node created.
        r   r   ra   zcom.microsoftr<   r…   )r   ri   r   rj   ÚdomainÚ	attributeÚextendÚmake_attribute)
r   r‚   rƒ   r„   rE   r<   r…   Ú
mha_inputsÚmha_outputsÚmha_nodes
             r   Úcreate_multihead_attention_nodez;FusionMultiHeadAttentionDiT.create_multihead_attention_nodeæ   sª   € ð, ˜1Š}Ðˆ}à˜˜A�Yˆ
Ø�hˆä×#Ñ#Ø ØØØ—‘×,Ñ,Ð-AÓBô	
ˆð *ˆŒØ×Ñ×!Ñ!¤6×#8Ñ#8¸ÀiÓ#PÐ"QÔRàÐØ×Ñ×%Ñ%¤v×'<Ñ'<¸WÀeÓ'LÐ&MÔNàˆr   c                 óê  — |j                   dk(  sJ ‚|}| j                  j                  |j                  d   «      ry t	        j
                  |d«      }|�|dvry |€| j                  j                  «       dk  ry d }| j                  j                  |g d¢g d¢|«      }|�|\  }}}	}
n+| j                  j                  |g d¢g d	¢|«      }|€y |\  }}	}
t        j                  |	d
g d¢«      sy d }| j                  j                  |g d¢g d¢«      }|�|\  }}}n)| j                  j                  |ddgdd g«      }|€y |\  }}| j                  |«      }|€t        j                  d«       y | j                  |«      }|€y |r|j                  d   n|j                  d   }|j                  |   |k7  r]|r/| j                  j                  |g d¢dd|z
  dg«      }|€y |\  }}}n,| j                  j                  |ddgdd|z
  g«      }|€y |\  }}|j                  d   }|j                  d   }|j                  d   }d}|�)||v r%||   }|j                   dk(  r|j                  d   }d}| j                  j!                  |dd|¬«      }|�)t        j                  |d
g d¢«      r|j                  d   }n| j#                  |«      }d}|}||v r%||   }|j                   dk(  r|j                  d   }d}| j                  j%                  |«      }| j                  j%                  |«      }| j                  j%                  |«      }|�|�||k7  rt        j                  d||«       y |�|�||k7  rt        j                  d||«       y |€|�|s|�|€t        j                  d||«       y |r!|�|�||k7  rt        j                  d||«       y | j'                  ||«      } | dk  r| j'                  ||«      } | dk  r| j)                  |«      } | dk  r| j)                  |«      } | dk  r| j+                  |
|	«      } | dk  rt        j                  d«       y | j-                  |«      }!| j/                  |!|!dz   «      }"|j                  d   |j                  d   |j                  d   g}#|�|#j1                  |j                  d   «       |�|#j1                  |j                  d   «       |#D ]0  }$|$|v sŒt3        ||$   «      dkD  sŒt        j                  d|$«        y  | j5                  |"|||
j                  d   | |¬«      }%| j6                  j1                  |%«       | j8                  | j:                  |%j<                  <   ||	|
g}&|�|&j1                  |«       | j                  j?                  |&|
j                  d   g||«      st        j                  d «       y | j@                  jC                  |&«       d| _"        y )!Nr   r   Úaxis)r^   r4   é   )ÚCastÚMatMulr1   r@   )©r   r   r”   r”   r”   )r“   r1   r@   )r”   r”   r”   r2   r3   )ÚMulr’   r“   )r   Nr   r•   r“   z9fuse_dit_attention: failed to extract scale from Mul noder   Fr’   Tr1   )Úinput_indexr.   r€   zBfuse_dit_attention: Q/V element type mismatch (%s vs %s), skippingzBfuse_dit_attention: Q/K element type mismatch (%s vs %s), skippingzlfuse_dit_attention: cast nodes present, V not traced through Cast, types unverifiable (q=%s, v=%s), skippingzLfuse_dit_attention: K Cast source dtype mismatch with Q (%s vs %s), skippingz.fuse_dit_attention: failed to detect num_headsÚ_BSDzDfuse_dit_attention: intermediate %s has multiple consumers, skipping)r‚   rƒ   r„   rE   r<   r…   zFfuse_dit_attention: downstream nodes have external consumers, skipping)#r5   r   Úfind_graph_outputrE   r	   r6   Úget_opset_versionÚmatch_child_pathr   Úcheck_node_attributeÚmatch_parent_pathr)   ÚloggerÚdebugr,   r   Úmatch_parentr�   Ú	get_dtyper=   rU   rY   r{   rq   rl   rC   rŽ   rk   rh   rm   rK   Úis_safe_to_fuse_nodesÚnodes_to_remover‰   Úprune_graph)'r   r>   Úinput_name_to_nodesr.   Úsoftmaxr�   Úcast_after_softmaxÚchild_nodesÚ	matmul_svrW   rV   Úcast_before_softmaxÚparent_nodesÚ	mul_scaleÚ	matmul_qkr…   Údata_input_idxÚexpected_data_sourceÚparent_nodes_altÚq_bnshÚk_transposed_inputÚv_bnshÚv_traced_through_castÚ
v_producerÚk_transpose_nodeÚk_bnshÚk_traced_through_castÚk_bnsh_for_dtypeÚ
k_producerÚq_dtypeÚk_dtypeÚv_dtyper<   Úq_bsnhÚq_bsdÚintermediate_outputsr-   r�   r¢   s'                                          r   Úfusez FusionMultiHeadAttentionDiT.fuse  sà  € Ø�|‰|˜yÒ(Ð(Ð(Øˆð �:‰:×'Ñ'¨¯©°qÑ(9Ô:Øô ×+Ñ+¨G°VÓ<ˆØÐ ¨GÑ 3ØØˆ<˜DŸJ™J×8Ñ8Ó:¸RÒ?Øð
 "Ðð —j‘j×1Ñ1ØÚ6Ú,Øó	
ˆð Ð"ØHSÑEÐ 	¨=¹+ð Ÿ*™*×5Ñ5ØÚ2Ú(Ø#ó	ˆKð Ð"ØØ4?Ñ1ˆI�} kô ×/Ñ/°¸vÂ|ÔTØð
 #Ðð —z‘z×3Ñ3ØÚ%Úó
ˆð
 Ð#Ø8DÑ5ˆIÐ*©Ið  Ÿ:™:×7Ñ7ØØ˜Ð!Ø�D�	óˆLð
 Ð#ØØ#/Ñ ˆI�yð
 ×'Ñ'¨	Ó2ˆØˆ=Ü�L‰LÐTÔUØð ×3Ñ3°IÓ>ˆØÐ!Øñ ATÐ2×9Ñ9¸!Ò<ÐYb×YiÑYiÐjkÑYlÐØ�?‰?˜>Ñ*Ð.BÒBá"Ø#'§:¡:×#?Ñ#?ØÚ-Ø˜˜NÑ*¨AÐ.ó$Ð ð
 $Ð+ØØ<LÑ9�	Ð.±	à#'§:¡:×#?Ñ#?ØØ˜HÐ%Ø˜˜NÑ*Ð+ó$Ð ð
 $Ð+ØØ'7Ñ$�	˜9ð
 —‘ Ñ#ˆØ&Ÿ_™_¨QÑ/ÐØ—‘ Ñ#ˆð !&ÐØÐ)¨fÐ8KÑ.KØ,¨VÑ4ˆJØ×!Ñ! VÒ+Ø#×)Ñ)¨!Ñ,�Ø(,Ð%ð  Ÿ:™:×2Ñ2Ø�{°ÐGZð 3ó 
Ðð Ð'¬K×,LÑ,LÐM]Ð_eÒgsÔ,tØ%×+Ñ+¨AÑ.‰Fð ×0Ñ0Ð1CÓDˆFð !&ÐØ!ÐØÐ2Ñ2Ø,Ð-=Ñ>ˆJØ×!Ñ! VÒ+Ø#-×#3Ñ#3°AÑ#6Ð Ø(,Ð%ð —*‘*×&Ñ& vÓ.ˆØ—*‘*×&Ñ&Ð'7Ó8ˆØ—*‘*×&Ñ& vÓ.ˆØÐ 7Ð#6¸7ÀgÒ;MÜ�L‰LÐ]Ð_fÐhoÔpØØÐ 7Ð#6¸7ÀgÒ;MÜ�L‰LÐ]Ð_fÐhoÔpØð  Ð+Ð/AÐ/MÑWlØˆ ' /Ü—‘ð@àØô	ð ñ ! WÐ%8¸WÐ=PÐU\Ð`gÒUgÜ�L‰LØ^ØØôð
 ð
 ×)Ñ)¨&Ð2EÓFˆ	Ø˜Š>à×-Ñ-¨fÐ6IÓJˆIØ˜Š>à×>Ñ>¸vÓFˆIØ˜Š>Ø×>Ñ>¸vÓFˆIØ˜Š>à×9Ñ9¸+À}ÓUˆIØ˜Š>Ü�L‰LÐIÔJØð
 ×,Ñ,¨VÓ4ˆØ×"Ñ" 6¨6°F©?Ó;ˆð !*× 0Ñ 0°Ñ 3°Y×5EÑ5EÀaÑ5HÈ'Ï.É.ÐYZÑJ[Ð\ÐØÐ*Ø ×'Ñ'Ð(;×(BÑ(BÀ1Ñ(EÔFØÐ)Ø ×'Ñ'Ð(:×(AÑ(AÀ!Ñ(DÔEØ/ò 	ˆKØÐ1Ò1´cÐ:MÈkÑ:ZÓ6[Ð^_Ó6_Ü—‘ÐcÐepÔqÙð	ð ×7Ñ7ØØØØ×%Ñ% aÑ(ØØð 8ó 
ˆð 	×Ñ× Ñ  Ô*Ø6:×6JÑ6Jˆ×$Ñ$ X§]¡]Ñ3ð % m°[ÐAˆØÐ)Ø×"Ñ"Ð#5Ô6ð
 �z‰z×/Ñ/Ø˜k×0Ñ0°Ñ3Ð4Ð6IÐK^ô
ô �L‰LÐaÔbØà×Ñ×#Ñ# OÔ4ð  ˆÕr   )N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r   r   r$   r)   r&   r,   ÚstrÚdictr=   r7   rU   rY   rq   r{   r�   rŽ   rÀ   Ú__classcell__)r   s   @r   r   r      s>  ø„ ñð(a˜iõ að¨9ð ¸À¹ó ð$¨ið ¸CÀ$¹Jó ð*&¨Cð &Àdð &Èsó &ðP°	ð ¸có ð6¸Sð ÀSó ð0N¸	ð NÐR[ð NÐ`có Nð¨ð ¸#ð À#ó ð2°ð ¸ó ð°ð ¸ó ð* #ñ(àð(ð ð(ð ð	(ð
 ð(ð ð(ð �t‰|ð(ð 
ó(öTE r   r   )Úloggingr   Únumpyr!   Úfusion_baser   Úfusion_utilsr   Úonnxr   r   r   Ú
onnx_modelr	   rÁ   r�   r   © r   r   ú<module>rÏ      s4   ðõ
 ã Ý Ý $ß 0Ñ 0Ý  á	�8Ó	€ôE  &õ E r   