
    &`i`                         d dl Z d dlZd dl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mZ d dlmZ erd dlmZ  ej        e          Ze G d	 d
e                      Z G d d          ZdS )    N)TYPE_CHECKINGDictListOptionalTuple)	TuneError)Trial)DEFAULT_METRIC)FIFOSchedulerTrialScheduler)	PublicAPI)TuneControllerc                   d    e Zd ZdZdZ	 	 	 	 	 	 d#ded	ee         d
ee         dedede	f fdZ
d	ee         d
ee         de	fdZdddefdZd Zde	fdZdddedefdZdddddefdZdddefdZdddefdZdddedefdZdddefdZdddee         fd Zdefd!Zdeeef         fd"Z xZS )$HyperBandSchedulera	  Implements the HyperBand early stopping algorithm.

    HyperBandScheduler early stops trials using the HyperBand optimization
    algorithm. It divides trials into brackets of varying sizes, and
    periodically early stops low-performing trials within each bracket.

    To use this implementation of HyperBand with Tune, all you need
    to do is specify the max length of time a trial can run `max_t`, the time
    units `time_attr`, the name of the reported objective value `metric`,
    and if `metric` is to be maximized or minimized (`mode`).
    We automatically determine reasonable values for the other
    HyperBand parameters based on the given values.

    For example, to limit trials to 10 minutes and early stop based on the
    `episode_mean_reward` attr, construct:

    ``HyperBand('time_total_s', 'episode_reward_mean', max_t=600)``

    Note that Tune's stopping criteria will be applied in conjunction with
    HyperBand's early stopping mechanisms.

    See also: https://blog.ml.cmu.edu/2018/12/12/massively-parallel-hyperparameter-optimization/

    Args:
        time_attr: The training result attr to use for comparing time.
            Note that you can pass in something non-temporal such as
            `training_iteration` as a measure of progress, the only requirement
            is that the attribute should increase monotonically.
        metric: The training result objective value attribute. Stopping
            procedures will use this attribute. If None but a mode was passed,
            the `ray.tune.result.DEFAULT_METRIC` will be used per default.
        mode: One of {min, max}. Determines whether objective is
            minimizing or maximizing the metric attribute.
        max_t: max time units per trial. Trials will be stopped after
            max_t time units (determined by time_attr) have passed.
            The scheduler will terminate trials after this time has passed.
            Note that this is different from the semantics of `max_t` as
            mentioned in the original HyperBand paper.
        reduction_factor: Same as `eta`. Determines how sharp
            the difference is between bracket space-time allocation ratios.
        stop_last_trials: Whether to terminate the trials after
            reaching max_t. Defaults to True.
    Ftraining_iterationNQ      T	time_attrmetricmodemax_treduction_factorstop_last_trialsc                 B    dk    s
J d            |r|dv s
J d            t                                                       | _        t          t	          j        t	          j                  t	          j        |          z                      dz    _         _         fd _	         fd _
        g g _        i  _        d dd _        d _        | _        | _        d  _         j        d	k    rd
 _        n j        dk    rd _        | _        | _        d S )Nr   zMax (time_attr) not valid!)minmaxz`mode` must be 'min' or 'max'!   c                 r    t          t          j        j        | dz   z  j        | z  z                      S )Nr   )intnpceil_s_max_1_eta)sselfs    q/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/tune/schedulers/hyperband.py<lambda>z-HyperBandScheduler.__init__.<locals>.<lambda>k   s0    RWT]a!e-DtyRS|-S%T%T!U!U     c                 :    t          j        |  z  z            S N)r   r#   )r$   r   r%   s    r&   r'   z-HyperBandScheduler.__init__.<locals>.<lambda>m   s    ediQB.?&?!A!A r(   )bracketband_idxr         ?r         )super__init__r#   r   r    roundlogr"   _max_t_attr_get_n0_get_r0_hyperbands_trial_info_state_num_stopped_metric_mode
_metric_op
_time_attr_stop_last_trials)r%   r   r   r   r   r   r   	__class__s   `   `  r&   r0   zHyperBandScheduler.__init__Y   s<    qyyy6yyy 	L>)))+K)))$	BHRVE]]RV<L5M5M%MNNOORSS UUUUAAAAA4 #'A66
:!DOOZ5  "DO#!1r(   returnc                     | j         r|rdS | j        r|rdS |r|| _         |r|| _        | j        dk    rd| _        n| j        dk    rd| _        | j         | j        rt          | _         dS )NFr   r-   r   r.   T)r:   r;   r<   r
   )r%   r   r   specs       r&   set_search_propertiesz(HyperBandScheduler.set_search_properties   s     < 	F 	5: 	$ 	5 	"!DL 	DJ:!DOOZ5  "DO<DJ)DLtr(   tune_controllerr   trialc                 ,   | j         r| j        s8t          d                    | j        j        | j         | j                            | j        d         }| j        | j        d                  }||	                                rd}|r| 
                                r1g }| j                            |           | j        dxx         dz  cc<   t          |          }|| j        k     s
J d            |                     |          dk    rt                              d	           d}nd
}|                     |          }|                    |           || j        d<   || j        d                             |           || j        d         f| j        |<   dS )a  Adds new trial.

        On a new trial add, if current bracket is not filled,
        add to current bracket. Else, if current band is not filled,
        create new bracket, add to current bracket.
        Else, create new iteration, create new bracket, add to bracket.z{} has been instantiated without a valid `metric` ({}) or `mode` ({}) parameter. Either pass these parameters when instantiating the scheduler, or pass them as parameters to `tune.TuneConfig()`r+   r,   NTr   zCurrent band is filled!r   zBracket too small - Retrying...F)r:   r<   
ValueErrorformatr?   __name__r;   r8   r6   filled_cur_band_filledappendlenr"   r5   loggerinfo_create_bracket	add_trialr7   )r%   rD   rE   cur_bracketcur_bandretryr$   s          r&   on_trial_addzHyperBandScheduler.on_trial_add   s    | 	4? 	) *0N+T\4:* *	   k),#DK
$;<+"4"4"6"6E 5((** 1!H$++H555K
+++q0+++ MM4=(((*C(((<<??a''KK ABBB"&KK!E"&"6"6q"9"9K,,,)4I&#  5& 	I((///"-t{:/F"Fr(   c           	          t          | j        |                     |          |                     |          | j        | j        || j                  S )N)r   
max_trialsinit_t_attr
max_t_attretar$   r   )_Bracketr=   r4   r5   r3   r#   r>   )r%   r$   s     r&   rP   z"HyperBandScheduler._create_bracket   sL    o||AQ'	!3
 
 
 	
r(   c                 b    | j         | j        d                  }t          |          | j        k    S )zfChecks if the current band is filled.

        The size of the current band should be equal to s_max_1r,   )r6   r8   rM   r"   )r%   rS   s     r&   rK   z#HyperBandScheduler._cur_band_filled   s+    
 #DK
$;<8}}--r(   resultc                    | j         |         \  }}|                    ||           |                    |          rt          j        S t
                              d| d           |                     ||          }t
                              | d| d| j         d|	                    | j                              |S )at  If bracket is finished, all trials will be stopped.

        If a given trial finishes and bracket iteration is not done,
        the trial will be paused and resources will be given up.

        This scheduler will not start trials but will stop trials.
        The current running trial will not be handled,
        as the trialrunner will be given control to handle it.Processing bracket after trial z resultz for z on =)
r7   update_trial_statscontinue_trialr   CONTINUErN   debug_process_bracketr=   get)r%   rD   rE   r]   r+   _actions          r&   on_trial_resultz"HyperBandScheduler.on_trial_result   s     %e,
""5&111!!%(( 	+!**EuEEEFFF&&@@ ? ?E ? ?? ?!'DO!<!<? ?	
 	
 	
 r(   r+   r[   c                 z   t           j        }|                                r|                                r!|                    |           t           j        S d|_        |                    | j        | j	                  \  }}t                              dt          |           dt          |           d| d| d| 
           | xj        t          |          z  c_        |D ]}|j        t          j        k    s|j        r@t                              dt%          |                      |                    |           ^|j        t          j        k    rLt                              dt%          |                      |                    |           t           j        }t-          d	t%          |           d
|j                   |D ]}|                    |          r|j        t          j        t          j        fvsJ d|j         d|j         d            |j        t          j        k    s|j        r[t                              dt%          |                      |                     ||           |j                            |           |j        t          j        k    r6t                              dt%          |                      t           j        }|                                r|j        r|j        t          j        k    s|j        rAt                              dt%          |                      |                    |           |j        t          j        k    rKt                              dt%          |                      |                    |           t           j        }|S )a  This is called whenever a trial makes progress.

        When all live trials in the bracket have no more iterations left,
        Trials will be successively halved. If bracket is done, all
        non-running trials will be stopped and cleaned up,
        and during each halving phase, bad trials will be stopped while good
        trials will return to "PENDING".

        Note some implicit conditions here: In ``on_trial_result`` a trial is
        either continued (e.g. if it didn't reach the time threshold for the bracket)
        or this method (``_process_bracket``) is called. If there are other trials left
        that still haven't reached the threshold, the trial is PAUSED. This means
        that when the bracket is actually processed (``bracket.cur_iter_done``), there
        is at most one RUNNING trial (which is the trial that is currently processed)
        and the rest are either PAUSED (as explained above) or TERMINATED/ERRORED
        (if they finish separately).
        TzProcessing z
 good and z bad trials in bracket z.
Good: z
Bad: zStopping other trial zStopping current trial z.Trial with unexpected bad status encountered: z is zGood trial z is in an invalid state: zx
Expected trial to be either PAUSED, PENDING, or RUNNING.
If you encounter this, please file an issue on the Ray Github.zUnpausing trial zContinuing current trial z'Bracket finished. Stopping other trial z)Bracket finished. Stopping current trial ) r   PAUSEcur_iter_donefinishedcleanup_fullSTOPis_being_processedsuccessive_halvingr:   r<   rN   rd   rM   r9   statusr	   PAUSED	is_savingstr
stop_trialRUNNINGcleanup_trialr   rb   ERROR
TERMINATEDtrial_id_unpause_trialtrials_to_unpauseaddrc   r   )r%   rD   r+   rh   goodbadts          r&   re   z#HyperBandScheduler._process_bracket   s   *  %  "" F	5!! +$$_555%**)-G&224<QQID#LL,c$ii , ,3s88 , ,", ,, ,&), ,   S)  8u|++q{+LL!AQ!A!ABBB#..q1111X.. LL!C3q66!C!CDDD))!,,,+0FF $2q662 2'(x2 2    5 5))!,, 58EK9I+JJJJYaj Y Y18 Y Y Y KJJ
 x5<//1;/%@A%@%@AAA++OQ???155a8888U]22 %IQ%I%IJJJ!/!8%%'' 5G,D 5 x5<//1;/%WsSTvv%W%WXXX'2215555U]22 PAPP    --a000!/!4r(   c                     dS )zNo-op by default.N r%   rD   rE   s      r&   r|   z!HyperBandScheduler._unpause_trialN  s    r(   c                     | j         |         \  }}|                    |           |                                s=|j        s8t                              d| d           |                     ||           dS dS dS )zNotification when trial terminates.

        Trial info is removed from bracket. Triggers halving if bracket is
        not finished.r_   z removedN)r7   rx   rm   rp   rN   rd   re   )r%   rD   rE   r+   rg   s        r&   on_trial_removez"HyperBandScheduler.on_trial_removeR  s    
 %e,
e$$$!! 	<'*D 	<LLJ5JJJKKK!!/7;;;;;	< 	< 	< 	<r(   c                 2    |                      ||           dS )z;Cleans up trial info from bracket if trial completed early.Nr   )r%   rD   rE   r]   s       r&   on_trial_completez$HyperBandScheduler.on_trial_complete]  s      	_e44444r(   c                 2    |                      ||           dS )z9Cleans up trial info from bracket if trial errored early.Nr   r   s      r&   on_trial_errorz!HyperBandScheduler.on_trial_errorc  s    _e44444r(   c                     | j         D ]u}d |D             }t          |d           D ]T}|                                D ]=}|j        t          j        k    r	||j        v s|j        t          j        k    r|c c c S >UvdS )zFair scheduling within iteration by completion percentage.

        List of trials not used since all trials are tracked as state
        of scheduler. If iteration is occupied (ie, no trials to run),
        then look into next iteration.
        c                     g | ]}||S r*   r   ).0bs     r&   
<listcomp>z:HyperBandScheduler.choose_trial_to_run.<locals>.<listcomp>r  s    >>>ar(   c                 *    |                                  S r*   )completion_percentage)r   s    r&   r'   z8HyperBandScheduler.choose_trial_to_run.<locals>.<lambda>s  s    !:Q:Q:S:S r(   keyN)r6   sortedcurrent_trialsrr   r	   rs   r}   PENDING)r%   rD   	hyperbandscrubbedr+   rE   s         r&   choose_trial_to_runz&HyperBandScheduler.choose_trial_to_rung  s     ) 
	% 
	%I ?>9>>>H!(0S0STTT % %$3355 % %E44!W%>>>66$ 7	%% tr(   c                     d}|d                     | j        t          d | j        D                                 z  }t	          | j                  D ]<\  }}|d                     |          z  }|D ]}|r|d                     |          z  }=|S )a}  This provides a progress notification for the algorithm.

        For each bracket, the algorithm will output a string as follows:

            Bracket(Max Size (n)=5, Milestone (r)=33, completed=14.6%):
            {PENDING: 2, RUNNING: 3, TERMINATED: 2}

        "Max Size" indicates the max number of pending/running experiments
        set according to the Hyperband algorithm.

        "Milestone" indicates the iterations a trial will run for before
        the next halving will occur.

        "Completed" indicates an approximate progress metric. Some brackets,
        like ones that are unfilled, will not reach 100%.
        zUsing HyperBand: z num_stopped={} total_brackets={}c              3   4   K   | ]}t          |          V  d S r*   rM   r   bands     r&   	<genexpr>z2HyperBandScheduler.debug_string.<locals>.<genexpr>  s(      "J"J3t99"J"J"J"J"J"Jr(   z
Round #{}:z
  {})rH   r9   sumr6   	enumerate)r%   outir   r+   s        r&   debug_stringzHyperBandScheduler.debug_string|  s    " "188s"J"J9I"J"J"JJJ
 
 	
 !!122 	4 	4GAt>((+++C 4 4 48??7333C4 
r(   c                 N    t          d | j        D                       | j        dS )Nc              3   4   K   | ]}t          |          V  d S r*   r   r   s     r&   r   z+HyperBandScheduler.state.<locals>.<genexpr>  s(      GGdD		GGGGGGr(   )num_bracketsnum_stopped)r   r6   r9   r%   s    r&   statezHyperBandScheduler.state  s4    GGd6FGGGGG,
 
 	
r(   )r   NNr   r   T)rI   
__module____qualname____doc___supports_buffered_resultsru   r   r   floatboolr0   rC   r	   rU   rP   rK   r   ri   re   r|   r   r   r   r   r   r   __classcell__)r?   s   @r&   r   r   )   s       * *X "' . $""#!%$2 $2$2 $2 sm	$2
 $2  $2 $2 $2 $2 $2 $2 $2Lsm+3C=	   0)G,< )GU )G )G )G )GV	
 	
 	
.$ . . . ./8=GK   4]/]:D]	] ] ] ]~.> u    	</? 	< 	< 	< 	< 	<5/58=5GK5 5 5 55.> 5u 5 5 5 53C QV    *c    8
tCH~ 
 
 
 
 
 
 
 
r(   r   c                   .   e Zd ZdZ	 d#dedededededed	efd
Zde	fdZ
defdZdefdZdee	         fdZde	defdZdefdZdededeee	         ee	         f         fdZde	defdZde	fdZd$dZdefdZdedefdZdededefd Zdefd!Zd"S )%r[   zLogical object for tracking Hyperband bracket progress. Keeps track
    of proper parameters as designated by HyperBand.

    Also keeps track of progress to ensure good scheduling.
    Tr   rW   rX   rY   rZ   r$   r   c                 F   i | _         g | _        || _        |x| _        | _        |x| _        | _        || _        | j        | _        || _	        || _
        |                     | j        | j        |          | _        d| _        || _        d| _        t!                      | _        d S )Nr   F)_live_trials_all_trialsr=   _n_n0_r_r0r3   _cumul_rr#   _halves_calculate_total_work_total_work_completed_progressr   rp   setr}   )r%   r   rW   rX   rY   rZ   r$   r   s           r&   r0   z_Bracket.__init__  s     #''$((($(%	55dh!LL#$  0"'!$r(   rE   c                     |                                  r
J d            d| j        |<   | j                            |           dS )zAdd trial to bracket assuming bracket is not filled.

        At a later iteration, a newly added trial will be given equal
        opportunity to catch up.z#Cannot add trial to filled bracket!N)rJ   r   r   rL   r%   rE   s     r&   rQ   z_Bracket.add_trial  sK    
 ;;==GG"GGG #'% &&&&&r(   r@   c                 h     t           fd j                                        D                       S )zhChecks if all iterations have completed.

        TODO(rliaw): also check that `t.iterations == self._r`c              3   T   K   | ]"}                     |          j        k    V  #d S r*   )_get_result_timer   )r   r]   r%   s     r&   r   z)_Bracket.cur_iter_done.<locals>.<genexpr>  sL       
 
 !!&))T]:
 
 
 
 
 
r(   )allr   valuesr   s   `r&   rl   z_Bracket.cur_iter_done  sL      
 
 
 
+2244
 
 
 
 
 	
r(   c                 R    | j         sdS | j        dk    o|                                 S )NFr   )r   r   rl   r   s    r&   rm   z_Bracket.finished  s0    $ 	5|q 9T%7%7%9%99r(   c                 *    t          | j                  S r*   )listr   r   s    r&   r   z_Bracket.current_trials  s    D%&&&r(   c                     | j         |         }| j        s| j        dk    rdS |                     |          | j        k     r(t
                              d| d| j         d           dS dS )Nr   TzContinuing trial z) as it hasn't reached the time threshold z, yet.F)r   r   r   r   r   rN   rd   )r%   rE   r]   s      r&   rb   z_Bracket.continue_trial  s    "5)$ 	):):4""6**T]::LL)E ) )=) ) )   4ur(   c                 <    t          | j                  | j        k    S )zChecks if bracket is filled.

        Only let new trials be added at current level minimizing the need
        to backtrack and bookkeep previous medians.)rM   r   r   r   s    r&   rJ   z_Bracket.filled  s     4$%%00r(   r   	metric_opc                      j         dk    r j        s	 j        g fS  j         dk    sJ  xj         dz  c_         t          t	          j         j         j        z                       _         xj         j        z  c_        t          t           j         j
                             _         j         _        t           j         fd          }| j         d          |d  j                  }}||fS )Nr   r   c                 0    j         |                   z  S r*   )r   )r   r   r   r%   s    r&   r'   z-_Bracket.successive_halving.<locals>.<lambda>  s    Y9J19Mf9U-U r(   r   )r   r   r   r   r    r!   r   r#   r   r   r3   r   r   )r%   r   r   sorted_trialsr   r   s   ```   r&   rq   z_Bracket.successive_halving  s	    <1T%:$b((|a 	 bgdg	12233 	49c$'4#34455#U#U#U#U#U#U
 
 
 "47(**-}ZxZ/HcSyr(   r]   c                    || j         v sJ |                     |          dk    sJ |                     |          }|                     | j         |                   }||z
  }|dk    r.t                              d                    ||                     | xj        |z  c_        || j         |<   | j                            |           dS )zUpdate result for trial. Called after trial has finished
        an iteration - will decrement iteration count.

        TODO(rliaw): The other alternative is to keep the trials
        in and make sure they're not set as pending later.r   z<Restoring from a previous point in time. Previous={}; Now={}N)r   r   rN   rO   rH   r   r}   discard)r%   rE   r]   observed_timelast_observeddeltas         r&   ra   z_Bracket.update_trial_stats  s     )))))$$V,,1111--f55--d.?.FGG-A::KK&&,f]M&J&J   	  E)  #)% &&u-----r(   c                 <    | j                             |d           dS )a)  Clean up statistics tracking for terminated trials (either by force
        or otherwise).

        This may cause bad trials to continue for a long time, in the case
        where all the good trials finish early and there are only bad trials
        left in a bracket with a large max-iteration.N)r   popr   s     r&   rx   z_Bracket.cleanup_trial'  s#     	eT*****r(   rD   r   c                     |                                  D ],}|j        t          j        k    r|                    |           -dS )zCleans up bracket after bracket is completely finished.

        Lets the last trial continue to run until termination condition
        kicks in.N)r   rr   r	   rs   rv   r   s      r&   rn   z_Bracket.cleanup_full0  sM    
 ((** 	2 	2E|u|++**5111	2 	2r(   c                 h    |                                  rdS t          | j        | j        z  d          S )zrReturns a progress metric.

        This will not be always finish with 100 since dead trials
        are dropped.r-   )rm   r   r   r   r   s    r&   r   z_Bracket.completion_percentage9  s4    
 ==?? 	34+d.>>DDDr(   c                 $    |dS || j                  S )Nr   )r=   )r%   r]   s     r&   r   z_Bracket._get_result_timeB  s    >1do&&r(   nrc                 0   d}|}t          |dz             D ]~}|t          |          t          |          z  z  }|| j        z  }t          t          j        |                    }|| j        z  }t          t          || j        |z
                      }|S )Nr   r   )ranger   r#   r    r!   r   r3   )r%   r   r   r$   workcumulative_rrg   s          r&   r   z_Bracket._calculate_total_workG  s    q1u 	= 	=ACFFSVVO#DNABGAJJANAC4+l:;;<<AAr(   c                    d                     d                    | j                  d                    | j                  d                    |                                           g          }t          j        d | j        D                       }d                     t          d |	                                D                                 }d                    ||          S )Nz, zMax Size (n)={}zMilestone (r)={}zcompleted={:.1%}c                     g | ]	}|j         
S r   )rr   )r   r   s     r&   r   z%_Bracket.__repr__.<locals>.<listcomp>Z  s    %I%I%I1ah%I%I%Ir(   c              3   H   K   | ]\  }}d                      ||          V  dS )z{}: {}N)rH   )r   kvs      r&   r   z$_Bracket.__repr__.<locals>.<genexpr>\  s4      DDTQ8??1a((DDDDDDr(   zBracket({}): {{{}}} )
joinrH   r   r   r   collectionsCounterr   r   items)r%   rr   countstrial_statusess       r&   __repr__z_Bracket.__repr__R  s    !((11"))$-88"))$*D*D*F*FGG
 
 $%I%I8H%I%I%IJJDDV\\^^DDDDD
 
 &,,V^DDDr(   N)T)rD   r   )rI   r   r   r   ru   r   r   r   r0   r	   rQ   rl   rm   r   r   rb   rJ   r   rq   r   ra   rx   rn   r   r   r   r   r   r(   r&   r[   r[     sJ         "&' '' ' 	'
 ' ' ' ' ' ' ':'u ' ' ' '
t 
 
 
 
:$ : : : :
'U ' ' ' '
E 
d 
 
 
 
1 1 1 1 1&+	tE{DK'	(   @. .t . . . .,+5 + + + +2 2 2 2Eu E E E E't ' ' ' ' '
	s 	u 	 	 	 	 	E# E E E E E Er(   r[   )r   loggingtypingr   r   r   r   r   numpyr    ray.tune.errorr   ray.tune.experimentr	   ray.tune.resultr
   #ray.tune.schedulers.trial_schedulerr   r   ray.util.annotationsr   "ray.tune.execution.tune_controllerr   	getLoggerrI   rN   r   r[   r   r(   r&   <module>r      sb        = = = = = = = = = = = = = =     $ $ $ $ $ $ % % % % % % * * * * * * M M M M M M M M * * * * * * BAAAAAA		8	$	$2 r
 r
 r
 r
 r
 r
 r
 r
jE E E E E E E E E Er(   