
    &`i(                         d dl mZ d dlmZ d dlmZmZmZmZm	Z	 d dl
mZmZ d dlmZ d dlmZmZ d dlmZ  e            \  ZZ e            \  ZZZe G d d	e                      Zed
             ZdS )    )deque)chain)AnyDictListOptionalUnion)try_import_tftry_import_torch)	StatsBase)batch_values_to_cpu
safe_isnan)DeveloperAPIc            
           e Zd ZdZdZ	 	 d#deee         ef         de	eee
f                  f fdZdeeef         f fdZdeeef         ddf fd	Zd
 ZdefdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdeddfdZded          ddfdZ	 d$dededeeee         f         fdZ d%dedeed f         fd Z!defd!Z"e#d#deeef         fd"            Z$ xZ%S )&PercentilesStatszTA Stats object that tracks percentiles of a series of singular values (not vectors).percentilesNwindowc                      t                      j        |i | || _        g | _        |                     g            |g d}n't          |t                    r|}nt          d          || _        dS )a  Initializes a PercentilesStats instance.

        Percentiles are computed over the last `window` values across all parallel components.
        Example: If we have 10 parallel components, and each component tracks 1,000 values, we will track the last 10,000 values across all components.
        Be careful to not track too many values because computing percentiles is O(n*log(n)) where n is the window size.
        See https://github.com/ray-project/ray/pull/52963 for more details.

        Args:
            percentiles: The percentiles to track.
                If None, track the default percentiles [0, 50, 75, 90, 95, 99, 100].
                If a list, track the given percentiles.
        N)r   2   K   Z   _   c   d   z$`percentiles` must be a list or None)	super__init___windowvalues_set_values
isinstancelist
ValueError_percentiles)selfr   r   argskwargs	__class__s        }/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/rllib/utils/metrics/stats/percentiles.pyr   zPercentilesStats.__init__   s    & 	$)&)))46666KKT** 	E%KKCDDD'    returnc                     t                                                      }| j        |d<   | j        |d<   | j        |d<   |S Nr   r   r   )r   	get_stater   r   r#   r$   stater'   s     r(   r-   zPercentilesStats.get_state7   s@    !!##+h,h#0mr)   r/   c                     t                                          |           |                     |d                    |d         | _        |d         | _        d S r,   )r   	set_stater   r   r#   r.   s     r(   r1   zPercentilesStats.set_state>   sQ    %   x)))X!-0r)   c                 j    | j         r$| j        rt          || j                   | _        d S || _        d S )N)maxlen)r   is_leafr   r   )r$   
new_valuess     r(   r   zPercentilesStats._set_valuesD   s>     < 	%DL 	%
4<@@@DKKK %DKKKr)   c                 *    t          | j                  S )z/Returns the length of the internal values list.)lenr   r$   s    r(   __len__zPercentilesStats.__len__N   s    4;r)   c                      t          d          )NzNCannot convert to float because percentiles are not reduced to a single value.r"   r8   s    r(   	__float__zPercentilesStats.__float__R   s    \
 
 	
r)   c                 0    |                      d           d S )N__eq___comp_errorr$   others     r(   r>   zPercentilesStats.__eq__W       """""r)   c                 0    |                      d           d S )N__le__r?   rA   s     r(   rE   zPercentilesStats.__le__Z   rC   r)   c                 0    |                      d           d S )N__ge__r?   rA   s     r(   rG   zPercentilesStats.__ge__]   rC   r)   c                 0    |                      d           d S )N__lt__r?   rA   s     r(   rI   zPercentilesStats.__lt__`   rC   r)   c                 0    |                      d           d S )N__gt__r?   rA   s     r(   rK   zPercentilesStats.__gt__c   rC   r)   c                 0    |                      d           d S )N__add__r?   rA   s     r(   rM   zPercentilesStats.__add__f       #####r)   c                 0    |                      d           d S )N__sub__r?   rA   s     r(   rP   zPercentilesStats.__sub__i   rN   r)   c                 0    |                      d           d S )N__mul__r?   rA   s     r(   rR   zPercentilesStats.__mul__l   rN   r)   c                     t                      N)NotImplementedError)r$   comps     r(   r@   zPercentilesStats._comp_erroro   s    !###r)   c                      t          d          )NzWCannot format percentiles object because percentiles are not reduced to a single value.r;   )r$   fmts     r(   
__format__zPercentilesStats.__format__r   s    e
 
 	
r)   valuec                 J   t           r.t                               |          r|                                }t          |          rt	          d          t
          r.t          |t
          j                  r|                                }| j	        
                    |           dS )a  Pushes a value into this Stats object.

        Args:
            value: The value to be pushed. Can be of any type.
                PyTorch GPU tensors are kept on GPU until reduce() or peek().
                TensorFlow tensors are moved to CPU immediately.
        z.NaN values are not allowed in PercentilesStatsN)tf	is_tensornumpyr   r"   torchr    Tensordetachr   append)r$   rZ   s     r(   pushzPercentilesStats.pushw   s      	"",,u%% 	"KKMMEe 	OMNNN 	#Zu|44 	#LLNNE5!!!!!r)   incoming_statsc                 t     j         r
J d            t           fd|D                       s
J d            t           fd|D                       s
J d            d |D             }t          t          j        |                    }t           j                  |z   }| _         j         s	| _        dS dS )av  Merges PercentilesStats objects.

        This method assumes that the incoming stats have the same percentiles and window size.
        It will append the incoming values to the existing values.

        Args:
            incoming_stats: The list of PercentilesStats objects to merge.

        Returns:
            None. The merge operation modifies self in place.
        zSPercentilesStats should only be merged at aggregation stages (root or intermediate)c              3   8   K   | ]}|j         j         k    V  d S rT   )r#   .0sr$   s     r(   	<genexpr>z)PercentilesStats.merge.<locals>.<genexpr>   s>       
 
45ANd//
 
 
 
 
 
r)   zDAll incoming PercentilesStats objects must have the same percentilesc              3   8   K   | ]}|j         j         k    V  d S rT   )r   rg   s     r(   rj   z)PercentilesStats.merge.<locals>.<genexpr>   s=       
 
*+AI%
 
 
 
 
 
r)   zDAll incoming PercentilesStats objects must have the same window sizec                     g | ]	}|j         
S  )r   )rh   ri   s     r(   
<listcomp>z*PercentilesStats.merge.<locals>.<listcomp>   s    7771ah777r)   N)r4   allr!   r   from_iterabler   latest_merged)r$   rd   r5   
all_valuess   `   r(   mergezPercentilesStats.merge   s<    	a 	a`	a 	a 
 
 
 
9G
 
 
 
 
 	R 	RQ	R 	R 
  
 
 
 
/=
 
 
 
 
 	R 	RQ	R 	R 
 87777
%-j99::
$+&&3
  | 	,!+D	, 	,r)   TFcompilelatest_merged_onlyc                    |r| j         rt          d          |r3| j        |rd | j        D             S g S | j        }t	          |          }nt	          | j                  }|                                 |rt          || j                  S |S )a  Returns the result of reducing the internal values list.

        Note that this method does NOT alter the internal values list in this process.
        Thus, users can call this method to get an accurate look at the reduced value(s)
        given the current internal values list.

        Args:
            compile: If True, the result is compiled into the percentiles list.
            latest_merged_only: If True, only considers the latest merged values.
                This parameter only works on aggregation stats (root or intermediate nodes).
                When enabled, peek() will only use the values from the most recent merge operation.

        Returns:
            The result of reducing the internal values list on CPU.
        zQlatest_merged_only can only be used on aggregation stats objects (is_leaf=False).Nc                     i | ]}|d S rT   rm   rh   ps     r(   
<dictcomp>z)PercentilesStats.peek.<locals>.<dictcomp>   s    ???At???r)   )r4   r"   rq   r#   r   r   sortcompute_percentiles)r$   rt   ru   rq   r   s        r(   peekzPercentilesStats.peek   s    &  	$, 	c  
  	6!) ??T->????I .M(77FF )55F 	B&vt/@AAAr)   c                     t          | j                  }|                                 |                     g            |rt	          || j                  S |                                 }||_        |S )zReduces the internal values list.

        Args:
            compile: If True, the result is compiled into a single value if possible.

        Returns:
            The reduced value on CPU.
        )r   r   r{   r   r|   r#   clone)r$   rt   r   return_statss       r(   reducezPercentilesStats.reduce   sk     %T[11 	B&vt/@AAAzz||$r)   c                 `    d|                                   d| j         dt          |            S )NzPercentilesStats(z	; window=z; len=)r}   r   r7   r8   s    r(   __repr__zPercentilesStats.__repr__   s1    X499;;XXXXSQUYYXXXr)   c                     t          j        | |          }|i ||d         |d         dS | i || j        | j        dS t	          d          )z;Returns the initialization arguments for this Stats object.)stats_objectr/   Nr   r   )r   r   z-Either stats_object or state must be provided)r   _get_init_argsr#   r   r"   )r   r/   
super_argss      r(   r   zPercentilesStats._get_init_args   s     -<uUUU
$]3/   
 %+8&.    LMMMr)   )NN)TF)T)&__name__
__module____qualname____doc__stats_cls_identifierr	   r   intboolr   floatr   r   strr   r-   r1   r   r9   r<   r>   rE   rG   rI   rK   rM   rP   rR   r@   rY   rc   rs   r}   r   r   staticmethodr   __classcell__)r'   s   @r(   r   r      s       ^^( /3.2!( !(49d?+!( sEz*+!( !( !( !( !( !(F4S>      1tCH~ 1$ 1 1 1 1 1 1% % %         
 
 

# # ## # ## # ## # ## # #$ $ $$ $ $$ $ $$ $ $
 
 

"# "$ " " " "&,D);$< , , , , ,@ @E+ ++8<+	sDI~	+ + + +Z d eC9K4K.L    ,Y# Y Y Y Y N Nc3h N N N \N N N N Nr)   r   c                 2   t          |           }|dk    rd |D             S i }|D ]p}|dz  |dz
  z  }|                                r| t          |                   ||<   :t          |          }|dz   }||z
  }| |         d|z
  z  | |         |z  z   ||<   q|S )as  Compute percentiles from an already sorted list.

    Note that this will not raise an error if the list is not sorted to avoid overhead.

    Args:
        sorted_list: A list of numbers sorted in ascending order
        percentiles: A list of percentile values (0-100)

    Returns:
        A dictionary mapping percentile values to their corresponding data values
    r   c                     i | ]}|d S rT   rm   rx   s     r(   rz   z'compute_percentiles.<locals>.<dictcomp>  s    ---A4---r)   r      )r7   
is_integerr   )	sorted_listr   nresultsry   indexlower_indexupper_indexweights	            r(   r|   r|     s     	KAAvv------G  SQU# 		$SZZ0GAJJe**K%/K[(FK(AJ7k*V34 AJJ
 Nr)   N)collectionsr   	itertoolsr   typingr   r   r   r   r	   ray.rllib.utils.frameworkr
   r   "ray.rllib.utils.metrics.stats.baser   #ray.rllib.utils.metrics.stats.utilsr   r   ray.util.annotationsr   r_   _r\   r   r|   rm   r)   r(   <module>r      s6               3 3 3 3 3 3 3 3 3 3 3 3 3 3 E E E E E E E E 8 8 8 8 8 8 O O O O O O O O - - - - - -q=??2q qN qN qN qN qNy qN qN qNh          r)   