
    h                     J    S r SSKrSSKJrJr   " S S\R
                  5      rg)zDefine SpaceToDepth fusion.    N   )fusions
onnx_modelc                      ^  \ rS rSrSrS\R                  4U 4S jjrS\R                  S\
\\\R                     4   S\
\\R                  4   4S jrS\R                  S\
\\\R                     4   S\
\\R                  4   4S	 jrS
rU =r$ )FusionSpaceToDepth   zFusion for SpaceToDepth.modelc                 (   > [         TU ]  USS5        g)z@Initialize.

Args:
    model: An onnx_model.ONNXModel instance.
SpaceToDepthReshapeN)super__init__)selfr	   	__class__s     ~/var/www/fran/franai/venv/lib/python3.13/site-packages/onnxruntime/quantization/execution_providers/qnn/fusion_spacetodepth.pyr   FusionSpaceToDepth.__init__   s     		:    nodeinput_name_to_nodesoutput_name_to_nodec           	        ^ ^ UnU4S jnU" US5      =nb<  U" US5      =nb0  U" US5      =nb$  U" US5      =n	b  U" U	S5      =n
b  U" U
S5      =nc  gU 4S jnU" UR                   S   5      =nb`  U" UR                  S   5      =nbH  U" UR                  S   5      =nb0  U" U	R                  S   5      =nb  U" UR                  S   5      =nc  gT R                  US5      nT R                  US5      nT R                  U
S5      n[        U5      S:w  d<  [        U5      S	:w  d-  [        U5      S:w  d  [        U5      S
:w  d  [        U5      S:w  a  gUu  nnnnUS   nUUUUU-  UUU-  U/:w  dX  U/ SQ:w  dP  UUUUU-  UU-  -  US-  /:w  d:  U/ SQ:w  d2  UUUUS-  UU-  UU-  /:w  d  U/ SQ:w  d  UUUS-  U-  UU-  UU-  /:w  a  gT R                  R                  UUUUU	U
U/5        [        R                  R                  T R                  T R                  5       UR                   S   /UR                  S   /US9nT R                  R                  U5        g)a  Fuse for early version of YOLO.

Pattern:

        |     [N, C, H, W]
     Reshape
        |     [N, C, H/blk, blk, W/blk, blk]
    Transpose
        |     [N, C, H/blk, W/blk, blk, blk]
     Reshape
        |     [N, C, H/blk * W/blk, blk * blk]
    Transpose
        |     [N, C, blk * blk, H/blk * W/blk]
     Reshape
        |     [N, C, blk * blk, H/blk, W/blk]
    Transpose
        |     [N, blk * blk, C, H/blk, W/blk]
     Reshape
        |     [N, blk * blk * C, H/blk, W/blk]

This sequence can be fused into a single SpaceToDepth with blocksize `blk`. Note that unlike DepthToSpace
supporting DCR or CRD mode, SpaceToDepth only supports DCR mode in its latest opset version (13), which matches
the pattern here.
c                    > U R                   S   T;  a  gTU R                   S      n[        U5      S:  d  US   R                  U:w  a  gUS   $ )zGet target child of given node.r   N   )outputlenop_type)parent_nodetarget_op_typechildrenr   s      r   get_target_child7FusionSpaceToDepth._fuse_yolo.<locals>.get_target_child8   sY    !!!$,??*;+=+=a+@AH8}q HQK$7$7>$IA;r   	Transposer   Fc                    > TR                   R                  U 5      nU(       d  gTR                  U5      nU(       d  gU$ )z Get shape for given tensor name.N)r	   get_tensor_typetensor_shape_to_list)tensor_nametensor_typetensor_shaper   s      r   get_tensor_shape7FusionSpaceToDepth._fuse_yolo.<locals>.get_tensor_shapeM   s9    **44[AK44[ALr   r   perm         r   )r   r      r,   r   r.   r/   )r   r   r   r/   )r   r/   r   r   r,   )nameinputsoutputs	blocksizeT)inputr   get_node_attributer   nodes_to_removeextendonnxhelper	make_nodefused_op_typecreate_unique_node_namenodes_to_addappend)r   r   r   r   reshape_node1r    transpose_node1reshape_node2transpose_node2reshape_node3transpose_node3reshape_node4r)   input_shapereshape_shape1reshape_shape2reshape_shape3reshape_shape4transpose_perm1transpose_perm2transpose_perm3batchchannelheightwidthr3   s2d_nodes   ` `                        r   
_fuse_yoloFusionSpaceToDepth._fuse_yolo   s   < 		 !1 LL_U!1/9!MMV#3M;#OOX!1/9!MMV#3M;#OOX!1/9!MMV
	  -]-@-@-CDD[M"2=3G3G3J"KKT"2=3G3G3J"KKT"2=3G3G3J"KKT"2=3G3G3J"KKT11/6J11/6J11/6J !>"a'>"a'>"a'>"a' )4%w"1%	ugv/BIuXaOaclmm"44%6Y3F5T]K]2^`ikl`l!mm,.%)Q,)@SUZ^gUg!hh/1%A)?9ATV[_hVh!ii##
	
 ;;((--/!''*+"))!,- ) 
 	  *r   c                 (    U R                  XU5        g)a4  Fuse a sequence of Reshape and Transpose nodes into a single SpaceToDepth node.

Args:
    node: An onnx.NodeProto matching the specified search type (i.e., Reshape).
    input_name_to_nodes: A dict mapping tensor name to consumed nodes.
    output_name_to_node: A dict mapping tensor name to produced node.
N)rS   )r   r   r   r   s       r   fuseFusionSpaceToDepth.fuse   s     	3FGr    )__name__
__module____qualname____firstlineno____doc__r   	ONNXModelr   r8   	NodeProtodictstrlistrS   rV   __static_attributes____classcell__)r   s   @r   r   r      s    ";j22 ;{nn{ "#tDNN';";<{ "#t~~"56	{zHnnH "#tDNN';";<H "#t~~"56	H Hr   r   )r]   r8    r   r   Fusionr   rX   r   r   <module>rg      s$    "  #UH UHr   