o
    h'                      @   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 r+e dej d dd Z	dd	 Z
d
d Zdd ZddlmZ dd ZdejfddZdejfddZdejfddZdejf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 < qi Z!d d"l"m#Z# d d#l$m%Z% dd$l&m'Z'm(Z( d%d& Z)d4d(ejd)ej*fd*d+Z+e,d,krG d-d. d.ejZ-G d/d0 d0ejjZ.e. Z/e0d1d2Z1e+e/e1d'd3Z2e3e2 dS dS )5    N)LooseVersionz1.8.0zVtorch.fx requires version higher than 1.8.0. But You are using an old version PyTorch z. c                 C      dS )zYEnsures tensor array sizes are appropriate by clamping specified input and output shapes.r    input_shapesoutput_shapesr   r   c/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/thop/fx_profile.pycount_clamp      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   in_shape	out_shapein_features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   stridepaddingdilationgroupsx_shapek_shapeb_shaper   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_linearA   s   
r/   c                 O   r   )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_opsF   r
   r0   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   in_channelsr%   r!   shaper   r   r   r   )	r.   r   r   r*   r   r+   r%   
kernel_opsr,   r   r   r   count_nn_conv2dK   s   r4   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_bn2dW   s   r6   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   r   )zOA no-op print function that takes any arguments without performing any actions.Nr   )r   r   r   r   r   
null_print   r
   r<   Fmodinputc              
   C   s  t | }t|| t}|rt}i }d}|jjD ]E}|d|j d|j d|j	 d|j
  d}g }	|ddd	 |j
D ]}
t|
|vrFq=||t|
  dd	 |	|t|
  q=|  |d
|jd j  |jd jg}|jdv rxd}n|jdkrt|jdd dddd }|tv rt| |	|g|j
R i |j}n|j|ft|< td| d n|jdkrt|j}|tv rt| |	|}nq|j|ft|< t| d nb|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r'td ntt| td|  |j d j  |jd j|t|j	< |durQ||7 }td| d|  |d qtt dkrwd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:	tensor_meta)outputplaceholdercall_functionat< >|z| is missingcall_methodz is missingcall_modulezmodule type:zweight_shape: Nonezweight_shape: z.weightzCurrent node's FLOPs: z, total FLOPs: zP================================================================================)pprintzMissing operators: )r8   r9   	propagater<   printgraphnodesoptargetnamer   strappendmetar2   splitreplacestrip	count_mapr   missing_mapsr:   get_submoduletype
isinstancezero_ops
state_dictr;   r   keysrL   )r=   r>   verbosegmfprintv_mapstotal_flopsnode
node_flopsr   argr   keymrL   r   r   r   
fx_profile   sr   (


("


 

rl   __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   )selfr>   r   r   r   forward   s   zMyOP.forwardN)__name__
__module____qualname__rp   r   r   r   r   rn      s    rn   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linear2rn   myop)ro   	__class__r   r   rw      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)r{   r|   r7   r}   )ro   xout1out2r   r   r   rp      s   
zMyModule.forward)rq   rr   rs   rw   rp   __classcell__r   r   r~   r   rt      s    rt      ru   )rb   )F)4loggingdistutils.versionr   rx   thtorch.nnry   __version__warningr	   r   r   r   vision.calc_funcr   r-   Moduler/   r0   Conv2dr4   BatchNorm2dr6   ReLUReLU6Dropout	MaxPool2d	AvgPool2dAdaptiveAvgPool2dr_   rz   rZ   kr[   torch.fxr8   torch.fx.passes.shape_propr9   utilsr:   r;   r<   Tensorrl   rq   rn   rt   netrandndatar   rN   r   r   r   r   <module>   sj   	

O