a
    d                     @   sz   d dl mZmZ d dlmZmZm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 G dd	 d	eeZdS )
    )ABCabstractmethod)AnyListOptionalN)Tensortensor)Metric)_check_retrieval_inputs)_flexible_bincountdim_zero_catc                       s   e Zd ZU dZdZeed< dZeed< dZeed< e	e
 ed< e	e
 ed< e	e
 ed	< deee edd fddZe
e
e
ddddZe
dddZee
e
e
dddZ  ZS )RetrievalMetrica  Works with binary target data. Accepts float predictions from a model output.

    As input to ``forward`` and ``update`` the metric accepts the following input:

    - ``preds`` (:class:`~torch.Tensor`): A float tensor of shape ``(N, ...)``
    - ``target`` (:class:`~torch.Tensor`): A long or bool tensor of shape ``(N, ...)``
    - ``indexes`` (:class:`~torch.Tensor`): A long tensor of shape ``(N, ...)`` which indicate to which query a
      prediction belongs

    .. note:: ``indexes``, ``preds`` and ``target`` must have the same dimension and will be flatten
    to single dimension once provided.

    .. note::
        Predictions will be first grouped by ``indexes`` and then the real metric, defined by overriding
        the `_metric` method, will be computed as the mean of the scores over each query.

    As output to ``forward`` and ``compute`` the metric returns the following output:

    - ``metric`` (:class:`~torch.Tensor`): A tensor as computed by ``_metric`` if the number of positive targets is
      at least 1, otherwise behave as specified by ``self.empty_target_action``.

    Args:
        empty_target_action:
            Specify what to do with queries that do not have at least a positive
            or negative (depend on metric) target. Choose from:

            - ``'neg'``: those queries count as ``0.0`` (default)
            - ``'pos'``: those queries count as ``1.0``
            - ``'skip'``: skip those queries; if all queries are skipped, ``0.0`` is returned
            - ``'error'``: raise a ``ValueError``

        ignore_index:
            Ignore predictions where the target is equal to this number.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Raises:
        ValueError:
            If ``empty_target_action`` is not one of ``error``, ``skip``, ``neg`` or ``pos``.
        ValueError:
            If ``ignore_index`` is not `None` or an integer.

    Fis_differentiableThigher_is_betterfull_state_updateindexespredstargetnegN)empty_target_actionignore_indexkwargsreturnc                    s   t  jf i | d| _d}||vr4td| d|| _|d urTt|tsTtd|| _| jdg d d | jdg d d | jd	g d d d S )
NF)errorskipr   posz7Argument `empty_target_action` received a wrong value `z`.z3Argument `ignore_index` must be an integer or None.r   )defaultZdist_reduce_fxr   r   )	super__init__allow_non_binary_target
ValueErrorr   
isinstanceintr   Z	add_state)selfr   r   r   Zempty_target_action_options	__class__ d/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/retrieval/base.pyr   M   s    zRetrievalMetric.__init__)r   r   r   r   c                 C   sT   |du rt dt|||| j| jd\}}}| j| | j| | j| dS )zGCheck shape, check and convert dtypes, flatten and add to accumulators.Nz!Argument `indexes` cannot be None)r   r   )r    r
   r   r   r   appendr   r   )r#   r   r   r   r&   r&   r'   updatee   s    zRetrievalMetric.update)r   c                    s  t | j}t | j t | j}t|\}} |  || }t|  	 }g }t
tj |ddtj||ddD ]h\}}| s| jdkrtd| jdkr|td q| jdkr|td qv|| || qv|rt fd	d
|D  S td S )a  First concat state ``indexes``, ``preds`` and ``target`` since they were stored as lists.

        After that, compute list of groups that will help in keeping together predictions about the same query. Finally,
        for each group compute the ``_metric`` if the number of positive targets is at least 1, otherwise behave as
        specified by ``self.empty_target_action``.

        r   )Zdimr   zC`compute` method was provided with a query with no positive target.r   g      ?r   g        c                    s   g | ]}|  qS r&   )to).0xr   r&   r'   
<listcomp>       z+RetrievalMetric.compute.<locals>.<listcomp>)r   r   r   r   torchsortr   detachcputolistzipsplitsumr   r    r(   r   _metricstackmeanr*   )r#   r   r   indicesZsplit_sizesresZ
mini_predsZmini_targetr&   r-   r'   computer   s(    





zRetrievalMetric.compute)r   r   r   c                 C   s   dS )zCompute a metric over a predictions and target of a single group.

        This method should be overridden by subclasses.

        Nr&   )r#   r   r   r&   r&   r'   r8      s    zRetrievalMetric._metric)r   N)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   r   strr   r"   r   r   r)   r=   r   r8   __classcell__r&   r&   r$   r'   r      s&   
+  #r   )abcr   r   typingr   r   r   r0   r   r   Ztorchmetricsr	   Ztorchmetrics.utilities.checksr
   Ztorchmetrics.utilities.datar   r   r   r&   r&   r&   r'   <module>   s   