o
    i                     @   s2   d Z ddlZddlmZmZ G dd dejZdS )zDefine SpaceToDepth fusion.    N   )fusions
onnx_modelc                       s   e Zd ZdZdejf fddZdejde	e
eej f de	e
ejf fdd	Zdejde	e
eej f de	e
ejf fd
dZ  ZS )FusionSpaceToDepthzFusion for SpaceToDepth.modelc                    s   t  |dd dS )zXInitialize.

        Args:
            model: An onnx_model.ONNXModel instance.
        ZSpaceToDepthReshapeN)super__init__)selfr   	__class__ ~/home/kim/smarthome/.venv/lib/python3.10/site-packages/onnxruntime/quantization/execution_providers/qnn/fusion_spacetodepth.pyr	      s   zFusionSpaceToDepth.__init__nodeinput_name_to_nodesoutput_name_to_nodec              	      s|  |} fdd}||d }du s>||d }du s>||d }du s>||d }	du s>||	d }
du s>||
d }du r@dS fdd}||j d	  }du s}||jd	  }du s}||jd	  }du s}||	jd	  }du s}||jd	  }du rdS |d
}|d
}|
d
}t|dkst|dkst|dkst|dkst|dkrdS |\}}}}|d }||||| ||| |gks|g dks||||| ||  |d gks|g dks||||d || || gks|g dks|||d | || || gkrdS j|||||	|
|g tjjj	
 |j d	 g|jd	 g|d}j| dS )at  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                    sF   | j d  vr	dS  | j d  }t|dks|d j|krdS |d S )zGet target child of given node.r   N   )outputlenZop_type)Zparent_nodeZtarget_op_typechildren)r   r   r   get_target_child8   s   z7FusionSpaceToDepth._fuse_yolo.<locals>.get_target_childZ	TransposeNr   Fc                    s*    j | }|s
dS  |}|sdS |S )z Get shape for given tensor name.N)r   Zget_tensor_typeZtensor_shape_to_list)Ztensor_nameZtensor_typeZtensor_shape)r
   r   r   get_tensor_shapeM   s   
z7FusionSpaceToDepth._fuse_yolo.<locals>.get_tensor_shaper   perm         r   )r   r      r   r   r   r   )r   r   r   r   )r   r   r   r   r   )nameZinputsZoutputs	blocksizeT)inputr   Zget_node_attributer   Znodes_to_removeextendonnxhelperZ	make_nodeZfused_op_typeZcreate_unique_node_nameZnodes_to_addappend)r
   r   r   r   Zreshape_node1r   Ztranspose_node1Zreshape_node2Ztranspose_node2Zreshape_node3Ztranspose_node3Zreshape_node4r   Zinput_shapeZreshape_shape1Zreshape_shape2Zreshape_shape3Zreshape_shape4Ztranspose_perm1Ztranspose_perm2Ztranspose_perm3batchZchannelheightwidthr   Zs2d_noder   )r   r
   r   
_fuse_yolo   sl   " "

zFusionSpaceToDepth._fuse_yoloc                 C   s   |  ||| dS )a\  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)r'   )r
   r   r   r   r   r   r   fuse   s   zFusionSpaceToDepth.fuse)__name__
__module____qualname____doc__r   Z	ONNXModelr	   r!   Z	NodeProtodictstrlistr'   r(   __classcell__r   r   r   r   r      s"    
}r   )r,   r!    r   r   ZFusionr   r   r   r   r   <module>   s   