
    |hAy              	       P   d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
mZmZmZ ddlZddlZddlmZmZ ddlmZ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# dd	l$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/m0Z0 e"dz  ddddddddf	dZ1 G d d      Z2 G d d      Z3y)a  
Benchmark a YOLO model formats for speed and accuracy.

Usage:
    from ultralytics.utils.benchmarks import ProfileModels, benchmark
    ProfileModels(['yolo11n.yaml', 'yolov8s.yaml']).run()
    benchmark(model='yolo11n.pt', imgsz=160)

Format                  | `format=argument`         | Model
---                     | ---                       | ---
PyTorch                 | -                         | yolo11n.pt
TorchScript             | `torchscript`             | yolo11n.torchscript
ONNX                    | `onnx`                    | yolo11n.onnx
OpenVINO                | `openvino`                | yolo11n_openvino_model/
TensorRT                | `engine`                  | yolo11n.engine
CoreML                  | `coreml`                  | yolo11n.mlpackage
TensorFlow SavedModel   | `saved_model`             | yolo11n_saved_model/
TensorFlow GraphDef     | `pb`                      | yolo11n.pb
TensorFlow Lite         | `tflite`                  | yolo11n.tflite
TensorFlow Edge TPU     | `edgetpu`                 | yolo11n_edgetpu.tflite
TensorFlow.js           | `tfjs`                    | yolo11n_web_model/
PaddlePaddle            | `paddle`                  | yolo11n_paddle_model/
MNN                     | `mnn`                     | yolo11n.mnn
NCNN                    | `ncnn`                    | yolo11n_ncnn_model/
IMX                     | `imx`                     | yolo11n_imx_model/
RKNN                    | `rknn`                    | yolo11n_rknn_model/
    N)Path)ListOptionalTupleUnion)YOLO	YOLOWorld)	TASK2DATATASK2METRIC)export_formats)	ARM64ASSETS	IS_JETSONLINUXLOGGERMACOSTQDMWEIGHTS_DIRYAML)IS_PYTHON_3_13check_imgszcheck_requirements
check_yolois_rockchip)safe_download)	file_size)get_cpu_infoselect_devicez
yolo11n.pt   FcpuMbP? c	                 L  #$ t        |      }t        |t              r|d   |d   k(  sJ d       	 ddl$d$j                  j
                  _        d$j                  j
                  _        t        |d      }t        | t        t        f      rt        |       } t        | j                  j                  d	   d
d      }
|xs t        | j                     }t         | j                     }g }t#        j"                         }|j%                         }|r(t'        t)               d         }||v sJ d| d| d       t+        t)               j-                          D ]T  \  }}}}}}d\  }}	 |r||k7  r|dk(  r| j                  dk7  s<J d       |dk(  rt.        rt0        r$J d       |dv rt2        st.        rt0        rJ d       |dk(  rt4        rJ d       |dv rt        | t6              rJ d       |dk(  rOt        | t6              rJ d       | j                  dk7  sJ d       |
rJ d       t.        rt8        rt2        sJ d       |d k(  rt        | t6              rJ d!       |d"k(  rt        | t6              rJ d#       |d$k(  rJ|
rJ t        | t6              rJ d%       | j                  d&k(  sJ d'       d(| j;                         v sJ d)       |d*k(  r>t        | t6              rJ d+       |
rJ d,       t.        sJ d-       t=               rJ d.       d/|j>                  v r	|sJ d0       d1|j>                  v r	|sJ d2       |d3k(  r+| j@                  xs | jB                  xs | jD                  }| }nE | jF                  d`||||||dd4|	}t        || j                  5      }|t        |      v sJ d6       d7}| j                  d8k7  s|dk7  sJ d9       |d:vsJ d;       |dk7  stI        jJ                         d<k(  sJ d=       |d"k(  r	|
rJ d>       |jM                  tN        d?z  |||d@       |jQ                  |d|d|||ddAB	      }|jR                  |   |jT                  dC   }}tW        dD||z   z  dE      }|jY                  |dFtW        t[        |      d      tW        |dG      tW        |dE      |g       W te        |J       $jg                  |dKdLdM|dNdOgP      }| jD                  }t#        j"                         |z
  }dQ}dR| dS| dT| dU|dVdW| dX|ji                  d3       dX} ta        jj                  |        tm        dYdZd[d\]      5 }!|!jo                  |        ddd       |r@t        |tp              r0||   jr                  }"|#tu        #$fd^|"D              s
J d_#        |S # t\        $ rp}|rt?        |      t^        u sJ dH| dI|        ta        jb                  dH| dI|        |jY                  ||tW        t[        |      d      dddg       Y d}~d}~ww xY w# 1 sw Y   xY w)aa  
    Benchmark a YOLO model across different formats for speed and accuracy.

    Args:
        model (str | Path): Path to the model file or directory.
        data (str | None): Dataset to evaluate on, inherited from TASK2DATA if not passed.
        imgsz (int): Image size for the benchmark.
        half (bool): Use half-precision for the model if True.
        int8 (bool): Use int8-precision for the model if True.
        device (str): Device to run the benchmark on, either 'cpu' or 'cuda'.
        verbose (bool | float): If True or a float, assert benchmarks pass with given metric.
        eps (float): Epsilon value for divide by zero prevention.
        format (str): Export format for benchmarking. If not supplied all formats are benchmarked.
        **kwargs (Any): Additional keyword arguments for exporter.

    Returns:
        (pandas.DataFrame): A pandas DataFrame with benchmark results for each format, including file size, metric,
            and inference time.

    Examples:
        Benchmark a YOLO model with default settings:
        >>> from ultralytics.utils.benchmarks import benchmark
        >>> benchmark(model="yolo11n.pt", imgsz=640)
    r      z'benchmark() only supports square imgsz.N
   x   F)verboseend2endArgumentzExpected format to be one of z, but got 'z'.)   ❌Npbobbz.TensorFlow GraphDef not supported for OBB taskedgetpuz3Edge TPU export only supported on non-aarch64 Linux>   tfjscoremlzECoreML and TF.js export only supported on macOS and non-aarch64 Linuxr0   z#CoreML not supported on Python 3.13>   r,   r/   tfliter.   saved_modelz;YOLOWorldv2 TensorFlow exports not supported by onnx2tf yetpaddlez,YOLOWorldv2 Paddle exports not supported yetzBPaddle OBB bug https://github.com/PaddlePaddle/Paddle/issues/72024z3End-to-end models not supported by PaddlePaddle yetz3Windows and Jetson Paddle exports not supported yetmnnz)YOLOWorldv2 MNN exports not supported yetncnnz*YOLOWorldv2 NCNN exports not supported yetimxz%YOLOWorldv2 IMX exports not supporteddetectz%IMX only supported for detection taskC2fzIMX only supported for YOLOv8rknnz*YOLOWorldv2 RKNN exports not supported yetz+End-to-end models not supported by RKNN yetzRKNN only supported on Linuxz1RKNN Inference only supported on Rockchip devicesr    zinference not supported on CPUcudazinference not supported on GPU-)imgszformathalfint8datadevicer'   )taskzexport failedu   ❎posez(GraphDef Pose inference is not supported>   r/   r.   zinference not supportedDarwinz(inference only supported on macOS>=10.13zHEnd-to-end torch.topk operation is not supported for NCNN prediction yetzbus.jpg)r<   rA   r>   r'   r!   )	r@   batchr<   plotsrA   r>   r?   r'   conf	inference     u   ✅   zBenchmark failure for : )rA   Formatu	   Status❔z	Size (MB)zInference time (ms/im)FPS)columnsud   Benchmarks legend:  - ✅ Success  - ❎ Export passed but validation failed  - ❌️ Export failedz
Benchmarks complete for z on z
 at imgsz=z (z.2fzs)

zbenchmarks.logaignoreutf-8)errorsencodingc              3   L   K   | ]  }j                  |      s|kD    y wN)notna).0xfloorpds     [/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/utils/benchmarks.py	<genexpr>zbenchmark.<locals>.<genexpr>   s     =!1u9=s   $
$z%Benchmark failure: metric(s) < floor  );r   
isinstancelistpandasoptionsdisplaymax_columnswidthr   strr   r   getattrmodelr
   rB   r   timelower	frozensetr   zipvaluesr   r   r   r   r	   r   __str__r   typept_path	ckpt_path
model_nameexportplatformsystempredictr   valresults_dictspeedroundappendr   	ExceptionAssertionErrorr   errorr   	DataFramefillnainfoopenwritefloatarrayall)%ri   r@   r<   r>   r?   rA   r'   epsr=   kwargs
is_end2endkeyyt0
format_argformatsnamesuffixr    gpu_emojifilenameexported_modelresultsmetricrz   fpsedfdtlegendsfmetricsr[   r\   s%                                      @@r]   	benchmarkr   4   s   H E#-eT#:58uQxoFooD%'BJJ""BJJ651F%#t%U**2.	5AJ(9UZZ(D
ejj
!C
A	BJN,Z89 d$A'+V`Uaac"dd -0.2B2I2I2K-L SU)ffc3%xQ	UjF2 ~zzU*\,\\*9$Ua,aa*--u [5 !)P+PP)KK%eY7v9vv7!%eY7g9gg7zzU*p,pp*%\'\\~iEp;pp9%eY7d9dd7%eY7e9ee7%%~%eY7`9``7zzX-V/VV-/P1PP/%eY7e9ee7%T'TT~<<<u&=]*]](#<<<s$<<<s } ==OEOOOu?O?O!&'5<< T4X^hmqw "&hUZZ!@X.??.E ::'6T>e;ee9!44O6OO4X%):h)FrHrrF%q'qq~""6I#5U6X\fk"l %(( ) 
G $005w}}[7QEF,a0CHHdE58)<a#@%PQBRTYZ_abTcehij]SUl f	a(KcKcej!k	lBD	r	BsF
$TF$tfJugR3xtTZS[[]^`^g^ghk^l]mmopA
KKN	Hw	G 1	
 :gu-S'--=g==nAfglfm?nn=I/  	UAw.0V4J4&PRSTRU2VV0LL1$r!=>HHdE58)<a#@$dSTT		U s,   &V.L<V X	X'A%XXX#c                   ^    e Zd ZdZd ZdefdZddefdZede	fd       Z
d	ed
ededefdZy)RF100Benchmarka  
    Benchmark YOLO model performance across various formats for speed and accuracy.

    This class provides functionality to benchmark YOLO models on the RF100 dataset collection.

    Attributes:
        ds_names (List[str]): Names of datasets used for benchmarking.
        ds_cfg_list (List[Path]): List of paths to dataset configuration files.
        rf (Roboflow): Roboflow instance for accessing datasets.
        val_metrics (List[str]): Metrics used for validation.

    Methods:
        set_key: Set Roboflow API key for accessing datasets.
        parse_dataset: Parse dataset links and download datasets.
        fix_yaml: Fix train and validation paths in YAML files.
        evaluate: Evaluate model performance on validation results.
    c                 @    g | _         g | _        d| _        g d| _        y)zcInitialize the RF100Benchmark class for benchmarking YOLO model performance across various formats.Nclassimagestargets	precisionrecallmap50map95)ds_namesds_cfg_listrfval_metrics)selfs    r]   __init__zRF100Benchmark.__init__   s     b    api_keyc                 B    t        d       ddlm}  ||      | _        y)a%  
        Set Roboflow API key for processing.

        Args:
            api_key (str): The API key.

        Examples:
            Set the Roboflow API key for accessing datasets:
            >>> benchmark = RF100Benchmark()
            >>> benchmark.set_key("your_roboflow_api_key")
        roboflowr   )Roboflow)r   N)r   r   r   r   )r   r   r   s      r]   set_keyzRF100Benchmark.set_key   s     	:&%7+r   ds_link_txtc                    t         j                  j                  d      r*t        j                  d      t        j
                  d      fnt        j
                  d       t        j                  d       t        j
                  d       t        d       t        |d      5 }|D ]  }	 t        j                  d|j                               \  }}}}}| j                  j                  |       | d| }	t        |	      j                         sI| j                  j!                  |      j#                  |      j%                  |      j'                  d       nt)        j*                  d	       | j,                  j                  t        j.                         |	z  d
z          	 ddd       | j                  | j,                  fS # t0        $ r Y )w xY w# 1 sw Y   1xY w)a  
        Parse dataset links and download datasets.

        Args:
            ds_link_txt (str): Path to the file containing dataset links.

        Returns:
            ds_names (List[str]): List of dataset names.
            ds_cfg_list (List[Path]): List of paths to dataset configuration files.

        Examples:
            >>> benchmark = RF100Benchmark()
            >>> benchmark.set_key("api_key")
            >>> benchmark.parse_dataset("datasets_links.txt")
        zrf-100zultralytics-benchmarkszQhttps://github.com/ultralytics/assets/releases/download/v0.0.0/datasets_links.txtrS   rU   z/+r;   yolov8zDataset already downloaded.z	data.yamlN)ospathexistsshutilrmtreemkdirchdirr   r   resplitstripr   r|   r   r   	workspaceprojectversiondownloadr   r   r   cwdr}   )
r   r   fileliner   urlr   r   r   proj_versions
             r]   parse_datasetzRF100Benchmark.parse_dataset  sx     :<9Qx	 "((8"45WYW_W_`hWi

)*ij+0 	D 
:<((4:V7AsIwMM((1&-Yay#9L-446)))4<<WEMMgV__`hi$AB$$++DHHJ,E,ST	 }}d.... ! 	 	s1   !G(C6GG	G
GGGGr   c                 n    t        j                  |       }d|d<   d|d<   t        j                  ||        y)z8Fix the train and validation paths in a given YAML file.ztrain/imagestrainzvalid/imagesrx   N)r   loaddump)r   	yaml_datas     r]   fix_yamlzRF100Benchmark.fix_yaml&  s3     IIdO	+	')	%		)T"r   	yaml_pathval_log_fileeval_log_filelist_indc                 <   g d}t        j                  |      d   t        |d      5 }|j                         }g }|D ]x  t	        fd|D              rj                  d      t        t        d             D 	cg c]  }	|	j                  d       c}	|j                  fd	D               z 	 d
d
d
       d}
t              dkD  r+t        j                  d       |D ]  }|d   dk(  s|d   }
 n+t        j                  d       |D cg c]  }|d   	 c}d   }
t        |dd      5 }|j                  | j                  |    d|
 d       d
d
d
       t        |
      S c c}	w # 1 sw Y   xY wc c}w # 1 sw Y   t        |
      S xY w)a  
        Evaluate model performance on validation results.

        Args:
            yaml_path (str): Path to the YAML configuration file.
            val_log_file (str): Path to the validation log file.
            eval_log_file (str): Path to the evaluation log file.
            list_ind (int): Index of the current dataset in the list.

        Returns:
            (float): The mean average precision (mAP) value for the evaluated model.

        Examples:
            Evaluate a model on a specific dataset
            >>> benchmark = RF100Benchmark()
            >>> benchmark.evaluate("path/to/data.yaml", "path/to/val_log.txt", "path/to/eval_log.txt", 0)
        )u   🚀u   ⚠️u   💡r+   namesrS   r   c              3   &   K   | ]  }|v  
 y wrW   r_   )rY   symbolr   s     r]   r^   z*RF100Benchmark.evaluate.<locals>.<genexpr>F  s     A&v~As    c                     | dk7  S )Nr"   r_   )rx   s    r]   <lambda>z)RF100Benchmark.evaluate.<locals>.<lambda>I  s
    #) r   rP   c           	   3   ~   K   | ]4  }|v s|d k(  r)dvr%dvr!d   d   d   d   d   d   d	   d
 6 yw)r   z(AP)z(AR)r   r$   rJ      rK         r   Nr_   )rY   r   class_namesentriess     r]   r^   z*RF100Benchmark.evaluate.<locals>.<genexpr>K  sl      " K'AJ6;PU[cjUj ")")!*#*1:%,QZ")!*!(!("s   :=N        r$   zMultiple dicts foundr   r   r   zSingle dict foundr   rQ   rL   )r   r   r   	readlinesanyr   ra   filterr   extendlenr   r   r   r   r   )r   r   r   r   r   skip_symbolsr   lines
eval_linesr   map_vallstresr   r   r   s                @@@r]   evaluatezRF100Benchmark.evaluate.  s   $ 9ii	*73,1 	QKKMEJ ALAA**S/v&;WEF29:Q1774=:!! " %" 	, z?QKK./! +w<5(!'lG+ KK+,/9:s7|:1=G-w7 	?1GGt}}X./r'"=>	? W~7 ;	 	< ;	? W~s0   AE7E2 E7F:%F2E77F FN)zdatasets_links.txt)__name__
__module____qualname____doc__r   rg   r   r   staticmethodr   r   intr   r_   r   r]   r   r      sc    $c,s ,"#/ #/J #t # #7# 7S 7 7X[ 7r   r   c                      e Zd ZdZ	 	 	 	 	 	 	 d dee   dededededed	ed
e	e
ej                  ef      fdZd Zd Zedefd       Zed!dej&                  dedefd       Zd"dedefdZd"dedefdZdedeeef   deeef   deeeeef   fdZededeeef   deeef   deeeeef   fd       Zedee   fd       Zy)#ProfileModelsa/  
    ProfileModels class for profiling different models on ONNX and TensorRT.

    This class profiles the performance of different models, returning results such as model speed and FLOPs.

    Attributes:
        paths (List[str]): Paths of the models to profile.
        num_timed_runs (int): Number of timed runs for the profiling.
        num_warmup_runs (int): Number of warmup runs before profiling.
        min_time (float): Minimum number of seconds to profile for.
        imgsz (int): Image size used in the models.
        half (bool): Flag to indicate whether to use FP16 half-precision for TensorRT profiling.
        trt (bool): Flag to indicate whether to profile using TensorRT.
        device (torch.device): Device used for profiling.

    Methods:
        run: Profile YOLO models for speed and accuracy across various formats.
        get_files: Get all relevant model files.
        get_onnx_model_info: Extract metadata from an ONNX model.
        iterative_sigma_clipping: Apply sigma clipping to remove outliers.
        profile_tensorrt_model: Profile a TensorRT model.
        profile_onnx_model: Profile an ONNX model.
        generate_table_row: Generate a table row with model metrics.
        generate_results_dict: Generate a dictionary of profiling results.
        print_table: Print a formatted table of results.

    Examples:
        Profile models and print results
        >>> from ultralytics.utils.benchmarks import ProfileModels
        >>> profiler = ProfileModels(["yolo11n.yaml", "yolov8s.yaml"], imgsz=640)
        >>> profiler.run()
    Npathsnum_timed_runsnum_warmup_runsmin_timer<   r>   trtrA   c	                     || _         || _        || _        || _        || _        || _        || _        t        |t        j                        r|| _	        yt        |      | _	        y)a]  
        Initialize the ProfileModels class for profiling models.

        Args:
            paths (List[str]): List of paths of the models to be profiled.
            num_timed_runs (int): Number of timed runs for the profiling.
            num_warmup_runs (int): Number of warmup runs before the actual profiling starts.
            min_time (float): Minimum time in seconds for profiling a model.
            imgsz (int): Size of the image used during profiling.
            half (bool): Flag to indicate whether to use FP16 half-precision for TensorRT profiling.
            trt (bool): Flag to indicate whether to profile using TensorRT.
            device (torch.device | str | None): Device used for profiling. If None, it is determined automatically.

        Notes:
            FP16 'half' argument option removed for ONNX as slower on CPU than FP32.

        Examples:
            Initialize and profile models
            >>> from ultralytics.utils.benchmarks import ProfileModels
            >>> profiler = ProfileModels(["yolo11n.yaml", "yolov8s.yaml"], imgsz=640)
            >>> profiler.run()
        N)r   r   r   r   r<   r>   r  r`   torchrA   r   )	r   r   r   r   r   r<   r>   r  rA   s	            r]   r   zProfileModels.__init__  sX    B 
,. 
	 *65<< @fmTZF[r   c           	         | j                         }|st        j                  d       g S g }g }|D ]  }|j                  d      }|j                  dv rt        t        |            }|j                          |j                         }| j                  r]| j                  j                  dk7  rD|j                         s4|j                  d| j                  | j                  | j                  d      }|j                  d| j                  | j                  d	      }n%|j                  d
k(  r| j!                  |      }|}n| j#                  t        |            }	| j%                  t        |            }
|j'                  | j)                  |j*                  |
|	|             |j'                  | j-                  |j*                  |
|	|              | j/                  |       |S )a  
        Profile YOLO models for speed and accuracy across various formats including ONNX and TensorRT.

        Returns:
            (List[dict]): List of dictionaries containing profiling results for each model.

        Examples:
            Profile models and print results
            >>> from ultralytics.utils.benchmarks import ProfileModels
            >>> profiler = ProfileModels(["yolo11n.yaml", "yolov8s.yaml"])
            >>> results = profiler.run()
        z'No matching *.pt or *.onnx files found.z.engine   .pt.yml.yamlr    engineF)r=   r>   r<   rA   r'   onnx)r=   r<   rA   r'   z.onnx)	get_filesr   warningwith_suffixr   r   rg   fuser   r  rA   rp   is_filert   r>   r<   get_onnx_model_infoprofile_tensorrt_modelprofile_onnx_modelr|   generate_table_rowstemgenerate_results_dictprint_table)r   files
table_rowsoutputr   engine_fileri   
model_info	onnx_filet_enginet_onnxs              r]   runzProfileModels.run  s     NNDEI
 	_D**95K{{66SY

"ZZ\
88 0 0E 9+BUBUBW"',,'!YY"jj#{{ % #/ #K "LL!**;;!	 ) 	 '!55d;
 	223{3CDH,,S^<Fd55diiS]^_MM$44TYYR\]^;	_> 	$r   c                 >   g }| j                   D ]  }t        |      }|j                         rLg d}|j                  |D cg c]*  }t	        j                  t        ||z              D ]  }| , c}}       j|j                  dv r|j                  t        |             |j                  t	        j                  t        |                    t        j                  dt        |              t        |      D cg c]  }t        |       c}S c c}}w c c}w )z
        Return a list of paths for all relevant model files given by the user.

        Returns:
            (List[Path]): List of Path objects for the model files.
        )z*.ptz*.onnxz*.yamlr  zProfiling: )r   r   is_dirr   globrg   r   r|   r   r   sorted)r   r  r   
extensionsextr   s         r]   r  zProfileModels.get_files  s     JJ 	3D:D{{}9
j`sTYYsSWZ]S]E_`Td`d`a 88SY'TYYs4y12	3 	k&-12'-e}5tT
55 a 6s   /D?Dr  c                      y)zWExtract metadata from an ONNX model file including parameters, GFLOPs, and input shape.)r   r   r   r   r_   )r  s    r]   r  z!ProfileModels.get_onnx_model_info   s     "r   r@   sigma	max_itersc                    t        j                  |       } t        |      D ]b  }t        j                  |       t        j                  |       }}| | |||z  z
  kD  | |||z  z   k  z     }t        |      t        |       k(  r | S |} d | S )a  
        Apply iterative sigma clipping to data to remove outliers.

        Args:
            data (numpy.ndarray): Input data array.
            sigma (float): Number of standard deviations to use for clipping.
            max_iters (int): Maximum number of iterations for the clipping process.

        Returns:
            (numpy.ndarray): Clipped data array with outliers removed.
        )npr   rangemeanstdr   )r@   r'  r(  r   r,  r-  clipped_datas          r]   iterative_sigma_clippingz&ProfileModels.iterative_sigma_clipping  s     xx~y! 	 Arvvd|#Dus{(:!:tdUUX[FX?X YZL< CI-  D	  r   r  r   c                 z   | j                   rt        |      j                         syt        |      }t	        j
                  | j                  | j                  dft        j                        }d}t        d      D ]\  }t        j                         }t        | j                        D ]  } ||| j                  d        t        j                         |z
  }^ t        t        | j                  ||z   z  | j                  z        | j                  dz        }g }	t        t        |      |      D ]8  } ||| j                  d      }
|	j!                  |
d	   j"                  d
          : | j%                  t	        j&                  |	      dd      }	t	        j(                  |	      t	        j*                  |	      fS )a  
        Profile YOLO model performance with TensorRT, measuring average run time and standard deviation.

        Args:
            engine_file (str): Path to the TensorRT engine file.
            eps (float): Small epsilon value to prevent division by zero.

        Returns:
            mean_time (float): Mean inference time in milliseconds.
            std_time (float): Standard deviation of inference time in milliseconds.
        )r   r   r   )dtyper   F)r<   r'   2   descr   rH   rJ   r'  r(  )r  r   r  r   r*  zerosr<   uint8r+  rj   r   maxr{   r   r   r   r|   rz   r/  r   r,  r-  )r   r  r   ri   
input_dataelapsedr   
start_timenum_runs	run_timesr   s              r]   r  z$ProfileModels.profile_tensorrt_model  sv    xxtK088: [!XXtzz4::q9J
 q 	/AJ4//0 Cj

EBCiikJ.G		/ uT]]gm<t?S?SSTVZViVilnVno 	eHoK8 	<AJdjj%HGWQZ--k:;	< 11"((92EQZ[1\	wwy!266)#444r   c                    t        d       ddl}|j                         }|j                  j                  |_        d|_        |j                  ||dg      }|j                         d   }|j                  }t        d |j                  D               }|rdd	| j                  | j                  fn|j                  }	d
|v rt        j                  }
nbd|v rt        j                  }
nMd|v rt        j                   }
n8d|v rt        j"                  }
n#d|v rt        j$                  }
nt'        d|       t        j(                  j*                  |	 j-                  |
      }|j.                  }|j1                         d   j.                  }d}t3        d	      D ]\  }t5        j4                         }t3        | j6                        D ]  }|j9                  |g||i        t5        j4                         |z
  }^ t;        t=        | j>                  ||z   z  | j6                  z        | j@                        }g }tC        t3        |      |      D ]T  }t5        j4                         }|j9                  |g||i       |jE                  t5        j4                         |z
  dz         V | jG                  t        jH                  |      dd      }t        jJ                  |      t        jL                  |      fS )a  
        Profile an ONNX model, measuring average inference time and standard deviation across multiple runs.

        Args:
            onnx_file (str): Path to the ONNX model file.
            eps (float): Small epsilon value to prevent division by zero.

        Returns:
            mean_time (float): Mean inference time in milliseconds.
            std_time (float): Standard deviation of inference time in milliseconds.
        onnxruntimer   N   CPUExecutionProvider)	providersc              3   J   K   | ]  }t        |t              xr |d k\    yw)r   N)r`   r   )rY   dims     r]   r^   z3ProfileModels.profile_onnx_model.<locals>.<genexpr>Y  s#     Z*S#.;3!8;Zs   !#r$   r   float16r   doubleint64int32zUnsupported ONNX datatype r   r3  rI   rJ   r   r5  )'r   r?  SessionOptionsGraphOptimizationLevelORT_ENABLE_ALLgraph_optimization_levelintra_op_num_threadsInferenceSession
get_inputsrp   r   shaper<   r*  rE  float32float64rG  rH  
ValueErrorrandomrandastyper   get_outputsr+  rj   r   r  r8  r{   r   r   r   r|   r/  r   r,  r-  )r   r  r   ortsess_optionssessinput_tensor
input_typedynamicinput_shapeinput_dtyper9  
input_nameoutput_namer:  r   r;  r<  r=  s                      r]   r  z ProfileModels.profile_onnx_modelB  s    	=)! ))+030J0J0Y0Y-,-)##I|H^G_#`(+!&&
Z|GYGYZZZ8?q!TZZ4\EWEW 
"**K
"**K#**K
"((K
"((K9*FGGYY^^[188E
!&&
&&(+00 q 	/AJ4//0 B+Z(@ABiikJ.G		/ uT]]gm<t?S?SSTVZViVij 	eHoI6 	@AJHHk]Z$<=diikJ6$>?	@
 11"((92EQZ[1\	wwy!266)#444r   rs   r  r  r  c                     |\  }}}}d|dd| j                    d|d   dd|d   dd	|d   dd|d   dd	|d
z  dd|ddS )a  
        Generate a table row string with model performance metrics.

        Args:
            model_name (str): Name of the model.
            t_onnx (tuple): ONNX model inference time statistics (mean, std).
            t_engine (tuple): TensorRT engine inference time statistics (mean, std).
            model_info (tuple): Model information (layers, params, gradients, flops).

        Returns:
            (str): Formatted table row string with model metrics.
        z| 18sz | z | - | r   z.1f   ±r$   z ms | g    .Az |)r<   )	r   rs   r  r  r  layersparams	gradientsflopss	            r]   r  z ProfileModels.generate_table_row  s    & ,6(	5C DJJ<wvayoRq	RUV\]efg]hil\mmo{3vfsl3%7s5+RI	
r   c                 h    |\  }}}}| |t        |d      t        |d   d      t        |d   d      dS )a  
        Generate a dictionary of profiling results.

        Args:
            model_name (str): Name of the model.
            t_onnx (tuple): ONNX model inference time statistics (mean, std).
            t_engine (tuple): TensorRT engine inference time statistics (mean, std).
            model_info (tuple): Model information (layers, params, gradients, flops).

        Returns:
            (dict): Dictionary containing profiling results.
        r   r   )z
model/namezmodel/parameterszmodel/GFLOPszmodel/speed_ONNX(ms)zmodel/speed_TensorRT(ms))r{   )rs   r  r  r  re  rf  rg  rh  s           r]   r  z#ProfileModels.generate_results_dict  sG    & ,6(	5$ &!%O$)&)Q$7(-hqk1(=
 	
r   r  c                    t         j                  j                         rt         j                  j                  d      nd}ddddt	                dd| d	d
dg}ddj                  d |D              z   dz   }ddj                  d |D              z   dz   }t        j                  d|        t        j                  |       | D ]  }t        j                  |        y)z
        Print a formatted table of model profiling results.

        Args:
            table_rows (List[str]): List of formatted table row strings.
        r   GPUModelzsize<br><sup>(pixels)zmAP<sup>val<br>50-95zSpeed<br><sup>CPU (z) ONNX<br>(ms)zSpeed<br><sup>z TensorRT<br>(ms)zparams<br><sup>(M)zFLOPs<br><sup>(B)|c              3   (   K   | ]
  }d | d   yw)r   Nr_   rY   hs     r]   r^   z,ProfileModels.print_table.<locals>.<genexpr>  s     :Q!A3a:s   c              3   >   K   | ]  }d t        |      dz   z    yw)r;   rJ   N)r   ro  s     r]   r^   z,ProfileModels.print_table.<locals>.<genexpr>  s     "G!3#a&1*#5"Gs   z

N)r  r:   is_availableget_device_namer   joinr   r   )r  r   headersheader	separatorrows         r]   r  zProfileModels.print_table  s     05zz/F/F/Hejj((+e#"!,.!1@SE!23 
 sxx:':::S@#(("Gw"GGG#M	d6(O$I 	CKK	r   )d   r%   <   i  TTN)rJ   r   )r!   )r   r   r   r   r   rg   r   r   boolr   r   r  rA   r   r  r  r   r  r*  ndarrayr/  r  r  r   r  r  r  r_   r   r]   r   r   h  s   H "!59(\Cy(\ (\ 	(\
 (\ (\ (\ (\ u||S012(\T5n6* "s " " rzz % PS  *%5# %5E %5N?5C ?5e ?5B

 eUl#
 u%	

 %u45
2 

eUl#
 u%
 %u45	
 
6 S	  r   r   )4r   r"  r   ru   r   r   rj   pathlibr   typingr   r   r   r   numpyr*  
torch.cudar  ultralyticsr   r	   ultralytics.cfgr
   r   ultralytics.engine.exporterr   ultralytics.utilsr   r   r   r   r   r   r   r   r   ultralytics.utils.checksr   r   r   r   r   ultralytics.utils.downloadsr   ultralytics.utils.filesr   ultralytics.utils.torch_utilsr   r   r   r   r   r_   r   r]   <module>r     s   8  	  	    / /   ' 2 6 e e e m m 5 - E 
$	
		_DO Odh hr   