a
    f                     @   s  d dl Z d dlmZ d dlZd dlZd dlmZ eejedk rVe dej d dd Z	dd	 Z
d
d Zdd ZddlmZ dd ZejdddZejdddZejdddZejdddZejejejejejejfZejeejeejedede	dededed e
d!e
i
ZeD ]Z eee < qi Z!d d"l"m#Z# d d#l$m%Z% dd$l&m'Z'm(Z( d%d& Z)d3ejej*d(d)d*Z+e,d+krG d,d- d-ejZ-G d.d/ d/ejjZ.e. Z/e0d0d1Z1e+e/e1d'd2Z2e3e2 dS )4    N)LooseVersionz1.8.0zVtorch.fx requires version higher than 1.8.0. But You are using an old version PyTorch z. c                 C   s   dS )zYEnsures tensor array sizes are appropriate by clamping specified input and output shapes.r    input_shapesoutput_shapesr   r   K/var/www/html/django/DPS/env/lib/python3.9/site-packages/thop/fx_profile.pycount_clamp   s    r   c                 C   s   |d   S )z9Returns the number of elements in the first output shape.r   numelr   r   r   r   	count_mul   s    r   c                 C   s(   | d }|d }|d }|  }|| S )zgCalculates matrix multiplication ops based on input and output tensor shapes for performance profiling.r   r	   )r   r   Zin_shape	out_shapeZin_featuresZnum_elementsr   r   r   count_matmul   s
    r   c                 O   s&   t | |}d|v r"||d  7 }|S )zVCalculates the total FLOPs for a linear layer, including bias operations if specified.biasr   )r   r
   )r   r   argskwargsflopsr   r   r   count_fn_linear"   s    
r      )calculate_convc                 O   s   |\}}}}}}	}
t | dkr(| \}}nt | dkr>| \}}}|d }|dd  }d}|d }t||| ||
 }t|S )zyCalculates total operations (FLOPs) for a 2D conv layer based on input and output shapes using
    `calculate_conv`.
          r   Nr   )lenr
   r   itemint)r   r   r   r   inputsweightr   ZstridepaddingZdilationgroupsZx_shapeZk_shapeZb_shaper   Zkernel_parametersbias_op
in_channel	total_opsr   r   r   count_fn_conv2d-   s    

r"   )modulec                 C   s
   t ||S )zQCounts the FLOPs for a fully connected (linear) layer in a neural network module.)r   )r#   r   r   r   r   r   count_nn_linear@   s    r$   c                 O   s   dS )zRReturns 0 for a neural network module, input shapes, and output shapes in PyTorch.r   r   )r#   r   r   r   r   r   r   r   count_zero_opsE   s    r%   c           	      C   sZ   | j durdnd}|d }| j}| j}| jjdd  }t||| || }t|S )zUCalculates FLOPs for a 2D Conv2D layer in an nn.Module using input and output shapes.Nr   r   r   )	r   Zin_channelsr   r   shaper
   r   r   r   )	r#   r   r   r   r   r    r   Z
kernel_opsr!   r   r   r   count_nn_conv2dJ   s    r'   c                 C   s(   t |dksJ d|d }d|  S )zLCalculate FLOPs for an nn.BatchNorm2d layer based on the given output shape.r   z*nn.BatchNorm2d should only have one outputr   r   )r   r
   )r#   r   r   yr   r   r   count_nn_bn2dV   s    r)   zfunction linearclampzbuilt-in function addzbuilt-in method flz%built-in method conv2d of type objectzbuilt-in function mulzbuilt-in function truediv)symbolic_trace)	ShapeProp)prRedprYellowc                  O   s   dS )zOA no-op print function that takes any arguments without performing any actions.Nr   )r   r   r   r   r   
null_print~   s    r/   F)modinputc              
   C   s  t | }t|| t}|r"t}i }d}|jjD ]}|d|j d|j d|j	 d|j
  d}g }	|ddd	 |j
D ]:}
t|
|vrqz||t|
  dd	 |	|t|
  qz|  |d
|jd j  |jd jg}|jdv rd}n|jdkrtt|jdd dddd }|tv rRt| |	|g|j
R i |j}n|j|ft|< td| d n|jdkrt|j}|tv rt| |	|}n|j|ft|< t| d n|jdkr| |j}t|}|t|t|tv  t|tv rtt| ||	|}n|jft|< t| d tdt| t|trZtd n,tt| td|  |j d j  |jd j|t|j	< |dur||7 }td| d|  |d q2tt dkrddlm} td |t |S ) zVProfiles nn.Module for total FLOPs per operation and prints detailed nodes if verbose.r   zNodeOP:z	,	Target:z,	NodeName:z,	NodeArgs:Nzinput_shape:	)endzoutput_shape:	Ztensor_meta)outputplaceholderZcall_functionat< >|z| is missingZcall_methodz is missingZcall_modulezmodule type:zweight_shape: Nonezweight_shape: z.weightzCurrent node's FLOPs: z, total FLOPs: zP================================================================================)pprintzMissing operators: )r+   r,   	propagater/   printgraphnodesoptargetnamer   strappendmetar&   splitreplacestrip	count_mapr   missing_mapsr-   Zget_submoduletype
isinstancezero_opsZ
state_dictr.   r   keysr;   )r0   r1   verboseZgmZfprintZv_mapsZtotal_flopsnodeZ
node_flopsr   argr   keymr;   r   r   r   
fx_profile   sr    (

(
"


 

rT   __main__c                   @   s   e Zd Zdd ZdS )MyOPc                 C   s   |d S )z*Performs forward pass on given input data.r   r   )selfr1   r   r   r   forward   s    zMyOP.forwardN)__name__
__module____qualname__rX   r   r   r   r   rV      s   rV   c                       s$   e Zd Z fddZdd Z  ZS )MyModulec                    s6   t    tjdd| _tjdd| _t | _dS )zGInitializes MyModule with two linear layers and a custom MyOP operator.   r   N)	super__init__torchnnLinearlinear1linear2rV   myop)rW   	__class__r   r   r_      s    
zMyModule.__init__c                 C   s,   |  |}| |jddd}| || S )zApplies two linear transformations to the input tensor, clamps the second, then combines and processes
            with MyOP operator.
            g        g      ?)minmax)rc   rd   r*   re   )rW   xZout1Zout2r   r   r   rX      s    
zMyModule.forward)rY   rZ   r[   r_   rX   __classcell__r   r   rf   r   r\      s   r\      r]   )rO   )F)4loggingZdistutils.versionr   r`   thZtorch.nnra   __version__warningr   r   r   r   Zvision.calc_funcr   r"   Moduler$   r%   ZConv2dr'   ZBatchNorm2dr)   ZReLUZReLU6ZDropoutZ	MaxPool2dZ	AvgPool2dZAdaptiveAvgPool2drM   rb   rI   krJ   Ztorch.fxr+   Ztorch.fx.passes.shape_propr,   utilsr-   r.   r/   ZTensorrT   rY   rV   r\   netZrandndatar   r=   r   r   r   r   <module>   sj   	
O
