
    .hv}              	      H   d Z ddlm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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 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-m.Z. e dz  ddddddddf	dZ/ G d d      Z0 G d d      Z1y)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/
    )annotationsN)Path)YOLO	YOLOWorld)	TASK2DATATASK2METRIC)export_formats)
ARM64ASSETS
ASSETS_URL	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	                  % t        |      }t        |t              r|d   |d   k(  sJ d       	 ddl}
|
j                  j                  d       |
j                  j                  d       |
j                  j                  d       |
j                  j                  d       |
j                  j                  d       |
j                  j                  d       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       t1        t/               j3                          D ]T  \  }}}}}}d\  }}	 |r||k7  r|dk(  r| j$                  dk7  s<J d       |dk(  rt4        rt6        r$J d       |dv rt8        st4        rt6        rJ d       |dk(  rt:        rJ d       |dv rt        | t<              rJ d       |dk(  rOt        | t<              rJ d       | j$                  dk7  sJ d       |rJ d       t4        rt>        rt8        sJ d       |d k(  rt        | t<              rJ d!       |d"k(  rt        | t<              rJ d#       |d$k(  rJ|rJ t        | t<              rJ d%       | j$                  d&k(  sJ d'       d(| jA                         v sJ d)       |d*k(  r>t        | t<              rJ d+       |rJ d,       t4        sJ d-       tC               rJ d.       d/|jD                  v r	|sJ d0       d1|jD                  v r	|sJ d2       |d3k(  r+| jF                  xs | jH                  xs | jJ                  }| }nE | jL                  dc||||||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tO        jP                         d<k(  sJ d=       |d"k(  r	|rJ d>       |jS                  tT        d?z  |||d@       |jW                  |d|d|||ddAB	      }|jX                  |   |jZ                  dC   }}t]        dD||z   z  dE      }|j_                  |dFt]        ta        |      d      t]        |dG      t]        |dE      |g       W tk        |J       |
jm                  |dKdLdM|dNdOgdPQ      }|jo                  dRdS      }|jq                  |
js                         ju                  |
jv                        jy                  d3            }| jJ                  }t)        j(                         |z
  } dT}!dU| dV| dW| dX| dYdZ|! d[| d[}"tg        jz                  |"       t}        d\d]d^d_`      5 }#|#j                  |"       ddd       |rCt        |t              r3||   j                         }$|%ts        %fda|$D              s
J db%        |S # tb        $ rp}|rtE        |      td        u sJ dH| dI|        tg        jh                  dH| dI|        |j_                  ||t]        ta        |      d      dddg       Y d}~d}~ww xY w# 1 sw Y   xY w)da  
    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:
        (polars.DataFrame): A polars 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      Tz'benchmark() only supports square imgsz.NASCII_BORDERS_ONLY_CONDENSEDF)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 Linuxr-   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 YOLOv8n and YOLO11n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)r9   r>   r;   r%   r   )	r=   batchr9   plotsr>   r;   r<   r%   conf	inference     u   ✅   zBenchmark failure for : )r>   Formatu	   Status❔z	Size (MB)zInference time (ms/im)FPSrow)schemaorient )offsetud   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  T   K   | ]  }t        j                  |      r|kD   ! y wN)npisnan).0xfloors     Z/var/www/html/ai-service/venv/lib/python3.12/site-packages/ultralytics/utils/benchmarks.py	<genexpr>zbenchmark.<locals>.<genexpr>   s     ARXXa[1u9As   (
(z%Benchmark failure: metric(s) < floor  )Br   
isinstancelistpolarsConfigset_tbl_colsset_tbl_rowsset_tbl_width_charsset_tbl_hide_column_data_typesset_tbl_hide_dataframe_shapeset_tbl_formattingr   strr   r   getattrmodelr   r?   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with_row_indexwith_columnsallcastString	fill_nullinfoopenwritefloatto_numpy)&rm   r=   r9   r;   r<   r>   r%   epsr:   kwargspl
is_end2endkeyyt0
format_argformatsnamesuffixr   gpu_emojifilenameexported_modelresultsmetricr~   fpsedf
df_displaydtlegendsfmetricsr]   s&                                        @r^   	benchmarkr   5   s(   H E#-eT#:58uQxoFooDII2II2II!!"%II,,T2II**40II  !?@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-/]1]]/%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;SJbdi jsx	yB			3q		)Bryy!9!C!CC!HIJD	r	BsF
$TF$tfJugR3xtTZS[[]^h]iiklA
KKN	Hw	G 1	
 :gu-S'""$AgAArEjkpjqCrrA3  	UAw.0V4J4&PRSTRU2VV0LL1$r!=>HHdE58)<a#@$dSTT		U" s,   YL<Y7[	[!A%[[[c                  B    e Zd ZdZd ZddZd	d
dZedd       Zd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    c                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)api_keyN)r   r   r   r   )r   r   r   s      r^   set_keyzRF100Benchmark.set_key   s     	:&%7+r   c                   t         j                  j                  d      r*t        j                  d      t        j
                  d      fnt        j
                  d       t        j                  d       t        j
                  d       t        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        j0                         |	z  d
z          	 ddd       | j                  | j.                  fS # t2        $ 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-benchmarksz/datasets_links.txtrT   rV   z/+r8   yolov8zDataset already downloaded.z	data.yamlN)ospathexistsshutilrmtreemkdirchdirr   r   r   resplitstripr   r   r   r   	workspaceprojectversiondownloadr   r   r   cwdr   )
r   ds_link_txtfileliner   urlr   r   r   proj_versions
             r^   parse_datasetzRF100Benchmark.parse_dataset	  s     :<9Qx	 "((8"45WYW_W_`hWi

)*$789+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!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/imagesr|   N)r   loaddump)r   	yaml_datas     r^   fix_yamlzRF100Benchmark.fix_yaml.  s3     IIdO	+	')	%		)T"r   c                <   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(   namesrT   r   c              3  &   K   | ]  }|v  
 y wrX   r`   )r[   symbolr   s     r^   r_   z*RF100Benchmark.evaluate.<locals>.<genexpr>N  s     A&v~As   rO   c                    | dk7  S )Nr    r`   )r|   s    r^   <lambda>z)RF100Benchmark.evaluate.<locals>.<lambda>Q  s
    #) r   rQ   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"   rG      rH         r   Nr`   )r[   r   class_namesentriess     r^   r_   z*RF100Benchmark.evaluate.<locals>.<genexpr>S  sl      " K'AJ6;PU[cjUj ")")!*#*1:%,QZ")!*!(!("s   :=N        r"   zMultiple dicts foundr   r   r   zSingle dict foundr   rR   rI   )r   r   r   	readlinesanyr   rb   filterr   extendlenr   r   r   r   r   )r   	yaml_pathval_log_fileeval_log_filelist_indskip_symbolsr   lines
eval_linesr   map_vallstresr   r   r   s                @@@r^   evaluatezRF100Benchmark.evaluate6  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)r   rk   )zdatasets_links.txt)r   rk   )r   r   )r   rk   r   rk   r   rk   r   int)
__name__
__module____qualname____doc__r   r   r   staticmethodr   r   r`   r   r^   r   r      s1    $c,"#/J # #7r   r   c                      e Zd ZdZ	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd Zd Zedd       Zeddd       Z	dddZ
ed	        Zddd
Z	 	 	 	 	 	 	 	 ddZe	 	 	 	 	 	 	 	 dd       Zed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()
    Nc	                    || _         || _        || _        || _        || _        || _        || _        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)pathsnum_timed_runsnum_warmup_runsmin_timer9   r;   trtra   torchr>   r   )	r   r  r  r	  r
  r9   r;   r  r>   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;   r9   r>   r%   onnx)r:   r9   r>   r%   z.onnx)	get_filesr   warningwith_suffixr   r   rk   fuser   r  r>   rt   is_filerx   r;   r9   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_filerm   
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   globrk   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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   c                   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 (np.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:
            (np.ndarray): Clipped data array with outliers removed.
        )rY   arrayrangemeanstdr   )r=   sigma	max_itersr   r3  r4  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   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)r9   r%   2   descr   rE   rG   r5  r6  )r  r   r  r   rY   zerosr9   uint8r2  rn   r	  maxr   r
  r  r   r   r~   r8  r1  r3  r4  )r   r#  r   rm   
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               S )z<Check whether the tensor shape in the ONNX model is dynamic.c              3  J   K   | ]  }t        |t              xr |d k\    yw)r   N)ra   r   )r[   dims     r^   r_   z.ProfileModels.check_dynamic.<locals>.<genexpr>M  s#     QSz#s+8q8Qs   !#)r   )tensor_shapes    r^   check_dynamiczProfileModels.check_dynamicJ  s     QLQQQQr   c                   t        dg       ddl}|j                         }|j                  j                  |_        d|_        |j                  ||dg      }t               }|j                         D ]  }|j                  }| j                  |j                        rt        |j                        dk7  rC| j                  |j                  dd       r%t        d	|j                   d
|j                         t        |j                        dk(  rdd| j                   | j                   fndg|j                  dd }	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.                  j0                  |	 j3                  |
      }|j                  }|j5                  ||i        |j7                         d   j                  }d}t9        d      D ]Z  }t;        j:                         }t9        | j<                        D ]  }|j?                  |g|        t;        j:                         |z
  }\ tA        tC        | jD                  ||z   z  | j<                  z        | jF                        }g }tI        t9        |      |      D ]R  }t;        j:                         }|j?                  |g|       |jK                  t;        j:                         |z
  dz         T | jM                  t#        jN                  |      dd      }t#        jP                  |      t#        jR                  |      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.
        )onnxruntimezonnxruntime-gpur   N   CPUExecutionProvider)	providersrH   r"   zUnsupported dynamic shape z of r   float16r   doubleint64int32zUnsupported ONNX datatype r   r<  rF   rG   r   r>  )*r   rM  SessionOptionsGraphOptimizationLevelORT_ENABLE_ALLgraph_optimization_levelintra_op_num_threadsInferenceSessiondict
get_inputsrt   rK  shaper   
ValueErrorr   r9   rY   rQ  float32float64rS  rT  randomrandastypeupdateget_outputsr2  rn   r	  r(  rA  r   r
  r  r   r   r8  r1  r3  r4  )r   r%  r   ortsess_optionssessinput_data_dictinput_tensor
input_typeinput_shapeinput_dtyperB  
input_nameoutput_namerC  r   rD  rE  rF  s                      r^   r  z ProfileModels.profile_onnx_modelO  s/    	>?@! ))+030J0J0Y0Y-,-)##I|H^G_#`& OO- 	=L%**J!!,"4"45|))*a/D4F4F|GYGYZ[Z\G]4^$'A,BTBTAUUYZfZkZkYl%mnn69,:L:L6MQR6RQ4::tzz2YZXt]i]o]opqpr]sXt  +00 J& jjJ& jjZ' jjJ& hhJ& hh #=j\!JKK5<<[IJ%**J""J
#;<7	=: &&(+00 q 	/AJ4//0 9+89iikJ.G		/ uT]]gm<t?S?SSTVZViVij 	eHoI6 	@AJHHk]O4diikJ6$>?	@
 11"((92EQZ[1\	wwy!266)#444r   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 |)r9   )	r   rw   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   )rw   r'  r&  r$  rs  rt  ru  rv  s           r^   r  z#ProfileModels.generate_results_dict  sG    & ,6(	5$ &!%O$)&)Q$7(-hqk1(=
 	
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)rO   Nr`   r[   hs     r^   r_   z,ProfileModels.print_table.<locals>.<genexpr>  s     :Q!A3a:s   c              3  >   K   | ]  }d t        |      dz   z    yw)r8   rG   N)r   r}  s     r^   r_   z,ProfileModels.print_table.<locals>.<genexpr>  s     "G!3#a&1*#5"Gs   z

N)r  r7   is_availableget_device_namer   joinr   r   )r!  r   headersheader	separatorrL   s         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   
   <   i  TTN)r  	list[str]r  r   r	  r   r
  r   r9   r   r;   boolr  r  r>   ztorch.device | str | None)r%  rk   )rG   r   )r=   z
np.ndarrayr5  r   r6  r   )r   )r#  rk   r   r   )r%  rk   r   r   )rw   rk   r'  tuple[float, float]r&  r  r$  z!tuple[float, float, float, float])r!  r  )r   r   r  r  r   r(  r  r  r  r8  r  rK  r  r  r  r  r`   r   r^   r  r  p  sI   H "!,0(\(\ (\ 	(\
 (\ (\ (\ (\ *(\T5n6* " "  *%5N R RH5T

 $
 &	

 6
2 

#
 &
 6	
 
6  r   r  )2r  
__future__r   r+  r   ry   r   r   rn   pathlibr   numpyrY   
torch.cudar  ultralyticsr   r   ultralytics.cfgr   r   ultralytics.engine.exporterr	   ultralytics.utilsr
   r   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 q q q m m 5 - E 
$	
		fRO Odv vr   