
    j;                        d dl mZ d dlmZ d dlmZ d dlZd dl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mZmZmZmZmZmZ ddZ dddZ! G d de
j"                  Z#dS )    )annotations)Path)AnyN)check_suffix)is_url   )AxeleraBackendCoreMLBackendDeepXBackendExecuTorchBackend
MNNBackendNCNNBackendONNXBackendONNXIMXBackendOpenVINOBackendPaddleBackendPyTorchBackendRKNNBackendTensorFlowBackendTensorRTBackendTorchScriptBackendTritonBackendnameslist | dictreturndict[int, str]c                   t          | t                    rt          t          |                     } t          | t                    r*d |                                 D             } t          |           }t          |                                           |k    r\t          | d|dz
   dt          |                                            dt          |                                            d          t          | d         t                    ra| d                             d          rFdd	lm}m} |                    |d
z            d         fd|                                 D             } | S )a8  Check class names and convert to dict format if needed.

    Args:
        names (list | dict): Class names as list or dict format.

    Returns:
        (dict): Class names in dict format with integer keys and string values.

    Raises:
        KeyError: If class indices are invalid for the dataset size.
    c                N    i | ]"\  }}t          |          t          |          #S  )intstr).0kvs      ]/var/www/html/Carbon-Document/venv/lib/python3.11/site-packages/ultralytics/nn/autobackend.py
<dictcomp>z%check_class_names.<locals>.<dictcomp>3   s*    :::DAqQQ:::    z(-class dataset requires class indices 0-r   z%, but you have invalid class indices -z defined in your dataset YAML.r   n0)ROOTYAMLzcfg/datasets/ImageNet.yamlmapc                (    i | ]\  }}||         S r   r   )r"   r#   r$   	names_maps      r%   r&   z%check_class_names.<locals>.<dictcomp>>   s#    ???AQ	!???r'   )
isinstancelistdict	enumerateitemslenmaxkeysKeyErrorminr!   
startswithultralytics.utilsr*   r+   load)r   nr*   r+   r.   s       @r%   check_class_namesr=   #   s    % 'Yu%%&&% @::EKKMM:::JJuzz||!! Y Ya!e Y Yuzz||$$Y Y'*5::<<'8'8Y Y Y   eAh$$ 	@q)<)<T)B)B 	@44444444		$)E"EFFuMI???????ELr'   datastr | Path | Nonec                    | rA	 ddl m} ddlm} |                     ||                     d         S # t
          $ r Y nw xY wd t          d          D             S )zLoad class names from a YAML file or return numerical class names.

    Args:
        data (str | Path, optional): Path to YAML file containing class names.

    Returns:
        (dict): Dictionary mapping class indices to class names.
    r   )r+   )
check_yamlr   c                    i | ]}|d | 	S classr   r"   is     r%   r&   z'default_class_names.<locals>.<dictcomp>S   s     ///qA{q{{///r'     )r:   r+   ultralytics.utils.checksrA   r;   	Exceptionrange)r>   r+   rA   s      r%   default_class_namesrK   B   s      	......;;;;;;99ZZ--..w77 	 	 	D	//E#JJ////s   /4 
A Ac                  P    e Zd ZdZi dedededededede	d	e
d
e
de
de
dedededededeeeedZ ej                    d ej        d          dddddfd? fd#            Zd@ fd(Z	 	 	 dAdBd1ZdCd4ZdDdEd9ZedFdGd<            ZdH fd=ZdH fd>Z  xZ!S )IAutoBackenda
  Handle dynamic backend selection for running inference using Ultralytics YOLO models.

    The AutoBackend class is designed to provide an abstraction layer for various inference engines. It supports a wide
    range of formats, each with specific naming conventions as outlined below:

        Supported Formats and Naming Conventions:
            | Format                | File Suffix       |
            | --------------------- | ----------------- |
            | PyTorch               | *.pt              |
            | TorchScript           | *.torchscript     |
            | ONNX Runtime          | *.onnx            |
            | ONNX OpenCV DNN       | *.onnx (dnn=True) |
            | OpenVINO              | *openvino_model/  |
            | CoreML                | *.mlpackage       |
            | TensorRT              | *.engine          |
            | TensorFlow SavedModel | *_saved_model/    |
            | TensorFlow GraphDef   | *.pb              |
            | TensorFlow Lite       | *.tflite          |
            | TensorFlow Edge TPU   | *_edgetpu.tflite  |
            | PaddlePaddle          | *_paddle_model/   |
            | MNN                   | *.mnn             |
            | NCNN                  | *_ncnn_model/     |
            | IMX                   | *_imx_model/      |
            | RKNN                  | *_rknn_model/     |
            | Triton Inference      | triton://model    |
            | ExecuTorch            | *.pte             |
            | Axelera AI            | *_axelera_model/  |
            | DeepX                 | *_deepx_model/    |

    Attributes:
        backend (BaseBackend): The loaded inference backend instance.
        format (str): The model format (e.g., 'pt', 'onnx', 'engine').
        model: The underlying model (nn.Module for PyTorch backends, backend instance otherwise).
        device (torch.device): The device (CPU or GPU) on which the model is loaded.
        task (str): The type of task the model performs (detect, segment, classify, pose).
        names (dict): A dictionary of class names that the model can detect.
        stride (int): The model stride, typically 32 for YOLO models.
        fp16 (bool): Whether the model uses half-precision (FP16) inference.
        nhwc (bool): Whether the model expects NHWC input format instead of NCHW.

    Methods:
        forward: Run inference on an input image.
        from_numpy: Convert NumPy arrays to tensors on the model device.
        warmup: Warm up the model with a dummy input.
        _model_type: Determine the model type from file path.

    Examples:
        >>> model = AutoBackend(model="yolo26n.pt", device="cuda")
        >>> results = model(img)
    pttorchscriptonnxdnnopenvinoenginecoremlsaved_modelpbtfliteedgetpupaddlemnnncnnimxrknntriton)
executorchaxeleradeepxz
yolo26n.ptcpuFNTmodelstr | torch.nn.Moduledevicetorch.deviceboolr>   r?   fp16fuseverbosec                    t                                                       t          |t          j                  rdn|                     ||          }||dv z  }t          |t          j                  rAt          j        	                                r#|j
        dk    r|dvrt          j        d          }||d}	|dk    rt          d          || j        vr*dd	lm}
 t          d
| d |
            d          d          |dk    r||	d<   ||	d<   n	|dv r||	d<    | j        |         |fi |	| _        |dv | _        || _        | j        j        st)          |          | j        _        t+          | j        j                  | j        _        dS )af  Initialize the AutoBackend for inference.

        Args:
            model (str | torch.nn.Module): Path to the model weights file or a module instance.
            device (torch.device): Device to run the model on.
            dnn (bool): Use OpenCV DNN module for ONNX inference.
            data (str | Path, optional): Path to the additional data.yaml file containing class names.
            fp16 (bool): Enable half-precision inference. Supported only on specific backends.
            fuse (bool): Fuse Conv2D + BatchNorm layers for optimization.
            verbose (bool): Enable verbose logging.
        rN   >   rN   rP   rS   r^   rR   rO   rb   >   rN   rP   rS   rY   rO   )re   rh   tfjsz7Ultralytics TF.js inference is not currently supported.r   export_formatszmodel='z9' is not a supported model format. Ultralytics supports: Formatz9
See https://docs.ultralytics.com/modes/predict for help.ri   rj   >   rV   rQ   rW   rX   rU   format>   rV   r]   rT   rW   rX   rU   N)super__init__r/   nnModule_model_typetorchre   cudais_availabletypeNotImplementedError_BACKEND_MAPultralytics.engine.exporterrn   	TypeErrorbackendnhwcrp   r   rK   r=   )selfrc   re   rQ   r>   rh   ri   rj   rp   backend_kwargsrn   	__class__s              r%   rr   zAutoBackend.__init__   s   , 	#E2955W4;K;KESV;W;W 	WWW vu|,,	)
''))	) u$$OOO\%((F %+D99V%&_```***BBBBBBL% L L)7)9)9()CL L L  
 T>>%)N6"(/N9%%HHH'-N8$0t(0II.IIZZ	 |! 	;!4T!:!:DL.t|/ABBr'   namer!   r   r   c                    d| j         v r*t          | j        |          rt          | j        |          S t	                                          |          S )aw  Delegate attribute access to the backend.

        This allows AutoBackend to transparently expose backend attributes
        without explicit copying.

        Args:
            name: Attribute name to look up.

        Returns:
            The attribute value from the backend.

        Raises:
            AttributeError: If the attribute is not found in backend.
        r~   )__dict__hasattrr~   getattrrq   __getattr__)r   r   r   s     r%   r   zAutoBackend.__getattr__   sM     %%'$,*E*E%4<...ww""4(((r'   imtorch.Tensoraugment	visualizeembedlist | Nonekwargs!torch.Tensor | list[torch.Tensor]c                     j         r|                    dddd          } j        j        r)|j        t
          j        k    r|                                }i } j        dk    r|||d|}  j        j	        |fi |}t          |t          t          f          rt           j                  dk    rf j        dk    st          |          dk    rH|d         j        d         |d         j        d         z
  d	z
  }d
 t#          |          D              _        t          |          dk    r                     |d                   n fd|D             S                      |          S )a:  Run inference on an AutoBackend model.

        Args:
            im (torch.Tensor): The image tensor to perform inference on.
            augment (bool): Whether to perform data augmentation during inference.
            visualize (bool): Whether to visualize the output predictions.
            embed (list, optional): A list of layer indices to return embeddings from.
            **kwargs (Any): Additional keyword arguments for model configuration.

        Returns:
            (torch.Tensor | list[torch.Tensor]): The raw output tensor(s) from the model.
        r         r   rN   )r   r   r   rG   segment   c                    i | ]}|d | 	S rC   r   rE   s     r%   r&   z'AutoBackend.forward.<locals>.<dictcomp>  s     @@@a@@@r'   c                :    g | ]}                     |          S r   )
from_numpy)r"   xr   s     r%   
<listcomp>z'AutoBackend.forward.<locals>.<listcomp>  s&    =\=\=\UVdooa>P>P=\=\=\r'   )r   permuter~   rh   dtyperv   float16halfrp   forwardr/   r0   tupler4   r   taskshaperJ   r   )	r   r   r   r   r   r   forward_kwargsyncs	   `        r%   r   zAutoBackend.forward   sf   ( 9 	(Aq!Q''B< 	U]!:!:B ;$)0ySXcc\bcN DL 66~66a$'' 	&4:#%%49	+A+ASVVq[[qTZ]QqTZ]2Q6@@eBii@@@
,/FFaKK4??1Q4(((=\=\=\=\Z[=\=\=\\??1%%%r'   r   np.ndarray | torch.Tensorc                    t          |t          j                  r,t          j        |                              | j                  n|S )zConvert a NumPy array to a torch tensor on the model device.

        Args:
            x (np.ndarray | torch.Tensor): Input array or tensor.

        Returns:
            (torch.Tensor): Tensor on `self.device`.
        )r/   npndarrayrv   tensortore   )r   r   s     r%   r   zAutoBackend.from_numpy  s9     3=Q
2K2KRu|A!!$+...QRRr'   r   r     r   imgsztuple[int, int, int, int]Nonec                   ddl m} | j        dv r| j        j        dk    s| j        dk    rt          j        || j        rt
          j        nt
          j	        | j        d}t          | j        dk    rdnd	          D ]_}|                     |           t          j        d	d
d| j                  }|ddddfxx         |d         z  cc<    ||           \dS dS dS )zWarm up the model by running forward pass(es) with a dummy input.

        Args:
            imgsz (tuple[int, int, int, int]): Dummy input shape in (batch, channels, height, width) format.
        r   )non_max_suppression>   rV   rN   rP   rS   r^   rU   rO   rb   r^   )r   re   rO   r   r   T      )re   Nr   )ultralytics.utils.nmsr   rp   re   ry   rv   emptyrh   r   floatrJ   r   rand)r   r   r   r   _warmup_boxess         r%   warmupzAutoBackend.warmup)  s    	>=====;```K%%)@)@e+S5::\`\ghhhB} < <11!DD 2 2R   $z!RDKHHHQQQU###uRy0#####L1111 a`)@)@2 2r'   path/to/model.ptpc                   ddl m}  |            d         }t          |           s%t          | t                    st          | |           t          |           j        fd|D             dxx                             d          z  cc<   dxx         d          z  cc<   t          fd	t           |            d
                   D             d          }|dk    rd}n^|dk    r|rd}nSt                    sDddlm}  ||           }t          |j                  rt          |j                  r|j        dv rd}|S )a  Take a path to a model file and return the model format string.

        Args:
            p (str): Path to the model file.
            dnn (bool): Whether to use OpenCV DNN module for ONNX inference.

        Returns:
            (str): Model format string (e.g., 'pt', 'onnx', 'engine', 'triton').

        Examples:
            >>> fmt = AutoBackend._model_type("path/to/model.onnx")
            >>> assert fmt == "onnx"
        r   rm   Suffixc                    g | ]}|v S r   r   )r"   sr   s     r%   r   z+AutoBackend._model_type.<locals>.<listcomp>P  s    '''qd'''r'      z.mlmodel   	   c              3  2   K   | ]\  }}|         |V  d S Nr   )r"   rF   ftypess      r%   	<genexpr>z*AutoBackend._model_type.<locals>.<genexpr>S  s3      YYTQPUVWPXYqYYYYYYr'   ArgumentNr(   rN   rP   rQ   )urlsplit>   grpchttpr^   )r|   rn   r   r/   r!   r   r   r   endswithnextr2   anyurllib.parser   rg   netlocpathscheme)	r   rQ   rn   sfrp   r   urlr   r   s	          @@r%   ru   zAutoBackend._model_type;  s    	?>>>>>^h'ayy 	 As!3!3 	 BAww|''''B'''aDMM*---aaL YYYYY~~/?/?
/K%L%LYYY[_``S==FFv#FFU 	"------(1++CCJ "DNN "szEU7U7U!r'   c                    t          | j        d          r8t          | j        j        d          r| j        j                                         t	                                                      S )z6Set the backend model to evaluation mode if supported.rc   eval)r   r~   rc   r   rq   )r   r   s    r%   r   zAutoBackend.eval`  sV    4<)) 	&gdl6H&.Q.Q 	&L##%%%ww||~~r'   c                n   t                                          |          } t          | j        d          r}t	          | j        j        t          j                  rY| j        j                            |           t          | j        j        	                                          j
        | j        _
        | S )a  Apply a function to backend.model parameters, buffers, and tensors.

        This method extends the functionality of the parent class's _apply method by additionally resetting the
        predictor and updating the device in the model's overrides. It's typically used for operations like moving the
        model to a different device or changing its precision.

        Args:
            fn (Callable): A function to be applied to the model's tensors. This is typically a method like to(), cpu(),
                cuda(), half(), or float().

        Returns:
            (AutoBackend): The model instance with the function applied and updated attributes.
        rc   )rq   _applyr   r~   r/   rc   rs   rt   r   
parametersre   )r   fnr   s     r%   r   zAutoBackend._applyf  s     ww~~b!!4<)) 	Oj9KRY.W.W 	OL%%b)))"&t|'9'D'D'F'F"G"G"NDLr'   )rc   rd   re   rf   rQ   rg   r>   r?   rh   rg   ri   rg   rj   rg   )r   r!   r   r   )FFN)r   r   r   rg   r   rg   r   r   r   r   r   r   )r   r   r   r   )r   )r   r   r   r   )r   F)r   r!   rQ   rg   r   r!   )r   rM   )"__name__
__module____qualname____doc__r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r	   r   r{   rv   no_gradre   rr   r   r   r   r   staticmethodru   r   r   __classcell__)r   s   @r%   rM   rM   V   sP       1 1fn) 	 	{	
 	O 	/ 	- 	( 	 	# 	$ 	- 	z 	 	~  	!" 	-#$ (!)  L. U]__ (4+u|E22"&?C ?C ?C ?C ?C ?C _?CB) ) ) ) ) ), !&& && && && &&P	S 	S 	S 	S2 2 2 2 2$ " " " " \"H              r'   rM   )r   r   r   r   r   )r>   r?   r   r   )$
__future__r   pathlibr   typingr   numpyr   rv   torch.nnrs   rH   r   ultralytics.utils.downloadsr   backendsr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r=   rK   rt   rM   r   r'   r%   <module>r      s   # " " " " "                        1 1 1 1 1 1 . . . . . .                                   (   >0 0 0 0 0(b b b b b") b b b b br'   