o
    ϯiC                     @   s:  U d dl mZ d dlmZmZmZmZmZmZm	Z	 d dl
mZ d dlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZ eeeeeeeeedededed ded d	edd ed d	d
Zeeef ed< G dd deZ	ddejdeedf deeeef  deeee f ee f fddZ!dS )    )defaultdict)AnyCounterDefaultDictDictOptionalTupleUnionN)Tensor   )JitModelAnalysis)
addmm_flop_jitbatchnorm_flop_jitbmm_flop_jitconv_flop_jiteinsum_flop_jitelementwise_flop_counterHandlelinear_flop_jitmatmul_flop_jitnorm_flop_counter      )zaten::addmmz	aten::bmmzaten::_convolutionzaten::einsumzaten::matmulzaten::mmzaten::linearzaten::batch_normzaten::group_normzaten::layer_normzaten::instance_normzaten::upsample_nearest2dzaten::upsample_bilinear2dzaten::adaptive_avg_pool2dzaten::grid_sampler_DEFAULT_SUPPORTED_OPSc                       sJ   e Zd ZdZdejdeeeedf f ddf fddZ	e
j	je	_  ZS )	FlopCountAnalysisa  
    Provides access to per-submodule model flop count obtained by
    tracing a model with pytorch's jit tracing functionality. By default,
    comes with standard flop counters for a few common operators.
    Note that:

        1. Flop is not a well-defined concept. We just produce our best estimate.
        2. We count one fused multiply-add as one flop.

    Handles for additional operators may be added, or the default ones
    overwritten, using the ``.set_op_handle(name, func)`` method.
    See the method documentation for details.

    Flop counts can be obtained as:

    * ``.total(module_name="")``: total flop count for the module
    * ``.by_operator(module_name="")``: flop counts for the module, as a Counter
      over different operator types
    * ``.by_module()``: Counter of flop counts for all submodules
    * ``.by_module_and_operator()``: dictionary indexed by descendant of Counters
      over different operator types

    An operator is treated as within a module if it is executed inside the
    module's ``__call__`` method. Note that this does not include calls to
    other methods of the module or explicit calls to ``module.forward(...)``.

    Example usage:

    >>> import torch.nn as nn
    >>> import torch
    >>> class TestModel(nn.Module):
    ...    def __init__(self):
    ...        super().__init__()
    ...        self.fc = nn.Linear(in_features=1000, out_features=10)
    ...        self.conv = nn.Conv2d(
    ...            in_channels=3, out_channels=10, kernel_size=1
    ...        )
    ...        self.act = nn.ReLU()
    ...    def forward(self, x):
    ...        return self.fc(self.act(self.conv(x)).flatten(1))

    >>> model = TestModel()
    >>> inputs = (torch.randn((1,3,10,10)),)
    >>> flops = FlopCountAnalysis(model, inputs)
    >>> flops.total()
    13000
    >>> flops.total("fc")
    10000
    >>> flops.by_operator()
    Counter({"addmm" : 10000, "conv" : 3000})
    >>> flops.by_module()
    Counter({"" : 13000, "fc" : 10000, "conv" : 3000, "act" : 0})
    >>> flops.by_module_and_operator()
    {"" : Counter({"addmm" : 10000, "conv" : 3000}),
     "fc" : Counter({"addmm" : 10000}),
     "conv" : Counter({"conv" : 3000}),
     "act" : Counter()
    }
    modelinputs.returnNc                    s$   t  j||d | jdi t d S )N)r   r    )super__init__set_op_handler   )selfr   r   	__class__r   H/home/ubuntu/.local/lib/python3.10/site-packages/fvcore/nn/flop_count.pyr    l   s   zFlopCountAnalysis.__init__)__name__
__module____qualname____doc__nnModuler	   r
   r   r    r   __classcell__r   r   r#   r%   r   /   s    <r   r   r   .supported_opsr   c                 C   sX   |du ri }t | |jdi |}tt}|  D ]
\}}|d ||< q|| fS )aR  
    Given a model and an input to the model, compute the per-operator Gflops
    of the given model.

    Args:
        model (nn.Module): The model to compute flop counts.
        inputs (tuple): Inputs that are passed to `model` to count flops.
            Inputs need to be in a tuple.
        supported_ops (dict(str,Callable) or None) : provide additional
            handlers for extra ops, or overwrite the existing handlers for
            convolution and matmul and einsum. The key is operator name and the value
            is a function that takes (inputs, outputs) of the op. We count
            one Multiply-Add as one FLOP.

    Returns:
        tuple[defaultdict, Counter]: A dictionary that records the number of
            gflops for each operation and a Counter that records the number of
            unsupported operations.
    Ng    eAr   )r   r!   r   floatby_operatoritemsunsupported_ops)r   r   r-   flop_counter
giga_flopsopflopr   r   r%   
flop_countw   s   r6   )N)"collectionsr   typingr   r   r   r   r   r   r	   torch.nnr*   torchr
   jit_analysisr   jit_handlesr   r   r   r   r   r   r   r   r   r   r   str__annotations__r   r+   r.   r6   r   r   r   r%   <module>   sB   $0K
