o
    .wi1                     @   s  d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z	 d dl
mZmZmZmZ d dlmZ d dlZd dlmZ d dlmZ eejd	d
Zeejdd ZdededefddZdededdfddZ	d5dedededeeef fddZ		d6dededededee deeeef fddZ	d5dedededeeef fddZ d7deded e!defd!d"Z"eddg d#d$fd%ed&ee#e$ef  d'ee#e$ef  d(ee d)eddfd*d+Z%d,e$d-e&d.e&defd/d0Z'efd1ed2edefd3d4Z(dS )8    N)MappingSequence)partial)perf_counter)AnyCallableOptionalno_type_check)Mock)Tensor)MetricDOCTEST_DOWNLOAD_TIMEOUTx   SKIP_SLOW_DOCTESTpredstargetreturnc                 C   s    |   |    kodkS   S )Nr   )numelr   r    r   Z/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/utilities/checks.py_check_for_empty_tensors    s    r   c                 C   s*   | j |j krtd| j  d|j  ddS )zHCheck that predictions and target have the same shape, else raise error.zEPredictions and targets are expected to have the same shape, but got z and .N)shapeRuntimeErrorr   r   r   r   _check_same_shape$   s
   r   Fallow_non_binary_targetc                 C   s:   | j |j kr
td|  r|  stdt| ||dS )a9  Check ``preds`` and ``target`` tensors are of the same shape and of the correct data type.

    Args:
        preds: either tensor with scores/logits
        target: tensor with ground true labels
        allow_non_binary_target: whether to allow target to contain non-binary values

    Raises:
        ValueError:
            If ``preds`` and ``target`` don't have the same shape, if they are empty
            or not of the correct ``dtypes``.

    Returns:
        preds: as torch.float32
        target: as torch.long if not floating point else torch.float32

    z.`preds` and `target` must be of the same shapez=`preds` and `target` must be non-empty and non-scalar tensorsr   )r   
ValueErrorr   size,_check_retrieval_target_and_prediction_typesr   r   r   r   r   r   "_check_retrieval_functional_inputs,   s
   r"   indexesignore_indexc                 C   s   | j |j ks|j |j krtd| jtjurtd|dur0||k}| | || || } }}|  r8|  s<tdt|||d\}}|   ||fS )a  Check ``indexes``, ``preds`` and ``target`` tensors are of the same shape and of the correct data type.

    Args:
        indexes: tensor with queries indexes
        preds: tensor with scores/logits
        target: tensor with ground true labels
        allow_non_binary_target: whether to allow target to contain non-binary values
        ignore_index: ignore predictions where targets are equal to this number

    Raises:
        ValueError:
            If ``preds`` and ``target`` don't have the same shape, if they are empty or not of the correct ``dtypes``.

    Returns:
        indexes: as ``torch.long``
        preds: as ``torch.float32``
        target: as ``torch.long``

    z9`indexes`, `preds` and `target` must be of the same shapez+`indexes` must be a tensor of long integersNzH`indexes`, `preds` and `target` must be non-empty and non-scalar tensorsr   )	r   r   dtypetorchlongr   r   r    flatten)r#   r   r   r   r$   valid_positionsr   r   r   _check_retrieval_inputsK   s   
r*   c                 C   s   |j tjtjtjfvrt|std|  std|s.| dks*| dk r.td| r6|	 n| }| 	 } | 
 |
 fS )a  Check ``preds`` and ``target`` tensors are of the same shape and of the correct data type.

    Args:
        preds: either tensor with scores/logits
        target: tensor with ground true labels
        allow_non_binary_target: whether to allow target to contain non-binary values

    Raises:
        ValueError:
            If ``preds`` and ``target`` don't have the same shape, if they are empty or not of the correct ``dtypes``.

    z9`target` must be a tensor of booleans, integers or floatsz"`preds` must be a tensor of floats   r   z%`target` must contain `binary` values)r%   r&   boolr'   intis_floating_pointr   maxminfloatr(   r!   r   r   r   r    |   s    r    ư>res1res2atolc                    sx   t  trtj |dS t  tr kS t  tr'tdd t D S t  tr8t fdd D S  kS )zFRecursively asserting that two results are within a certain tolerance.)r5   c                 s   s    | ]
\}}t ||V  qd S N_allclose_recursive).0r1r2r   r   r   	<genexpr>   s    z&_allclose_recursive.<locals>.<genexpr>c                 3   s"    | ]}t  | | V  qd S r6   r7   )r9   kr3   r4   r   r   r<      s     )	
isinstancer   r&   allclosestrr   allzipr   )r3   r4   r5   r   r>   r   r8      s   



r8   )
   d   i     metric_class	init_args
input_argsnum_update_to_comparerepsc              
   C   s*  |pi }|pi }G dd d| }G dd d| }|di |}|di |}d}	zt |d D ]}
|	t|di ||di |@ }	q/W n tyO   d}	Y nw | }z| }W n tye   d}	Y nw |	t||@ }	|	sutd d	S td
t||}t||gD ]5\}}t|D ],\}}t |D ]#}t	 }t |D ]	}
|di |}
qt	 }|| ||||f< |
  qqqt|d}t|d}t t|D ]3}td||  d|d|f  d|d|f d td||  d|d|f dd|d|f d q|d |d k  }td|  d d	S )a  Check if the new ``full_state_update`` property works as intended.

    This function checks if the property can safely be set to ``False`` which will for most metrics results in a
    speedup when using ``forward``.

    Args:
        metric_class: metric class object that should be checked
        init_args: dict containing arguments for initializing the metric class
        input_args: dict containing arguments to pass to ``forward``
        num_update_to_compare: if we successfully detect that the flag is safe to set to ``False``
            we will run some speedup test. This arg should be a list of integers for how many
            steps to compare over.
        reps: number of repetitions of speedup test

    Example (states in ``update`` are independent, save to set ``full_state_update=False``)
        >>> from torchmetrics.classification import MulticlassConfusionMatrix
        >>> check_forward_full_state_property(  # doctest: +SKIP
        ...     MulticlassConfusionMatrix,
        ...     init_args = {'num_classes': 3},
        ...     input_args = {'preds': torch.randint(3, (100,)), 'target': torch.randint(3, (100,))},
        ... )
        Full state for 10 steps took: ...
        Partial state for 10 steps took: ...
        Full state for 100 steps took: ...
        Partial state for 100 steps took: ...
        Full state for 1000 steps took: ...
        Partial state for 1000 steps took: ...
        Recommended setting `full_state_update=False`

    Example (states in ``update`` are dependent meaning that ``full_state_update=True``):
        >>> from torchmetrics.classification import MulticlassConfusionMatrix
        >>> class MyMetric(MulticlassConfusionMatrix):
        ...     def update(self, preds, target):
        ...         super().update(preds, target)
        ...         # by construction make future states dependent on prior states
        ...         if self.confmat.sum() > 20:
        ...             self.reset()
        >>> check_forward_full_state_property(
        ...     MyMetric,
        ...     init_args = {'num_classes': 3},
        ...     input_args = {'preds': torch.randint(3, (10,)), 'target': torch.randint(3, (10,))},
        ... )
        Recommended setting `full_state_update=True`

    c                   @      e Zd ZdZdS )z4check_forward_full_state_property.<locals>.FullStateTN__name__
__module____qualname__full_state_updater   r   r   r   	FullState       rR   c                   @   rL   )z4check_forward_full_state_property.<locals>.PartStateFNrM   r   r   r   r   	PartState   rS   rT   Tr   Fz,Recommended setting `full_state_update=True`N   zFull state for z steps took: z+-z0.3fzPartial state for r+   )r+   rV   )r   rV   z'Recommended setting `full_state_update=`r   )ranger8   r   computeprintr&   zeroslen	enumerater   resetmeanstditem)rG   rH   rI   rJ   rK   rR   rT   	fullstate	partstateequal_r3   r4   resimetricjtrstartendr_   r`   fasterr   r   r   !check_forward_full_state_property   sX   5$
	04ro   method_nameinstanceparentc                 C   s~   t || d}|du rdS t|dr|j}t|tr|j}nt|tr%|j}|du r+dS t || d}|du r9td|j	|j	kS )zRCheck if a method has been overridden by an instance compared to its parent class.NF__wrapped__z#The parent should define the method)
getattrhasattrrs   r?   r
   _mock_wrapsr   funcr   __code__)rp   rq   rr   instance_attrparent_attrr   r   r   is_overridden  s   


r{   fntimeoutc                 C   sr   t j| d}td| j d| dtjd |  || | s$dS td| j d| d	tjd |	  d
S )aY  Check if a certain function is taking too long to execute.

    Function will only be executed if running inside a doctest context. Currently, does not support Windows.

    Args:
        fn: function to check
        timeout: timeout for function

    Returns:
        Bool indicating if the function finished within the specified timeout

    )r   zTrying to run `z` for zs...)fileTrW   z` did not complete with z%, killing process and returning FalseF)
multiprocessingProcessrZ   rN   sysstderrrl   joinis_alivekill)r|   r}   procr   r   r   _try_proceed_with_timeout-  s   
r   )F)FN)r2   ))r   osr   collections.abcr   r   	functoolsr   timer   typingr   r   r   r	   unittest.mockr
   r&   r   torchmetrics.metricr   r-   environget_DOCTEST_DOWNLOAD_TIMEOUTr,   _SKIP_SLOW_DOCTESTr   r   tupler"   r*   r    r1   r8   dictrA   ro   objectr{   r   r   r   r   r   <module>   s   

#
4

 i