
    &`i                     ^   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mZ d dlm	Z	m
Z
mZmZmZm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 d dlmZ  e            \  ZZ ed	d
          e G d d                                  Zed             Zedee         dee         defd            ZdS )    N)defaultdictdeque)AnyDictListOptionalTupleUnion)
Deprecated)
force_list)try_import_torch)convert_to_numpy)DeveloperAPIzrllib.utils.metrics.statsF)newerrorc                      e Zd ZdZ	 	 	 	 	 	 	 	 	 d6dee         dee         deee	         e
f         de
d	eee	ef                  d
ee         de
dee
ef         dee         fdZdeddfdZdeddfdZd7dZd8dZd9de
deeee         f         fdZedefd            Zede
fd            Zd9de
deeee         f         fdZd:dZd;dZd8dZd8d Zed!             Zde	f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/ Z)de*eef         fd0Z+ed1e*eef         dd fd2            Z,e	 d<dd dee         dd fd3            Z-d4 Z.d<de/eef         fd5Z0dS )=Statsa  A container class holding a number of values and executing reductions over them.

    The individual values in a Stats object may be of any type, for example python int
    or float, numpy arrays, or more complex structured (tuple, dict) and are stored in
    a list under `self.values`. This class is not meant to be interfaced with directly
    from application code. Instead, use `MetricsLogger` to log and manipulate Stats.

    Stats can be used to store metrics of the same type over time, for example a loss
    or a learning rate, and to reduce all stored values applying a certain reduction
    mechanism (for example "mean" or "sum").

    Available reduction mechanisms are:
    - "mean" using EMA with a configurable EMA coefficient.
    - "mean" using a sliding window (over the last n stored values).
    - "max/min" with an optional sliding window (over the last n stored values).
    - "sum" with an optional sliding window (over the last n stored values).
    - None: Simply store all logged values to an ever-growing list.

    Through the `reduce()` API, one of the above-mentioned reduction mechanisms will
    be executed on `self.values`.
    NmeanFinit_valuesreducepercentilesreduce_per_index_on_aggregatewindow	ema_coeffclear_on_reduce
throughputthroughput_ema_coeffc
           	         |dvrt          d          ||t          d          ||dk    rt          d          |dur|t          d          |dt          d	          fv rt          d
          |durt          d| d          |du rg d}nt          |          t          t          fvrt          d          t          |t                    rPt          d |D                       st          d          t          d |D                       st          d          || _        |dt          d	          fv | _        | j        r|s|t          d          |dk    r| j        r|d}|| _	        || _
        || _        | j	        dvr|rt          d          || _        t          d           | _        || _        d| _        t"          j        g| _        t)          t+          j                              | _        t          t0                    | _        |	| _        d| _        |durqt9          t          |t0          t          f          rt          |t                    s|gndd|	dddd          | _        |t;          j                    | _        nd| _        d| _         | !                    tE          |                     d| _#        |	d| _$        dS d| _$        dS )a`  Initializes a Stats instance.

        Args:
            init_values: Optional initial values to be placed into `self.values`. If None,
                `self.values` will start empty. If percentiles is True, values must be ordered
                if provided.
            reduce: The name of the reduce method to be used. Allowed are "mean", "min",
                "max", and "sum". Use None to apply no reduction method (leave
                `self.values` as-is when reducing, except for shortening it to
                `window`). Note that if both `reduce` and `window` are None, the user of
                this Stats object needs to apply some caution over the values list not
                growing infinitely.
            percentiles: If reduce is `None`, we can compute the percentiles of the
                values list given by `percentiles`. Defaults to [0, 50, 75, 90, 95,
                99, 100] if set to True. When using percentiles, a window must be provided.
                This window should be chosen carfully. RLlib computes exact percentiles and
                the computational complexity is O(m*n*log(n/m)) where n is the window size
                and m is the number of parallel metrics loggers invovled (for example,
                m EnvRunners). To be safe, choose a window < 1M and less than 1000 Stats
                objects to aggregate. See #52963 for more details.
            window: An optional window size to reduce over.
                If `window` is not None, then the reduction operation is only applied to
                the most recent `windows` items, and - after reduction - the values list
                is shortened to hold at most `window` items (the most recent ones).
                Must be None if `ema_coeff` is not None.
                If `window` is None (and `ema_coeff` is None), reduction must not be
                "mean".
            reduce_per_index_on_aggregate: If True, when merging Stats objects, we reduce
                incoming values per index such that the new value at index `n` will be
                the reduced value of all incoming values at index `n`.
                If False, when reducing `n` Stats, the first `n` merged values will be
                the reduced value of all incoming values at index `0`, the next `n` merged
                values will be the reduced values of all incoming values at index `1`, etc.
            ema_coeff: An optional EMA coefficient to use if reduce is "mean"
                and no `window` is provided. Note that if both `window` and `ema_coeff`
                are provided, an error is thrown. Also, if `ema_coeff` is provided,
                `reduce` must be "mean".
                The reduction formula for EMA performed by Stats is:
                EMA(t1) = (1.0 - ema_coeff) * EMA(t0) + ema_coeff * new_value
            clear_on_reduce: If True, the Stats object will reset its entire values list
                to an empty one after `self.reduce()` is called. However, it will then
                return from the `self.reduce()` call a new Stats object with the
                properly reduced (not completely emptied) new values. Setting this
                to True is useful for cases, in which the internal values list would
                otherwise grow indefinitely, for example if reduce is None and there
                is no `window` provided.
            throughput: If True, track a throughput estimate together with this
                Stats. This is only supported for `reduce=sum` and
                `clear_on_reduce=False` metrics (aka. "lifetime counts"). The `Stats`
                then keeps track of the time passed between two consecutive calls to
                `reduce()` and update its throughput estimate. The current throughput
                estimate can be obtained through:
                `throughput_per_sec = Stats.peek(throughput=True)`.
                If a float, track throughput and also set current throughput estimate
                to the given value.
            throughput_ema_coeff: An optional EMA coefficient to use for throughput tracking.
                Only used if throughput=True.
        )Nr   minmaxsumr   z?`reduce` must be one of `mean|min|max|sum|percentiles` or None!Nz5Only one of `window` or `ema_coeff` can be specified!r   z;`ema_coeff` arg only allowed (not None) when `reduce=mean`!Fz:`reduce` must be `None` when `percentiles` is not `False`!infz8A window must be specified when reduce is 'percentiles'!z!`reduce_per_index_on_aggregate` (z4) must be `False` when `percentiles` is not `False`!T)r   2   K   Z   _   c   d   z%`percentiles` must be a list or bool!c              3   N   K   | ] }t          |t          t          f          V  !d S N)
isinstanceintfloat.0ps     x/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/rllib/utils/metrics/legacy_stats.py	<genexpr>z!Stats.__init__.<locals>.<genexpr>   s0      PPqz!c5\::PPPPPP    z/`percentiles` must contain only ints or floats!c              3   6   K   | ]}d |cxk    odk    nc V  dS )r   r(   N r.   s     r1   r2   z!Stats.__init__.<locals>.<genexpr>   s6      BBqA}}}}}}}}BBBBBBr3   z9`percentiles` must contain only values between 0 and 100!zWWhen using an infinite window without reduction, `clear_on_reduce` must be set to True!g{Gz?)r   r!   r   r    zVreduce_per_index_on_aggregate is only supported for mean, sum, min, and max reduction!c                      d S r*   r5   r5   r3   r1   <lambda>z Stats.__init__.<locals>.<lambda>   s     r3   )r   r   r   r   r   r   r   )%
ValueErrorr-   typeboollistr+   all_percentiles_inf_window_reduce_method_window
_ema_coeff_reduce_per_index_on_aggregater   _start_times_clear_on_reduce_has_returned_zeronpnan_last_reducedstruuiduuid4id_r,   _prev_merge_values_throughput_ema_coeff_throughput_statsr   timeperf_counter_last_throughput_measure_timevalues_set_valuesr   
_is_tensor_has_new_values)
selfr   r   r   r   r   r   r   r   r   s
             r1   __init__zStats.__init__-   s   N KKKQ  
 )"7TUUU Vv%5%5M   e##! P   $e--- N   -E99 K8U K K K  
 d"":::$$T4L88$%LMMMk400 PPKPPPPP (M   BBkBBBBB (W   ( "dE%LL%99  	O 	"   V 0Y5FI$# 'DDD- E h   /L+ (55 !0"' !fXtz||$$"-c"2"2%9"!%U""%*
 zC<88 'z488ZLL
 . % %)& & &D"  &595F5H5H22  2
 15K00111 "#'D   #(D   r3   valuereturnc                 X   | j         t          |t          j                  r|j        dk    rd S t
          r<t
                              |          r"d| _        t          |j                  dk    rd S n%t          |          t          t          t          fvrd S t          d| d          d S )Nr5   TzValue (z8) is required to be a scalar when using a reduce method!)r@   r+   rG   ndarrayshapetorch	is_tensorrV   tupler:   r<   r   r9   )rX   rZ   s     r1   check_valuezStats.check_value   s     *%,, 1B1B 5??511 "&%%++F ,eT5%$888%      +*r3   c                    |                      |           | j        r|                     |           | j        Q| j                            |           t          | j                  | j        k    r| j                                         nut          | j                  dk    r|                     |g           nF| j                            |           | 	                                \  }}|                     |           d| _
        dS )z}Pushes a value into this Stats object.

        Args:
            value: The value to be pushed. Can be of any type.
        Nr   T)rb   has_throughput_recompute_throughputrA   rT   appendlenpopleftrU   _reduced_valuesrW   )rX   rZ   _rT   s       r1   pushz
Stats.push  s     	 	.&&u---<#Ku%%%4;$,..##%%% 4;1$$  %))))""5))) 0022	6  (((  $r3   c                 b    t          j                    }t          j                    | j        |<   | S )as  Called when entering a context (with which users can measure a time delta).

        Returns:
            This Stats instance (self), unless another thread has already entered (and
            not exited yet), in which case a copy of `self` is returned. This way, the
            second thread(s) cannot mess with the original Stat's (self) time-measuring.
            This also means that only the first thread to __enter__ actually logs into
            `self` and the following threads' measurements are discarded (logged into
            a non-referenced shim-Stats object, which will simply be garbage collected).
        )	threading	get_identrQ   rR   rD   )rX   	thread_ids     r1   	__enter__zStats.__enter__#  s-     '))	'+'8':':)$r3   c                     t          j                    }| j        |         J t          j                    | j        |         z
  }|                     |           | j        |= dS )zJCalled when exiting a context (with which users can measure a time delta).N)rm   rn   rD   rQ   rR   rk   )rX   exc_type	exc_valuetbro   time_delta_ss         r1   __exit__zStats.__exit__4  sb    '))	 +777(**T->y-II		,i(((r3   Tcompilec                     | j         s	|s\| j        sU|                                 \  }}|s	| j        s|S |r| j        r|d         S |r| j        durt          || j                  S |S | j        }|r|d         }|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 a single value if possible.

        Returns:
            The result of reducing the internal values list.
        r   F)rW   r?   ri   r@   r>   compute_percentilesrI   )rX   rw   reduced_valuereduced_valuesreturn_values        r1   peekz
Stats.peek=  s      	  	 8H 	 ,0,@,@,B,B)M> &4#3 &%% (4. ($Q'' N4,E99*>4;LMMM  -L /  ,Ar3   c                 `    | j         st          d          | j                                        S )zReturns the current throughput estimate per second.

        Raises:
            ValueError: If throughput tracking is not enabled for this Stats object.

        Returns:
            The current throughput estimate per second.
        z8Throughput tracking is not enabled for this Stats object)rd   r9   rP   r}   rX   s    r1   r   zStats.throughput[  s4     " 	YWXXX%**,,,r3   c                     | j         duS )zReturns whether this Stats object tracks throughput.

        Returns:
            True if this Stats object has throughput tracking enabled, False otherwise.
        N)rP   r   s    r1   rd   zStats.has_throughputj  s     %T11r3   c                 V   t          |           }| j        rJ|                                 \  }}| j        r|                     g            n|                     |           n	d}| j        }|                     |          }| j        't          |	                                          | _        nd| _        |r/| j        (t          |          dk    sJ d|             |d         }|sH| j
        sA||                                 \  }}|                     |          	                                }n<|r8| j        dur/||                                 \  }}t          || j                  }n|}|r|S |dk    rt                              |           S t                              | |          S )a  Reduces the internal values list according to the constructor settings.

        Thereby, the internal values list is changed (note that this is different from
        `peek()`, where the internal list is NOT changed). See the docstring of this
        class for details on the reduction logic applied to the values list, based on
        the constructor settings, such as `window`, `reduce`, etc..

        Args:
            compile: If True, the result is compiled into a single value if possible.
                If it is not possible, the result is a list of values.
                If False, the result is a list of one or more values.

        Returns:
            The reduced value (can be of any type, depending on the input values and
            reduction method).
        NT   z:Reduced values list must contain exactly one value, found r   F)r   )rg   rW   ri   rE   rU   rI   _numpy_if_necessaryr@   r   copyr?   r>   ry   r   
similar_to)rX   rw   len_before_reducereducedreduced_internal_values_listrj   return_valuess          r1   r   zStats.reduces  s   "  II 	) 594H4H4J4J1G1$ ?  $$$$  !=>>>>+/((G**733 * ",GLLNN!;!;D $(D  	!t*6G!!!UGUU "!!ajG 	$t/ 	$+3262F2F2H2H// 44, dff M  	$*%77+3262F2F2H2H///,d.? MM $M 		E   A%% ''---##Dm#DDDr3   otherc                 R    | j                             |j                    d| _        dS )zMerges another Stats object's values into this one along the time axis.

        Args:
            other: The other Stats object to merge values from.
        TN)rT   extendrW   rX   r   s     r1   merge_on_time_axiszStats.merge_on_time_axis  s,     	5<(((  $r3   othersc           	      b     j         pt          d          } fd g|D             }t          |          dk    rdS t          |          dk    r"|d          k    rdS |d         j         _        dS g }g } j        durSt           j                  gd |D             }t          t          j        |           }                     |           nt          dt          t          t          |                    dz             D ]q}|D ]7}	t          |	          |k     r|                    |	j        |                     8 j        rd}
nt          |          }
 j        ,|                    t!          j        |          g|
z             n j        |                    |           n j        dk    r[                     |	          d         d         }|                    ||
z  g|
z              j        r                     |           n2|                                         |	          d         |
z             |                                 t          |          |k    r|d|         } ns                     t          t/          |                               d
 _        dS )a=  Merges all internal values of `others` into `self`'s internal values list.

        Thereby, the newly incoming values of `others` are treated equally with respect
        to each other as well as with respect to the internal values of self.

        Use this method to merge other `Stats` objects, which resulted from some
        parallelly executed components, into this one. For example: n Learner workers
        all returning a loss value in the form of `{"total_loss": [some value]}`.

        The following examples demonstrate the parallel merging logic for different
        reduce- and window settings:

        Args:
            others: One or more other Stats objects that need to be parallely merged
                into `self, meaning with equal weighting as the existing values in
                `self`.
        r"   c           	          g | ]h}t          |          d k    sSt          |          dk    r>t          j        t          j                            |j                                      f|iS )r   r   )rg   rG   r=   isnanr   rT   )r/   srX   s     r1   
<listcomp>z+Stats.merge_in_parallel.<locals>.<listcomp>  si     	
 	
 	
A!FFaKKBF28D4L4LQX4V4V+W+W$X$XK 
  KKr3   r   Nr   Fc                 6    g | ]}t          |j                  S r5   )r<   rT   )r/   os     r1   r   z+Stats.merge_in_parallel.<locals>.<listcomp>  s     2R2R2Ra4>>2R2R2Rr3   r!   rT   T)rA   r-   rg   rT   r>   r<   heapqmergerU   ranger    maprf   rC   rB   r   rG   nanmeanr@   ri   rd   re   clearreversedrW   )rX   r   winstats_to_merge
new_values
tmp_valueslists_to_mergemergedistatsn_values	added_sums   `           r1   merge_in_parallelzStats.merge_in_parallel  s	   $ l*eEll	
 	
 	
 	
_V_	
 	
 	
 ~!##F  A%%a D(( -Q/6
 

E)) #4;//S2R2R62R2R2RSN%+~677FV$$$$ 1c#c>":":;;a?@@ # # , 8 8E5zzA~~ %%elA2&67777 6 / HH":H?.%%rz*'='=&>&IJJJJ(0%%j1111(E11 !% 4 4J 4 G G J1 MI%%y8';&<x&GHHH* >229===%%,,J,??BXM     """z??c))!+DSD!1JE * T(:"6"677888  $r3   c                 Z    | j         r#| j                            g            d| _        dS dS )a
  Clears the throughput Stats, if applicable and `self` has throughput.

        Also resets `self._last_throughput_measure_time` to -1 such that the Stats
        object has to create a new timestamp first, before measuring any new throughput
        values.
        r8   N)rd   rP   rU   rS   r   s    r1   clear_throughputzStats.clear_throughput2  s>      	4"..r22213D...	4 	4r3   c                     | j         sJ t          j                    }| j        dk    r-|| j        z
  }|dk    r| j                            ||z             || _        dS )z?Recomputes the current throughput value of this Stats instance.r   N)rd   rQ   rR   rS   rP   rk   )rX   rZ   current_time	time_diffs       r1   re   zStats._recompute_throughput=  so     """"(**-22$t'III1}}&++EI,=>>>-9***r3   c                     t           r?t          |           dk    r,t                               | d                   rd | D             } | S )Nr   c                 Z    g | ](}|                                                                 )S r5   )cpunumpy)r/   vs     r1   r   z-Stats._numpy_if_necessary.<locals>.<listcomp>S  s(    666!aeeggmmoo666r3   )r_   rg   r`   r   s    r1   r   zStats._numpy_if_necessaryN  sF      	7S[[1__)C)C_66v666Fr3   c                 *    t          | j                  S )z/Returns the length of the internal values list.)rg   rT   r   s    r1   __len__zStats.__len__V  s    4;r3   c                     | j         r
d| j          n| j        r
d| j         nd}d|                                  dt          |            d| j         | dS )Nz; win=z; ema= zStats(z; len=z	; reduce=))rA   rB   r}   rg   r@   )rX   
win_or_emas     r1   __repr__zStats.__repr__Z  s     |#T\### +$/+++ 	9TYY[[ 9 9D		 9 9)9+59 9 9	
r3   c                 p    | j         t          d          t          |                                           S )NzmCannot convert Stats object with reduce method `None` to int because it can not be reduced to a single value.)r@   r9   r,   r}   r   s    r1   __int__zStats.__int__g  s:    &;  
 tyy{{###r3   c                 p    | j         t          d          t          |                                           S )NzoCannot convert Stats object with reduce method `None` to float because it can not be reduced to a single value.)r@   r9   r-   r}   r   s    r1   	__float__zStats.__float__p  s;    &C  
 %%%r3   c                 ~    | j         |                     d           d S t          |           t          |          k    S )N__eq__r@   _comp_errorr-   r   s     r1   r   zStats.__eq__y  <    &X&&&&&;;%,,..r3   c                 ~    | j         |                     d           d S t          |           t          |          k    S )N__le__r   r   s     r1   r   zStats.__le__  r   r3   c                 ~    | j         |                     d           d S t          |           t          |          k    S )N__ge__r   r   s     r1   r   zStats.__ge__  r   r3   c                 ~    | j         |                     d           d S t          |           t          |          k     S )N__lt__r   r   s     r1   r   zStats.__lt__  <    &X&&&&&;;u--r3   c                 ~    | j         |                     d           d S t          |           t          |          k    S )N__gt__r   r   s     r1   r   zStats.__gt__  r   r3   c                 |    | j         |                     d           d S t          |           t          |          z   S )N__add__r   r   s     r1   r   zStats.__add__  <    &Y''''';;u--r3   c                 |    | j         |                     d           d S t          |           t          |          z
  S )N__sub__r   r   s     r1   r   zStats.__sub__  r   r3   c                 |    | j         |                     d           d S t          |           t          |          z  S )N__mul__r   r   s     r1   r   zStats.__mul__  r   r3   c                 R    | j         t          d          t          |           | S )NzeCannot format Stats object with reduce method `None` because it can not be reduced to a single value.)r@   r9   r-   )rX   fmts     r1   
__format__zStats.__format__  s8    &4  
 Dkk3)))r3   c                 (    t          d| d          )NzCannot za Stats object with reduce method `None` to other because it can not be reduced to a single value.)r9   )rX   comps     r1   r   zStats._comp_error  s*    ?d ? ? ?
 
 	
r3   c           
          t          | j                  | j        | j        | j        | j        | j        | j        | j        | j	        d	}| j
        | j
                                        |d<   |S )N)	rT   r   r   r   r   r   r   rI   rV   throughput_stats)r   rT   r@   r>   rC   rA   rB   rE   rI   rV   rP   	get_state)rX   states     r1   r   zStats.get_state  st     't{33),-1-Pl#4!//
 
 !-(,(>(H(H(J(JE$%r3   r   c                    | d         }d| v r
| d         rg }d| v rt                               | d                   }t          || d         |                     dd          |                     dd          | d         | d	         | d
         |                                |j        	  	        }n|                     dd          rJt          || d         |                     dd          | d         | d	         | d
         | d         d          }nCt          || d         |                     dd          | d         | d	         | d
         dd           }d| v r\t          | d         d         t                    s't          t          d | d                             | d<   | d         d         |_        n&|                     dt          j
        g          |_        |S )NrT   rV   r   r   r   Fr   r   r   r   )r   r   r   r   r   r   r   r   _throughputg?)r   r   r   r   r   r   r   _histr   c                     | gS r*   r5   )xs    r1   r7   z"Stats.from_state.<locals>.<lambda>   s    QC r3   r8   rI   )r   
from_stategetr}   rB   r+   r<   r   rI   rG   rH   )r   rT   r   r   s       r1   r   zStats.from_state  s    x5  U<%8 F&&$//6H0IJJX!IImU;;.3ii3U/ / X, %&7 8+0022%5%@  EE YY}e,, 	
 X!IImU;;X, %&7 8 /%)	 	 	EE X!IImU;;X, %&7 8 %)	 	 	E eeGnQ/66 J!%c--w&H&H!I!Ig"'."4E"'))ObfX"F"FEr3   c                     t          || j        | j        | j        | j        | j        | j        | j        r| j        	                                nd| j
        	  	        }| j        |_        | j        |_        |S )aq  Returns a new Stats object that's similar to `other`.

        "Similar" here means it has the exact same settings (reduce, window, ema_coeff,
        etc..). The initial values of the returned `Stats` are empty by default, but
        can be set as well.

        Args:
            other: The other Stats object to return a similar new Stats equivalent for.
            init_value: The initial value to already push into the returned Stats.

        Returns:
            A new Stats object similar to `other`, with the exact same settings and
            maybe a custom initial value (if provided; otherwise empty).
        F)	r   r   r   r   r   r   r   r   r   )r   r@   r>   rC   rA   rB   rE   rd   rP   r}   rO   rM   rI   )r   r   r   s      r1   r   zStats.similar_to  s    & #'**/*N=&!2#u.33555!&!<
 
 
 I	#1r3   c                 h    | j         st          || j                  | _        n|| _        d| _        d S )N)maxlenT)r?   r   rA   rT   rW   )rX   r   s     r1   rU   zStats._set_values*  s>      	%
4<@@@DKK %DK#r3   c                    ||n| j         }| j        0| j        dur#t          |          }|                                 ||fS t          |          dk    r$| j        dv s| j        rt          j        gg fS dgg fS | j	        ?|d         }|dd         D ]}| j	        |z  d| j	        z
  |z  z   }| j
        r|g|gfS |g|fS t          rt                              |d                   rd| _        t          |d         j                  dk    r	|d         }nt          t          d| j        z             }t                              t          |                    }| j        d	k    r|                                } ||          }n[t          t          d| j        z             }t          j        t          j        |                    rt          j        }n ||          }d
 } ||          s|j        dk    rvt)          |d         t*          t"          f          rT|j        t          j        t          j        t          j        t          j        fv rt+          |          }nt#          |          }| j
        r| j        d	k    r|g|gfS |g|fS )ag  Runs a non-committed reduction procedure on given values (or `self.values`).

        Note that this method does NOT alter any state of `self` or the possibly
        provided list of `values`. It only returns new values as they should be
        adopted after a possible, actual reduction step.

        Args:
            values: The list of values to reduce. If not None, use `self.values`

        Returns:
            A tuple containing 1) the reduced values and 2) the new internal values list
            to be used. If there is no reduciton method, the reduced values will be the same as the values.
        NFr   )r   r    r   r   g      ?TrH   r   c                     t           r4t          | t           j                  rt                               |           S t	          j        |           S r*   )r_   r+   Tensorr   rG   )rZ   s    r1   
safe_isnanz)Stats._reduced_values.<locals>.safe_isnany  s=     .Zu|<< . ;;u---x&r3   r5   )rT   r@   r>   r<   sortrg   rF   rG   rH   rB   r?   r_   r`   rV   r^   getattrstackr-   r=   r   r+   r,   dtypeint32int64int8int16)rX   rT   
mean_valuer   r   reduce_meth	reduce_inr   s           r1   ri   zStats._reduced_values5  s    "-4; & --f 6>! [[A"&<<<@W< x|#sBw _(JABBZ X X!_q0C$/4IZ3WW

 ,"|j\11"|V++  233 2"&vay''1,,$QiGG")%9L1L"M"MK %DLL 9 9I*f44$-OO$5$5	)k)44GG%b%$2E*EFF6"(6**++ 2 fGG)k&11G' ' ' Jw''-MR''vay3,77 ( =RXrx"($KKK!'llGG#GnnG  	)D$76$A$A
  y7)++  y&((r3   )	Nr   FFNNFFN)r[   r   )r[   N)T)r   r   r[   N)r   r   r[   Nr*   )1__name__
__module____qualname____doc__r   r   rJ   r
   r   r,   r;   r-   rY   rb   rk   rp   rv   r}   propertyr   rd   r   r   r   r   re   staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rU   r	   ri   r5   r3   r1   r   r      s\        0 &* &.3.3.2%) %).04G) G)c]G) G) 49d?+	G)
 (,G) sEz*+G) E?G) G) $+&G) 'uoG) G) G) G)R     "$# $$ $ $ $ $8   ") ) ) )   D  E#tCy.,A        < -E - - - X- 2 2 2 2 X2JE JEd JEeCcN.C JE JE JE JEX	$ 	$ 	$ 	$f$ f$ f$ f$P	4 	4 	4 	4: : : :"   \         
# 
 
 
 
$ $ $& & &/ / // / // / /. . .. . .. . .. . .. . .* * *
 
 
4S>    " :$sCx. :W : : : \:x  &*! !!c]! 
! ! ! \!F	$ 	$ 	$`) `)eCHo `) `) `) `) `) `)r3   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 r*   r5   r.   s     r1   
<dictcomp>z'compute_percentiles.<locals>.<dictcomp>  s    ---A4---r3   r(   r   )rg   
is_integerr,   )	sorted_listr   nresultsr0   indexlower_indexupper_indexweights	            r1   ry   ry     s     	KAAvv------G  SQU# 		$SZZ0GAJJe**K%/K[(FK(AJ7k*V34 AJJ
 Nr3   
base_statsincoming_statsr[   c                    | d}nd}t          |          dk    r| S |rt          j        |d                   } |                                  t          |          dk    r | j        |dd           | j        dk    r6| j        r/| j        du r&|D ]#}|                                | j	        |j
        <   $n9t          |          dk    r%d}| j        dk    ri| j        rb| j        du rY|D ]V}| j	        |j
                 }|                    d          }| j        d	xx         |z  cc<   |||z
  z  }|| j	        |j
        <   Wt          j        |d                   }t          |          dk    r |j        |dd           | j        d
k    r4| j        s-|                     |j                                                   n1|                     |           | j        r|                     |           | S )a  Merges Stats objects.

    If `base_stats` is None, we use the first incoming Stats object as the new base Stats object.
    If `base_stats` is not None, we merge all incoming Stats objects into the base Stats object.

    Args:
        base_stats: The base Stats object to merge into.
        incoming_stats: The list of Stats objects to merge.

    Returns:
        The merged Stats object.
    NTFr   r   r!   g        )rw   r8   r   )rg   r   deepcopyr   r   r@   r?   rE   r}   rN   rM   rT   rU   r   rd   re   )r  r  new_root_statsstatr   prev_reductionnew_reductionparallel_merged_stats           r1   merge_statsr    sU    ~!## <<]>!#455
##%%%
 ~""(J(.*<==%..& /+u44& F F:>))++
-dh77	^		q	 	  	%..& /+u44& 	H 	H ",!>tx!H $		$	 7 7!"%%%7%%% ]^;;	:G
-dh77#}^A->??~"" 3 2N1224FGG $..z7R. ""#7#>#C#C#E#EFFFF))*>???( <00;;;r3   ) r   r   rm   rQ   rK   collectionsr   r   typingr   r   r   r   r	   r
   r   rG   ray._common.deprecationr   ray.rllib.utilsr   ray.rllib.utils.frameworkr   ray.rllib.utils.numpyr   ray.util.annotationsr   r_   rj   r   ry   r  r5   r3   r1   <module>r     s           * * * * * * * * : : : : : : : : : : : : : : : :     . . . . . . & & & & & & 6 6 6 6 6 6 2 2 2 2 2 2 - - - - - -q +5999) ) ) ) ) ) )  :9)D ! ! !H SHUO ST%[ SU S S S S S Sr3   