
    &`iLJ                       d dl Z d dlZ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
 d dlmZ d dlmZ d dlmZmZ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mZ d d
l m!Z!m"Z" d dl#m$Z$m%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/ d dl0m1Z1m2Z2m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8 d dl9m:Z: d dl;m<Z< d dl=m>Z>m?Z? d dl@mAZAmBZBmCZCmDZDmEZE d dlFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZN d dlOmPZPmQZQ d dlRmSZSmTZT d dlUmVZVmWZW d dlXmYZY d dlZm[Z[m\Z\ d dl]m^Z^m_Z_m`Z` d dlambZb d dlcmdZd d d lemfZfmgZg d d!lhmiZi d d"ljmkZk  ejl        em          Znei G d# d$                      Zo G d% d&          Zpei G d' d(                      Zqd)eTd*erfd+Zs G d, d-          ZtdS ).    N)defaultdictdeque)datetime)partial)Path)AnyCallableDictListOptionalSetTupleUnion)ResourceRequest)TIME_THIS_ITER_S)PlacementGroupResourceManagerResourceManager)RayActorManagerTrackedActor)RayActorErrorRayTaskError)_FutureTrainingResult_TrainingResult)StorageContext)CheckpointConfig)CallbackCallbackList)	TuneError_AbortTrialExecution_TuneStopTrialError)_ActorClassCache)_ExperimentCheckpointManager"_find_newest_experiment_checkpoint)_InsufficientResourcesManager)PlacementGroupFactory)
ExperimentTrial)_change_working_directory_get_trainable_kwargs	_Location_noop_logger_creator
_TrialInfo)DEBUG_METRICSDEFAULT_METRICDONERESULT_DUPLICATESHOULD_CHECKPOINTSTDERR_FILESTDOUT_FILE
TRIAL_INFO)FIFOSchedulerTrialScheduler)BasicVariantGeneratorSearchAlgorithm)NoopStopperStopper)ResumeConfig)flatten_dictwarn_if_slow)	Verbosity_dedup_logshas_verbosity)_ObjectCache)_ResourceUpdater)TuneFunctionDecoderTuneFunctionEncoder)DeveloperAPI)log_oncec                   n   e Zd ZdZdZddddddddddddddddee         deeee	f                  dee
         d	ee         d
ee         dedeeef         deee                  dee         dee         dee         dedeeg ef                  defdZd Zed             Zed             Zed             Zdee         deddfdZddZedefd            Z edefd            Z!edefd             Z"d! Z#d" Z$dd#ed$efd%Z%d&ee&         d
efd'Z'd(edee&         fd)Z(d
efd*Z)dd+ee         fd,Z*d-ee+e,f         fd.Z-d/ Z.d0 Z/d1 Z0d2 Z1d3e&fd4Z2dd6ed7edefd8Z3defd9Z4d: Z5d; Z6dd<efd=Z7dd<efd>Z8d? Z9d3e&d@efdAZ:deeef         fdBZ;d3e&fdCZ<dD Z=dE Z>dFe?fdGZ@ddHZAd3e&defdIZBd3e&fdJZCd3e&fdKZDd3e&defdLZEddFe?dNefdOZFdFe?fdPZGdFe?dQeHfdRZI	 	 	 	 	 dd3e&dSedTee         dUee         dVeee&e	gdf                  dWeee&eHgdf                  dXedeeJjK                 fdYZLdZ ZMdd3e&d[ed\efd]ZNdd3e&d\efd^ZOd_ ZPd3e&dQeHfd`ZQd3e&dQeeReSeTf         fdaZUdd3e&dQeeH         fdbZVdc ZWd3e&fddZXdd3e&dfefdgZYd3e&fdhZZd3e&deee[f         fdiZ\dj Z]dk Z^d3e&dle+ee	f         fdmZ_dn Z`	 dd3e&dlee         deea         fdoZbdpecfdqZdd3e&dpecfdrZeddsZfd3e&defdtZgd3e&dle	fduZhd3e&fdvZid3e&dweeReSeTf         fdxZjdy Zkd3e&fdzZld3e&d{ed|efd}Zmd3e&d~efdZnd Zod Zpd Zqdd3e&dfefdZrd Zsd Ztd ZudS )TuneControllerzexperiment_state-{}.jsonRAISENF)
search_algplaceholder_resolvers	schedulerstopperresume_config	fail_fastcheckpoint_period	callbacksmetrictrial_checkpoint_configstoragereuse_actorsresource_manager_factory_trainer_apirJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   c                `
   |r |            }nt                      }t          |          | _        t                      | _        t          d           | _        i | _        i | _        t          t                    | _        t                      | _        g | _        t                      | _        t                      | _        t                      | _        t                      | _        t                      | _        t                      | _        t                      | _        i | _        t-          d          | _        t1          t2          j                            dd                    | _        d| _        || _        t?          d          | _         t                      | _!        i | _"        t1          t3          j#        dd	                    | _$        t-          t3          j#        d
d                    | _%        t-          t3          j#        dd                    | _&        |ptO                      | _(        || _)        |ptU                      | _+        tY          |pg           | _-        t]          |          | _/        i | _0        tc          | j(                  | _2        || _3        |	| _4        d| _5        d| _6        d| _7        || _8        ts          | j8        tt                    r[| j8        ;                                | _8        | j8        | j<        k    rt{          j>        d           nt          d| j8         d          t          t1          t2          j                            dd                              | _A        g | _B        t                      | _C        i | _D        i | _E        g | _F        d| _G        |pt                      | _I        t          jJ                    | _K        t          jM        | jK                  N                    d          | _O        |t3          j#        dd          }|| _P        |
pt                      | _R        | S                                | _T        d| _U        |	 | V                    |           d| _U        d S # t          $ r}t          t          jZ                  r't          \                    tu          |                     t          ]                    d           | j8        r t          ^                    d           Y d }~d S d }~ww xY wt          _                    d           d S )N)resource_managerinfTUNE_FORCE_TRIAL_CLEANUP_S600
   T)may_keep_oneTUNE_RESULT_BUFFER_LENGTH   TUNE_RESULT_BUFFER_MIN_TIME_Sg        TUNE_RESULT_BUFFER_MAX_TIME_Sg      Y@)	for_trainr   Fzfail_fast='raise' detected. Be careful when using this mode as resources (such as Ray processes, file descriptors, and temporary files) may not be cleaned up properly. To use a safer mode, use fail_fast=True.z,fail_fast must be one of {bool, RAISE}. Got .TUNE_PRINT_ALL_TRIAL_ERRORS1z%Y-%m-%d_%H-%M-%STUNE_GLOBAL_CHECKPOINT_Sauto)rN   z Failed to restore the run state.zRestarting experiment.zStarting a new experiment.)`r   r   _actor_managerr!   _class_cacherB   _resource_updater_actor_to_trial_trial_to_actorr   set_resources_to_pending_trials_pending_trials_pending_trials_list_running_trials_paused_trials_stopped_trials_failed_trials_resetting_trials_staged_trials_started_actors_stopping_actorsfloat_earliest_stopping_actorintosenvironget_actor_cleanup_timeout_actor_force_cleanup_timeout_reuse_actorsrA   _actor_cache_trials_to_cache_trial_metadatagetenv_buffer_length_buffer_min_time_s_buffer_max_time_sr7   _search_alg_placeholder_resolversr5   _scheduler_algr   
_callbacksr$   _insufficient_resources_manager_pending_trial_queue_times_get_max_pending_trials_max_pending_trials_storage_metric_total_time
_iteration_has_errored
_fail_fast
isinstancestrupperrI   warningswarn
ValueErrorbool_print_trial_errors_trials_live_trials_cached_trial_decisions_queued_trial_decisions_stop_queue_should_stop_experimentr9   _stoppertime_start_timer   fromtimestampstrftime_session_str_checkpoint_periodr   _trial_checkpoint_config_create_checkpoint_manager_checkpoint_manager_resumedresume	Exceptionr@   r>   V3_TRIAL_DETAILSloggererror	exceptioninfodebug)selfrJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rY   es                    v/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/tune/execution/tune_controller.py__init__zTuneController.__init__H   s   $ $ 	?7799<>>-?OPPP,.. "2$!7!7 ;=:<
  	)
 ,/5513!+.55*-%%+.55*-%%-0UU*-%% 36%%  <>/4U||%+.JNN7??,
 ,
# 24) *(d;;; -0EE/1 ""),G"K"KLL"'	2QSV(W(W"X"X"'I5u==#
 #

 &@)>)@)@&;#':=??&yB77/L"0
 0
 0
, +-'#:4;K#L#L !#dos++ 	"o3355DO$*,,8    !XdoXXX   $(
<cBBCC$
 $
  %'(+')$')$',$0;==9;;$243CDDMM
 
 $ "	*Df M M"3(?(UCSCUCU%#'#B#B#D#D $	6-888 $ 6 6 6 !;<< )LLQ(((  !CDDD? 45555555556 LL566666s   !R   
T
A<TTc                 J    t          | t          |           h dh d          S )zCReturn wrapped tune controller to be passed to scheduler/searchers.>   
get_trialsrJ   
stop_trialpause_trialget_live_trials_set_trial_status_schedule_trial_save>   saver   rk   has_resources_for_trial)trial_executorrunner_whitelist_attrexecutor_whitelist_attr)TrialRunnerWrapper_FakeRayTrialExecutorr   s    r   _wrappedzTuneController._wrapped   sE    !066# # #% % %
 
 
 	
    c                     | j         S N)r   r   s    r   resumedzTuneController.resumed  s
    }r   c                     | j         S r   )r   r   s    r   rJ   zTuneController.search_alg  s    r   c                     | j         S r   )r   r   s    r   scheduler_algzTuneController.scheduler_alg  s    ""r   experimentstotal_num_samplesreturnc                 Z    |d         }|r|j         ni }||d<    | j        j        di | dS )a#  Obtains any necessary information from experiments.

        Mainly used to setup callbacks.

        Args:
            experiments: List of Experiments
                to use.
            total_num_samples: Total number of samples
                factoring in grid search samplers.
        r   r   N )public_specr   setup)r   r   r   
experimentspecs        r   setup_experimentsz TuneController.setup_experiments  sK     !^
)3;z%%$5 !%%%%%%%r   c                 F    | j                             | j                   dS )z0Calls ``on_experiment_end`` method in callbacks.)trialsN)r   on_experiment_endr   r   s    r   end_experiment_callbacksz'TuneController.end_experiment_callbacks&  s#    )))>>>>>r   c                 @    | j                             | j                  S r   )CKPT_FILE_TMPLformatr   r   s    r   experiment_state_file_namez)TuneController.experiment_state_file_name*  s    "))$*;<<<r   c                 d    t          | j        j        | j                                                  S )z-Returns the local experiment checkpoint path.)r   r   experiment_driver_staging_pathr   as_posixr   s    r   experiment_state_pathz$TuneController.experiment_state_path.  s/     M8+
 
 (**	r   c                     | j         j        S r   )r   experiment_fs_pathr   s    r   experiment_pathzTuneController.experiment_path6  s    }//r   c                 N    t          | j        | j        | j        j                  S )N)rT   rP   sync_every_n_trial_checkpoints)r"   r   r   r   num_to_keepr   s    r   r   z)TuneController._create_checkpoint_manager:  s-    +M"5+/+H+T
 
 
 	
r   c                    t          |                                                                           |                                 d| j        id}| j        j        }t          j        |d           t          t          || j                  d          5 }t          j        ||t                     ddd           n# 1 swxY w Y   | j                            || j                   | j                            || j                   dS )	a  Save TuneController state to the local staging experiment directory.

        This includes:
        - trial states
        - TuneController internal state (all the serializable attributes)
        - the searcher state
        - the callback states
        
start_time)
trial_datarunner_datastatsT)exist_okwclsN)session_str)list_get_trial_checkpointsvalues__getstate__r   r   r   r}   makedirsopenr   r   jsondumprD   r   save_to_dirr   r   )r   runner_statedriver_staging_pathfs       r   r  zTuneController.save_to_dirA  sX    t::<<CCEEFF,,.."D$45
 
 #mJ
'$7777$d&EFF
 
 	@ IlA+>????		@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	$$%8dFW$XXX##$7TEV#WWWWWs   B??CCforcewaitc                 J    | j                             | j        ||           d S )N)save_fnr  r  )r   sync_up_experiment_stater  )r   r  r  s      r   
checkpointzTuneController.checkpoint_  s6     99$E 	: 	
 	
 	
 	
 	
r   r   c                    t          |d d          D ]=}|j        t          j        k    r|j        }n$|j        t          j        k    r|j        }n|j        }d }|t          j	        j
        k    r:|}d |j        _        d |j        _        |                    t          j                   n|t          j	        j        k    r|                                }d |_        n^|t          j	        j        k    r7|}|j        t          j        k    r|                    t          j                   nt)          d|           |J |                     |           ?d S )Nc                     | j         j        S r   )run_metadatalast_result_time)ts    r   <lambda>z9TuneController._requeue_restored_trials.<locals>.<lambda>i  s    !."A r   T)keyreversezUnknown resume type: )sortedstatusr'   ERRORerrored
TERMINATEDfinished
unfinishedr;   
ResumeTypeRESUMEr  error_filenamepickled_error_filename
set_statusPENDINGRESTARTresetrestore_pathSKIPr   	add_trial)r   r   rN   trialresume_typetrial_to_adds         r   _requeue_restored_trialsz'TuneController._requeue_restored_trialsd  s_    AA4
 
 
 	) 	)E |u{**+3!111+4+6Ll5<<<$;?)8CG)@''6666 7 ???${{}},0)) 7 <<<$&%+55 !++E,<=== !F!F!FGGG+++NN<((((=	) 	)r   experiment_statec                    g }|d         D ]\  }}t          j        |          }|                    |           t          j        |j                  }| j        j        |_        | j        j        |_        | j        j        |_        |	                    |           t          j        j        j
                                        s|                                 |                    |           |d         j        j        | j        _        |S )Nr   r   )r'   from_json_staterestore_run_metadatacopyrT   r   storage_filesystemstorage_fs_pathexperiment_dir_nameset_storagerayutilclientis_connectedinit_local_pathappend
_timestamp)r   r*  r   trial_json_statetrial_runtime_metadatar&  new_storages          r   _restore_trialszTuneController._restore_trials  s    8H8V 	! 	!44)*:;;E&&'=>>> )EM22K-1]-MK**.-*GK'.2m.OK+ k***
 8?&3355 (%%'''MM%     $*!9#4#? r   c                 t   t          | j        j        | j        j                  }|*t	          d| j        j         dt
          j         d          t                              dt          |          j
                    | j        j                            |          5 }t          j        |                                t                    }ddd           n# 1 swxY w Y   |                     |d                    |                     |          }| j                                         | j        j        }| j                            |          r| j                            |           | j                            |          r| j                            |           |                     ||           dS )	zResumes all checkpointed trials from previous run.

        Requires user to manually re-register their objects. Also stops
        all ongoing trials.
        )fsNz+Tried to resume experiment from directory 'z-', but no experiment state file of the form 'zD' was found. This is expected if you are launching a new experiment.z9Restoring the run from the latest experiment state file: r   r   )r#   r   r   r/  r   rH   r   r   r   r   nameopen_input_streamr   loadsreadallrC   __setstate__r=  r   sync_down_experiment_stater   r   has_checkpointrestore_from_dirr   can_restorer)  )r   rN   newest_state_pathr  r*  r   driver_staging_dirs          r   r   zTuneController.resume  s    ?M,1Q
 
 
 $UM4U U6D6SU U U   	.%&&+. .	
 	
 	
 ]-??@QRR 	PVW#z!))++;NOOO	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	*=9::: %%&677 	 ;;===!]I**+=>> 	B--.@AAA?&&'9:: 	AO,,-?@@@ 	%%fm<<<<<s    .CC!Cmax_pending_trialsc                 <    |pt          | j                  | _        d S r   )r   r   r   )r   rK  s     r   update_max_pending_trialsz(TuneController.update_max_pending_trials  s(    #5 $
9P:
 :
   r   	resourcesc                     |sJ t          |t                    r	d|vrd|d<   | j        D ]-}|j        t          j        k    r|                    |           .dS )zgUpdate trial resources when resuming from checkpoint.

        Only updating the pending ones.
        gpur   )rN  N)r   dictr   r  r'   r   update_resources)r   rN  r&  s      r   update_pending_trial_resourcesz-TuneController.update_pending_trial_resources  sw     yi&& 	!5	+A+A Ie\ 	< 	<E|u},,&&&;;;	< 	<r   c                     t          | j                  dk    pt          d | j        D                       ot          d | j        D                       }|o| j                                        S )z1Returns whether all trials have finished running.r   c              3   >   K   | ]}|                                 V  d S r   is_finished.0r&  s     r   	<genexpr>z-TuneController.is_finished.<locals>.<genexpr>  s.      FF55$$&&FFFFFFr   c              3   >   K   | ]}|                                 V  d S r   rV  rX  s     r   rZ  z-TuneController.is_finished.<locals>.<genexpr>  s.      @@%%##%%@@@@@@r   )lenr   allr   r   rW  )r   trials_dones     r   rW  zTuneController.is_finished  s     !""a' GFFD4EFFFFFA @@4<@@@@@ 	 =t/;;===r   c                 B    fd| j         D             }|r|d         nd S )Nc                 *    g | ]}|j         k    |S r   trial_id)rY  r  tids     r   
<listcomp>z,TuneController.get_trial.<locals>.<listcomp>  s%    >>>qAJ#,=,=,=,=,=r   r   r   )r   rc  r&  s    ` r   	get_trialzTuneController.get_trial  s1    >>>>DL>>> *uQxxd*r   c                     | j         S )zReturns the list of trials managed by this TrialRunner.

        Note that the caller usually should not mutate trial state directly.
        re  r   s    r   r   zTuneController.get_trials  s    
 |r   c                     | j         S )zAReturns the set of trials that are not in Trial.TERMINATED state.)r   r   s    r   r   zTuneController.get_live_trials   s      r   r&  c           
         | j         r|                    | j                    |                                 | j                            |           |j        t          j        k    r| j        	                    |           t          d          5  | j                            |                                 |           ddd           n# 1 swxY w Y   |                     |           t                              d| d|j                    t          j        | j        t          j        | j        t          j        | j        t          j        | j        t          j        | j        i}||j                 	                    |           |j        t          j        k    rA| j                            |           | j        |j                 	                    |           dS dS )zAdds a new trial to this TrialRunner.

        Trials may be added at any time.

        Args:
            trial: Trial to queue.
        scheduler.on_trial_addNzAdding trial z with status )r   resolve_config_placeholderscreate_placement_group_factoryr   r8  r  r'   r  r   addr=   r   on_trial_addr   _mark_trial_to_checkpointr   r   r   rp   RUNNINGrr   PAUSEDrs   rt   r  ru   rq   ro   placement_group_factory)r   r&  status_str_maps      r   r%  zTuneController.add_trial  s    & 	K--d.IJJJ 	,,...E"""<5+++!!%(((233 	E 	E,,T]]__eDDD	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E&&u---GUGGGGHHH M4/M4/L$-d2K,
 	u|$((///<5=((%,,U333-e.KLPPQVWWWWW )(s   .CCCX  blockingtimeoutc                    | j                                         }|r|st          j                    }|s|                                 st          j                    |z
  |k     rwt                              d           | j                                         }t          j        d           |s.|                                 st          j                    |z
  |k     w|r|                     |           dS dS )a  Adds next trials to queue if possible.

        Note that the timeout is currently unexposed to the user.

        Args:
            blocking: Blocks until either a trial is available
                or is_finished (timeout or search algorithm finishes).
            timeout: Seconds before blocking times out.

        Returns:
            Boolean indicating if a new trial was created or not.
        zBlocking for next trial...r`   TF)r   
next_trialr   rW  r   r   sleepr%  )r   ru  rv  r&  starts        r   _update_trial_queuez"TuneController._update_trial_queue+  s      ++-- 
	E 
	IKKE
 "&"2"2"4"49=u9Lw9V9V9:::(3355
1	 "&"2"2"4"49=u9Lw9V9V  	NN5!!!4ur   c                 h    | j                                         }| j                            |          S r   )ri   get_live_actors_resourcesrk   debug_string)r   allocated_resourcess     r   _used_resources_stringz%TuneController._used_resources_stringK  s/    "1KKMM%223FGGGr   c                 8    | j                                          d S r   )rk   update_avail_resourcesr   s    r   on_step_beginzTuneController.on_step_beginP  s    5577777r   c                 ^    |                      d           |                     d           d S )NF	force_all)_cleanup_cached_actors_cleanup_stopping_actorsr   s    r   on_step_endzTuneController.on_step_endS  s6    ##e#444%%%66666r   r  c                 `   | j                                         r| j        s| j        j        dk    rd}| j                            |          D ]_}t                              d|            |                    d            |	                    d            | 
                    |           `d S )Nr   Tr  zCleaning up cached actor: tracked_actor)r   rW  rw   r   total_max_objectsflush_cached_objectsr   r   set_on_stopset_on_error_remove_actor)r   r  r  s      r   r  z%TuneController._cleanup_cached_actorsW  s    ((**	'	 !3q88
 I!.CC D 
 
 	< 	<M LLEmEEFFF%%d+++&&t,,,];;;;	< 	<r   c                    t          j                    }|s|| j        z
  | j        k    rd S t	          t          d | j                                        D             d                     }|r\|s,t          j                    |d         d         z
  | j        k    r.t          j                    |d         d         z
  | j        k     rC| j	        
                    |d         d                   r| j	                            d           |                                \  }}|| j        vr| j	        
                    |          r9t                              d|            | j	                            |d	
           | j                            |           |r/|t          j                    |d         d         z
  | j        k    .|r|d         d         | _        d S t#          d          | _        d S )Nc                     g | ]	\  }}||f
S r   r   )rY  r  	timestamps      r   rd  z;TuneController._cleanup_stopping_actors.<locals>.<listcomp>x  s1       0y .  r   c                     | d         S )Nr   r   )items    r   r  z9TuneController._cleanup_stopping_actors.<locals>.<lambda>|  s
    a r   )r  r   r`   r  rv  zForcefully killing actor: T)r  killrZ   )r   	monotonicr{   r   r   r  ry   itemsr   ri   is_actor_startednextpopleftr   r   remove_actorpoprz   )r   r  nowtimes_r  s         r   r  z'TuneController._cleanup_stopping_actorsk  s"   n 	d33t7RRR F  484I4O4O4Q4Q   )(  
 
  	5	5))E!HQK7$:UUU   58A;.1RRR%66U1Xa[6QQ S #(((333$}}A}D$999"33-3PP YI-IIJJJ#00}SW0XXX!%%m444'  	5	5))E!HQK7$:UUU(  	9,1!HQKD))),1%LLD)))r   c                 T   |                                  rt          d          t          d          5  |                                  d d d            n# 1 swxY w Y   t          d          5  | j                            | j        | j                   d d d            n# 1 swxY w Y   |                                  |                                  | j	        
                    d          s8| j	        j        s,| j                            |                                            |                                  	 |                                  n># t"          $ r1}t$                              dt)          |                      |d }~ww xY w| xj        dz  c_        t          d	          5  |                                  d d d            n# 1 swxY w Y   t          d
          5  | j                            | j        | j                   d d d            d S # 1 swxY w Y   d S )Nz%Called step when all trials finished?r  zcallbacks.on_step_begin)	iterationr   g?r  z'Trial controller checkpointing failed: r`   r  zcallbacks.on_step_end)rW  r   r=   r  r   r   r   _maybe_update_trial_queue_maybe_add_actorsri   r  num_live_actorsr   on_no_available_trialsr   _stop_experiment_if_neededr  r   r   warningr   r  )r   r   s     r   stepzTuneController.step  sE    	ECDDD/** 	! 	!   	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 344 	 	O))/$, *   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	&&((( 	    "'''44 	 &6 4KKOO%%  
 	'')))	OO 	 	 	NNMSVVMMNNNG	 	1-(( 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	122 	X 	XO''$/$,'WWW	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	Xs_   AAA.'B!!B%(B%<E 
F,FF.GGG)'HH!$H!r  c           
      2   |j         }||k    r#t                              d| d| d           dS t          j        | j        t          j        | j        t          j        | j	        t          j
        | j        t          j        | j        i}t                              d| d| d|            |||         v sJ ||f            |||         vsJ ||f            ||                             |           ||                             |           |t          j        k    r@| j                            |           | j        |j                                     |           n%| j        |j                                     |           |                    |           dS )a  Set trial to a specific status.

        This will keep track of trials with specific statuses in sets.

        For PENDING and PAUSED trials we also keep a list of trials to be able
        to retain FIFO ordering. See ``_maybe_add_actors`` for details.

        Lastly we also keep a mapping from resources to pending/paused trials
        to be able to efficiently start trials for cached actors.
        Trial z already has status z. Skipping update.NzSetting status for trial z from z to )r  r   r   r'   r   rp   rp  rr   rq  rs   r  rt   r  ru   removerm  rq   r8  ro   rr  discardr  )r   r&  r  current_statusrs  s        r   r   z TuneController._set_trial_status  s    V##LLW%WWVWWWXXXF M4/M4/L$-d2K,
 	QQQ^QQQQ	
 	
 	
 ~66668O666N62222UFO222~&--e444v""5)))
 U]""%,,U333-e.KLPPQVWWWW-e.KLTT   	     r   c                     | j         D ]#}|                                | j        |j        <   $| j                                          | j        S r   )r   get_json_stater   rb  clearr   r&  s     r   r   z%TuneController._get_trial_checkpoints  sR    * 	J 	JE383G3G3I3ID 00##%%%##r   c                 :    | j                             |           d S r   )r   rm  r  s     r   ro  z(TuneController._mark_trial_to_checkpoint  s    !!%(((((r   c                    | j                                         rdS | j        p| j        p| j        }t          | j                  | j        k     r:|                     |           sdS d}t          | j                  | j        k     8dS dS )z!Ask the searcher for more trials.N)ru  T)r   rW  rp   rr   rs   r\  r   r{  )r   dont_wait_for_trials     r   r  z(TuneController._maybe_update_trial_queue  s    '')) 	F  OD$8OD<O 	 $&''$*BBB++9L5L+MM "& $&''$*BBBBBBBr   c                    t                               d           t          | j                  D ]D}| j        |         }t                               d| d|            |                     |           E|                     d           t          j                    }t          j                    |z
  dk     r| j        j	        rxt          dt          |                    rt                               d           | j                            d	
           t          j                    |z
  dk     r| j        j	        xt                               d           |                     d           | j                                         d S )NzCLEANING UP all trialsz2Scheduling trial stop at end of experiment (trial z): Tr     actor_manager_cleanupz9Waiting for actor manager to clean up final state [dedup]r`   r  z!Force cleanup of remaining actors)r   r   r   rl   _schedule_trial_stopr  r   r  ri   num_total_actorsr?   r   r  r  cleanup)r   r  r&  rz  s       r   _cleanup_trialszTuneController._cleanup_trials  s   -...!$"677 	- 	-M(7ELL#U # # # #   %%e,,,, 	##d#333  n&**t/B/S*2CJJ?? O   $$Q$/// n&**t/B/S* 	8999%%%555##%%%%%r   r  c                     | j                             |dd          }t          j                    }| j                             |d|          r&|| j        |<   t          | j        |          | _        d S d S )NstopT)_return_futureF)r  stop_future)ri   schedule_actor_taskr   r  r  ry   minr{   )r   r  r  r  s       r   r  zTuneController._remove_actor*  s    )==6$ > 
 
 n++; , 
 
 	T 47D!-0,/0Ms,S,SD)))	T 	Tr   c                 *    t          d          5   j                                                                       }ddd           n# 1 swxY w Y   |rt	          d|j                  rt                              d| d           | j        vr| j	        vrt                              d|             
                    |t          j                    j                            |            j                            |j                                        |           nHt	          d|j                  rt                              d| d                                |           d	t&          t                   f fd
} | j                   _         j        j        r j        D ]} j        |         s j                            |          s+ j        |                                         }t                              d|                                 |          s! j        |                             |           | j        vr9 j                            |            j                            |j                   dS dS )a;  Add actors for pending and paused trials.

        For actors that have not been staged, yet, we request an actor.

        For actors that have been staged, already, we try to reuse a cached actor.

        First, we handle the trial that the scheduler chooses to run.

        Then, we handle all trials that are pending.

        Lastly, we see if we have cached actors that we can assign to a pending or
        paused trial. This can be the case when a trial has not been staged, yet,
        for instance because the number of staging trials was too large.
        choose_trial_to_runNtrial_to_run_chosenz#Chose trial to run from scheduler: z [dedup]zStaging trial to run: trial_to_run_reusez)Trying to re-use actor for trial to run: 
candidatesc                    g }| rj         j        j        k    rn|                     d          }|j        vr7|j        v r|                    |           V|j        v r                    |           ut          
                    d|            j                            |           j                            |j                                       |           | || z   S )Nr   z%Scheduling actor for enqueued trial: )ri   num_pending_actorsr   r  rp   rm   r8  rw   _maybe_reuse_cached_actorr   r   rm  r   increase_maxrr  _schedule_trial_actor)r  new_candidatesr&  r   s      r   r  z;TuneController._maybe_add_actors.<locals>._maybe_add_actorsh  s   N 2&9T=UUU"q))
  444D000"))%000D///225999LULLMMM#''...!..u/LMMM**5111/  22 "J..r   z+Trying to re-use actor for enqueued trial: )r=   r   r  r   r?   rb  r   r   rw   rm   r   r'   r   rm  r   r  rr  r  r  r   rq   num_cached_objectsro   has_cached_objectr  )r   trial_to_runr  resourcestart_trials   `    r   r  z TuneController._maybe_add_actors9  s-   $ /00 	T 	T.BB4==??SSL	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T  	=0,2GHH P,PPP   D$777 (<<<DlDDEEE&&|U]CCC#''555!..|/STTT**<8888 3\5JKK LL#L # # #   ..|<<<	/$u+ 	/ 	/ 	/ 	/ 	/ 	/< %6$5d6O$P$P! / 	 =  8B (::8DD "?IMMOOO+OO   55kBB 5h?CCKPPPP"$*===+//<<<)66'?  #	 	 s   -A

AAc                    || j         v rdS |j        }| j                            |          sdS | j                            |          }t
                              d| d|            || j        v rj| j                            |          }| j	                            |           t
                              d| d|            | 
                    |           || j        |<   || j	        |<   | j        j        |         d         }|                    |           |                     ||j        |j                   dS )zMaybe reuse a cached actor for a trial.

        If an actor has been scheduled for the trial already,
        this will remove the original actor.
        TFzReusing ACTOR for trial : z"Removing ORIGINAL ACTOR for trial r  r   )rv   rr  r   r  pop_cached_objectr   r   rm   r  rl   r  ri   $_live_actors_to_ray_actors_resourcesset_ray_actor_schedule_trial_resetconfigexperiment_tag)r   r&  resource_requestcached_actororiginal_actor	ray_actors         r   r  z(TuneController._maybe_reuse_cached_actor  s]    D***4 8 223CDD 	5(::;KLLGGGGGHHHD(((!155e<<N $$^444LLWeWW~WWXXX^<<<&2U#-2\* 'L

	 	I&&&""5%,8LMMMtr   c           	         t                               d|            |j        t          j        k    sJ |                                 |                     |           |                     |          rdS || j        v rt          d| d          |
                                }|sFt          d|j         d          }|                    |           |                     ||           dS | j                            |          }|                    t%                                 t'          |          }t)          |          5  | j                            ||j        || j        | j        | j        	          }|| j        |<   || j        |<   ddd           n# 1 swxY w Y   t                               d
| d| d|j                    dS )zSchedule an actor for a trial.

        If a cached actor is available, use it. Otherwise, request a
        new actor.
        z'Trying to schedule new ACTOR for trial Nz'Tried to request a new actor for trial z, but an old actor still exists. This can lead to leaked resources. The old actor should be removed first. This is an internal problem in Ray Tune. If you encounter this error, please raise an issue on https://github.com/ray-project/ray/issueszInvalid trainable: zH. If you passed a string, make sure the trainable was registered before.r   r&  )r   r  kwargson_starton_stopon_errorzScheduled new ACTOR for trial r  z. Resources: )r   r   r  r'   r   r7  ro  r  rm   RuntimeErrorget_trainable_clsr   trainable_namehandle_errorr  rj   r   set_locationr*   r)   r(   ri   	add_actorrr  _actor_started_actor_stopped_actor_failedrl   )r   r&  trainable_clsr   
_actor_clstrainable_kwargsr  s          r   r  z$TuneController._schedule_trial_actor  sp    	FuFFGGG|u},,,,&&u---))%00 	F D(((=% = = =   //11 	,Le&: L L L I y)))%%ey%AAAF&**=99
9;;'''0u===&u-- 
	8 
	8 /99!&!>',++ :  M +8D '27D /
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 
	8 	:U : :m : :7: :	
 	
 	
 	
 	
s   A	FF #F c                 j   || j         v r;| j                             |           | j                            |j                   dS |j        }d}| j         D ]}|j        }||k    r|} n|r;| j                             |           | j                            |j                   dS t          d          )z;Unstage trial, or one with the same resources as ``trial``.NzStarted a trial with resources requested by a different trial, but this trial was lost. This is an error in Ray Tune's execution logic. Please raise a GitHub issue at https://github.com/ray-project/ray/issues)rw   r  r   decrease_maxrr  r  )r   r&  r  candidate_trialstaged_trialstaged_resourcess         r   _unstage_trial_with_resourcesz,TuneController._unstage_trial_with_resources   s     D'''&&u---**5+HIIIF !8 / 	 	L+C#333". 4  	&&777**?+RSSSF8
 
 	
r   c                    | j         sdS | j                                        r'| j        s t                              d| d           dS | j        |         }| j                            |          r#| j        	                    |          s	|| j
        vr"t                              d| d|            dS | j                            |j        |          s t                              d| d           dS t                              d| d|            | j                            |          }| j                            |           |                    d	           d
S )a  Cache trial actor for reuse, if needed.

        We will only cache as many actors as are needed to fulfill any pending
        resource requests for actors with the same resource requirements.
        E.g. if we have 6 running trials and 4 additional staged actors, we will only
        cache up to 4 of the running trial actors when they finish.

        One exception is the case when we have no cached actors, yet. In that case,
        we will always cache the actor in this method.

        Later, in `_cleanup_cached_actors`, we will check again if we need this cached
        actor. That method will keep the actor if we don't have any staged trials,
        because we don't know at that point if the next trial might require the same
        resources. But because there is no staged trial, it is safe to keep the actor
        around, as it won't occupy resources needed by another trial until it's staged.
        FzNot caching actor of trial z5 as the search is over and no more trials are staged.z" as it has not been started, yet: zCould not cache actor of trial zC for reuse, as there are no pending trials requiring its resources.zCaching actor of trial z for re-use: NT)r   r   rW  rw   r   r   rm   ri   r  is_actor_failedrx   r   cache_objectrr  r  rl   r  )r   r&  r  s      r   _maybe_cache_trial_actorz'TuneController._maybe_cache_trial_actor"  s   " ! 	5'')) 	$2E 	LL2e 2 2 2   5,U3 #44]CC		"22=AA		 D$888LL#e # # # #   5 --)=
 
 	 LL+% + + +  
 5RuRR=RRSSS,0077  ///D!!!tr   STARTEDlogc                 .   | j                             |           | j        |         }t                              d| d| d|            |                     |           | j        j        |         d         }|                    |           | j	        
                    | j        | j        |           |                     |t          j                   |                     |           |                     |          s|                     |           d S d S )NzActor  for trial r  r   r  r   r&  )rx   rm  rl   r   r   r  ri   r  r  r   on_trial_startr   r   r   r'   rp  ro  _schedule_trial_restore_schedule_trial_train)r   r  r  r&  r  s        r   r  zTuneController._actor_started]  s(     ///$]3FcFFeFF}FFGGG**5111'L

	 	I&&&&&odl% 	' 	
 	
 	
 	uem444&&u---++E22 	.&&u-----	. 	.r   c                    || j         v ri| j                             |          }t                              d| d|            | j                            |           |                    d            t                              d|            | j                            |d            | j                            |           d S )NzActor STOPPED for trial r  zActor STOPPED: )	rl   r  r   r   rm   r  ry   rx   r  )r   r  r&  s      r   r  zTuneController._actor_stoppedv  s    D000(,,];;ELLLELL]LLMMM $$U+++%%%6}66777!!-666$$]33333r   r   c                 F   | j         |         }t                              d| d| d|            || j        | j        z  v rj|                     |t          j                   t                              d| d           |                     |           | 	                    ||           | j
                            |           |                    d            |                    d            | j
                            |d           |                     |           d S )	NzActor FAILED for trial r  z. Exception: r  zG failed in its creation task. Unstaging to allow it to be re-scheduled.r  F)r  )rl   r   r   rp   rs   r   r'   rp  r  _trial_task_failureri   clear_actor_task_futuresr  r  r  r  )r   r  r   r&  s       r   r  zTuneController._actor_failed  sS   $]3&e & &} & &#& &	
 	
 	

 T)D,??@@""5%-888LL3 3 3 3  
 ..u555$$Ui$@@@44]CCC 	!!$'''""4(((((U(CCC 	M*****r   method_nameargsr  	on_resultr  r  c           
           j                  }d}	d}
|pt                      }|pi }rdt          f fd}	rdt          dt          f fd}
t                              d                                 d            t                    5   j        	                    ||||	|
|          }|r|cddd           S 	 ddd           dS # 1 swxY w Y   dS )	a7  Schedule an actor task future for a trial.

        This is a wrapper around ``ActorManager.schedule_actor_task``. This method
        retrieves the tracked actor for a trial to kick off the task.

        It also wraps around the callbacks, retrieving the trial object given the
        tracked actor.
        Nr  c           
         j         |          k    sJ t                              d                                 d d| d|            	  g|R i | d S # t          $ ru}t                              d                                 d d|            |t
          u sj        j        k    r|t          t          j	                              d }~ww xY w)NFuture z RESOLVED for trial r  z, Error handling z result for trial )
rl   r   r   r   r   r   r   rI   	traceback
format_exc)r  r  r  r   r
  r  r   r&  s       r   
_on_resultz7TuneController._schedule_trial_task.<locals>._on_result  sF    4] CCCCC(k//11 ( (u ( (( (%( (  
@Ie5d555f55555  @ @ @LL2+*;*;*=*= 2 2%*2 2./2 2   I~~DJ)F)F'	(<(>(>???@s   A 
C&A0CCr   c           	      "   | j         vr-t          |t                    sJ t          |                      nj         |          k    sJ t                              d                                 d d|            	  |           d S # t          $ ru}t                              d                                 d d|            |t          u sj	        j
        k    r|t          t          j                              d }~ww xY w)Nr  z FAILED for trial r  r  z failure for trial )rl   r   r   typer   r   r   r   r   r   rI   r  r  )r  r   r   r
  r  r   r&  s      r   	_on_errorz6TuneController._schedule_trial_task.<locals>._on_error  s`    (<<<%i??PPiPP?P D$8$GGGGG#k//11 # #U # # # #  
@HUI.....  @ @ @LL2+*;*;*=*= 2 2%*2 2./2 2   I~~DJ)F)F'	(<(>(>???@s   B 
DA0D		Dr  z SCHEDULED for trial )r  r
  r  r  r  r  r  )
rm   tupler   r   r   r   r   r(   ri   r  )r   r&  r
  r  r  r  r  r  r  r  r  futures   ```  ``     r   _schedule_trial_taskz#TuneController._schedule_trial_task  s   & ,U3
	uww2 	@@, @ @ @ @ @ @ @ @ @$  	@@ @) @ @ @ @ @ @ @ @ @. 	P{0022PPPPQQQ&u-- 	 	(<<+'$"- =  F  	 	 	 	 	 	 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   %CCCc                     | j                             |j        |          }|t          j        u rd S |t          j        u s|t          j        u r|| j         |j        <   d S d S r   )r   
setdefaultrb  r6   STOPPAUSE)r   r&  decisionold_decisions       r   _queue_decisionzTuneController._queue_decision  sl    3>>u~xXX >...F
 ~***h.:N.N.N;CD(888 /O.Nr   r  
after_savec                 Z   |t           j        k    r|                     |           dS |t           j        k    r|                     ||            dS |t           j        k    r|                     |           dS |t           j        k    rdS t          d	                    |                    )zExecutes action based on decision.

        Args:
            trial: Trial to act on.
            decision: Scheduling decision to undertake.
        should_checkpointzInvalid decision: {}N)
r6   CONTINUEr  r  r   r  r   NOOPr   r   )r   r&  r  r!  s       r   _execute_actionzTuneController._execute_action  s     ~...&&u--------U*nEEEEE,,,OOE""""",,,D3::8DDEEEr   c                     | j                             |j        d           }|r:t                              d| d|            |                     |||           d S d S )Nz$Executing final queued decision for r  r!  )r   r  rb  r   r   r'  )r   r&  r!  final_decisions       r   _maybe_execute_queued_decisionz-TuneController._maybe_execute_queued_decision  s     599%.$OO 	OLLPuPPPP     : NNNNN		O 	Or   c                       j         o j        } j                                        s	|s j        r. j                                          fd j        D              dS dS )zStops all trials.c                 x    g | ]6}|j         t          j        t          j        hv!                    |          7S r   )r  r'   r  r  r  )rY  r  r   s     r   rd  z=TuneController._stop_experiment_if_needed.<locals>.<listcomp>&  sH       8EK1A#BBB ))!,,BBBr   N)r   r   r   stop_allr   r   set_finishedr   )r   rO   s   ` r   r  z)TuneController._stop_experiment_if_needed!  s    O9(9	=!!## 	y 	D4P 	))+++        	 	r   c                     | j         | j        k    r|| j        rt                              d| |           |                     ||           d S )NzTrial task failed for trial )exc_infor  )r   rI   r   r   r   _process_trial_failurer   r&  r   s      r   r  z"TuneController._trial_task_failure.  s`    ?dj((O' YCECCiXXX'''CCCCCr   c                 F   d| _         |                    |           |j        t          j        k    rT|                                r@|                     ||           | j                            | j	        | j
        |           dS |j        t          j        t          j        hv r|| j                            | |           | j                            |j        d           |                     ||           | j                            | j	        | j
        |           dS dS )zHandle trial failure.

        Attempt trial recovery if possible, clean up state otherwise.

        Args:
            trial: Failed trial.
            exception: Exception prior to invoking this method.
        T)excr  )r   r  N)r   r  r  r'   rp  should_recover_try_recoverr   on_trial_recoverr   r   r   r   on_trial_errorr   on_trial_completerb  r  r3  s      r   r2  z%TuneController._process_trial_failure6  s1    !9%%%<5=((U-A-A-C-C(e333O,,/$,e -      \emU];;;..tU;;;..u~T.JJJ%%ey%AAAO**/$,e +     	 <;r   c                    |j         t          j        k    rt                              d|            d S t                              d|            |j        r7t                              d| d           t          j        | j        |j	        <   d |j
        _        d |j
        _        |                     ||rt          j        nt          j                   |                    t!                                 || j        vrt                              d|            d S | j        |         }| j                            |           |                     |           |s|                     |          rd S t                              d| d|            | j                            |          }| j                            |           |                    d            |                     |           d S )	Nz2Not requesting trial STOP as it is ERROR already: z#Requesting to STOP actor for trial r  zB is currently saving/pausing. Scheduling STOP after save resolved.z-Will not STOP trial actor as it is not live: r  zTerminating actor for trial r  )r  r'   r  r   r   	is_savingr6   r  r   rb  temporary_state	saving_torestoring_fromr   r  r  r*   rm   ri   r	  ro  r  r  rl   r  r  )r   r&  r   r  s       r   r  z#TuneController._schedule_trial_stopR  s   <5;&&LLUeUUVVVFB5BBCCC? 	OLL" " " "   <J;ND(8*.'/3,uY&TekkEDTUUU9;;''',,,LLPPPQQQF,U344=4QQQ&&u--- 	T::5AA 	FLELL]LLMMM,0077  ///D!!!77777r   c                    	 |j         t          j        t          j        fv rdS |j         t          j        t          j        fv r;| j                            | |           | j        	                    |j
                   nt|j         t          j        u ra| j        	                    | |t          |j                             | j        	                    |j
        t          |j                             | j        	                    | j        | j        |           |                     |           | j                            |           dS # t(          $ r}t*                              d|           | j        | j        k    r t3          |t4                    r|                     ||           n:|                     |t9          t;          j                                         Y d}~dS Y d}~dS d}~ww xY w)a  The canonical implementation of stopping a trial.

        Trials may be in any external status when this function is called.
        If trial is in state PENDING or PAUSED, calls `on_trial_remove` for
        scheduler and `on_trial_complete()` for search_alg.
        If trial is in state RUNNING, calls `on_trial_complete` for scheduler
        and search_alg if RUNNING. Caller to ensure that there is no
        outstanding future to be handled for the trial. If there is, the future
        would be discarded.
        N)resultr  zTrial %s: Error stopping trial.r  )r  r'   r  r  r   rq  r   on_trial_remover   r:  rb  rp  r<   last_resultr   r   r   _schedule_graceful_trial_stopr   r  r   r   r   r   rI   r   r   r2  r    r  r  )r   r&  r   s      r   r   zTuneController.stop_trial}  s   	|U-=>>>%-!>>>#33D%@@@ 225>BBBB.. #55%e.?!@!@    22N<8I+J+J 3    O--/$,e .    ..u555%%e,,,,, 		 		 		>FFF$*,,!Y'' ++EQ+????++.y/C/E/EFF         @?????		s   E	 D$E	 	
G1BG,,G1c                 t    |                      |           |j        dk    r|                     |           d S d S )Nr  )_schedule_trial_exportr  r  r  s     r   rD  z,TuneController._schedule_graceful_trial_stop  sE    ##E***<7""%%e,,,,, #"r   Tr$  c                 (   || j         vr t                              d| d           d S |r1t          j        | j        |j        <   |                     |           d S |                     |           | 	                    |t          j                   d S )Nz Trial PAUSE requested for trial ) but trial is already stopping. Ignoring.r  )rm   r   r   r6   r  r   rb  r   r  r   r'   rq  r   r&  r$  s      r   _schedule_trial_pausez$TuneController._schedule_trial_pause  s    ,,,LL'5 ' ' '   F 	8;I;OD(8%%E%22222%%e,,,""5%,77777r   c                    d}d}|                      |          \  }}|dk    rd}||f}t                              d|                                 d|            |                     |||| j        | j                   d S )Nr   trainr`   train_bufferedzScheduling future r  )r&  r
  r  r  r  )_maybe_buffer_trainingr   r   r   r  _on_training_resultr  )r   r&  r  r
  buffer_lengthbuffer_time_ss         r   r  z$TuneController._schedule_trial_train  s    '+'B'B5'I'I$}1*K!=1DQ+*;*;*=*=QQ%QQRRR!!#.- 	" 	
 	
 	
 	
 	
r   c                 F   t          | j        t          | j        | j        j        dz                      }| j        }|dk    r4|j        r-t          d          rt          
                    d           d|fS |dk    r"|j        dk    rt          ||j                  |fS ||fS )Nr]   r`    trial_executor_buffer_checkpointz[Disabling buffered training as you passed `checkpoint_at_end` to `tune.CheckpointConfig()`.r   )maxr   r  r   ri   num_actor_tasksr   checkpoint_at_endrF   r   r  checkpoint_freq)r   r&  rQ  rP  s       r   rN  z%TuneController._maybe_buffer_training  s    #')<)LPR)RSS
 
 +1!8 :;; H   m##1!6!:!:}e&;<<mKKm++r   c                     t          |t                    s|g}t          d          5  |                     ||           d d d            n# 1 swxY w Y   |                     |d           d S )Nprocess_trial_resultFr)  )r   r   r=   _process_trial_resultsr+  r   r&  rA  s      r   rO  z"TuneController._on_training_result  s    &$'' 	XF011 	7 	7''v666	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7++Ee+DDDDDs   AAAc           
         t                               d| d|            t          dd          5  t          |          D ]\  }}t          d          5  |                     ||          }d d d            n# 1 swxY w Y   |W|t          |          dz
  k     r@t          d          r1t                               d	| d
t          |          |z
   d           |t          j	        k    r nd d d            d S # 1 swxY w Y   d S )Nz#Processing trial results for trial r  process_trial_resultszProcessing trial results took {duration:.3f} s, which may be a performance bottleneck. Please consider reporting results less frequently to Ray Tune.)messagerY  r`   !tune_controller_buffer_checkpointr  z) has a non-training future scheduled but z results left to process. This means that a checkpoint was requested, but buffered training was continued before it was saved. Consider using non-buffered training by setting the env variable `TUNE_RESULT_BUFFER_LENGTH=1`.)
r   r   r=   	enumerate_process_trial_resultr\  rF   r  r6   r  )r   r&  resultsirA  r  s         r   rZ  z%TuneController._process_trial_results  s   M5MMGMMNNN#=
 
 
 	 	 'w//  	6!"899 I I#99%HHHI I I I I I I I I I I I I I I# 3w<<!+++#$GHH 
"NN!B !B !B14W1A!B !B !B	 	 	 !444 E 53	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s6   $C=A9-C=9A==C= A=A/C==DDrA  c                    |                     |j                   t          |v }d}|r7t                              d           |j        }|                     d           | xj        |                    t          d          z  c_        t          |          }| 
                    |           |                     |j        |          s|                    |          rt          j        }nUt          d          5  | j                            |                                 ||          }d d d            n# 1 swxY w Y   |t          j        k    r|                     d           nGt          d          5  | j                            |j        |           d d d            n# 1 swxY w Y   |st          d	          5  | j                            | j        | j        ||
           d d d            n# 1 swxY w Y   |                    t.          d          }|                    |           |                     |           |t          j        k    r|                     ||           |j        rjt                              d| d|            | j                            |j                  r|t          j        t          j        hv r|| j        |j        <   d S |                     ||           |S )Nra  Fz&Trial finished without logging 'done'.T)doner   zscheduler.on_trial_resultzsearch_alg.on_trial_resultzcallbacks.on_trial_result)r  r   r&  rA  )r  z!Caching trial decision for trial r  )updaterb  r0   r   r   rC  r   r   r   r<   _validate_result_metricsr   should_stopr6   r  r=   r   on_trial_resultr   r   r   r   r   r1   update_last_resultro  r  _checkpoint_trial_if_neededr<  r   r   )r   r&  rA  is_duplicateforce_checkpointflat_resultr  s          r   ra  z$TuneController._process_trial_result  s   u~...'61 
  	%LLABBB&FMMtM$$$FJJ'7;;;"6**%%k222==00 	E4E4Ek4R4R 	%*HH9::  .>>MMOOUK                ~***MMtM$$$$ :;; N N 00MMMN N N N N N N N N N N N N N N
  	29::  //"o<! 0                   &zz*;UCC$$V,,,**5111 ~+++ ,,U:J,KKK? 	LLPUPPhPPQQQ /33ENCC Hx$#T H H @H,U^<4  111Os6   9/D44D8;D85!F""F&)F&>)G33G7:G7c                 0   t          t          j                            dd                    dk    r^t	          d D                       dk    rB| j        t          k    r| j        nd}| j        j        t          k    r| j        j        nd}| j	        j        t          k    r| j	        j        nd}t          |t                    r|g}|r	|vr|}d}n|r |vr|}t          | j                  j        }nv|rpt          fd|D                       rUt          t!          fd|                    }t	          |          dk    r|d         }t          | j	                  j        }nd}d}|r(t#          d	                    ||                    dS dS dS )
af  
        Check if any of the required metrics was not reported
        in the last result. If the only items are ``done`` or any of
        DEBUG_METRICS, this means that no result was ever received and
        the trial just returned. This is also okay and will not raise
        an error.

        This will ignore checking for the DEFAULT_METRIC.
        #TUNE_DISABLE_STRICT_METRIC_CHECKINGr   r`   c                 P    h | ]#}|t          t                    t          gz   v!|$S r   )r   r-   r/   )rY  ks     r   	<setcomp>z:TuneController._validate_result_metrics.<locals>.<setcomp>i  s1    LLLqatM/B/BdV/K&K&K&K&K&Kr   Nztune.TuneConfig()c              3       K   | ]}|vV  	d S r   r   )rY  search_metricrA  s     r   rZ  z:TuneController._validate_result_metrics.<locals>.<genexpr>  s9       ( (0=V+( ( ( ( ( (r   c                     | vS r   r   )ru  rA  s    r   r  z9TuneController._validate_result_metrics.<locals>.<lambda>  s    m6.I r   zTrial returned a result which did not include the specified metric(s) `{}` that `{}` expects. Make sure your calls to `tune.report()` include the metric, or set the TUNE_DISABLE_STRICT_METRIC_CHECKING environment variable to 1. Result: {})r|   r}   r~   r   r\  r   r.   r   rR   r   r   r   r  __name__anyr   filterr   r   )r   rA  base_metricscheduler_metricsearch_metricsreport_metriclocations    `     r   rg  z'TuneController._validate_result_metrics^  s    rz~~CQGGHHAMMLLFLLLMMPQQQ*.,.*H*H$,,dK &-?? #**  #*n<<  ''  .#.. 2"0!1  {&88 +.!  &6f&D&D 0 344=  C ( ( ( (AO( ( ( % %   !%IIII& ! ! }%%**$1!$4M 011: $ 
 <
 =CF%x= =	 	 	S NMQQN
 
r   c                     || j         vr t                              d| d           d S |p|j        }|                     |d| j        | j        d          }t          |          |j        _	        |j        j	        S )NzTrial SAVE requested for trial rH  r   T)r&  r
  r  r  r  )
rm   r   r   rC  r  _on_saving_resultr  r   r=  r>  )r   r&  rA  r  s       r   r   z#TuneController._schedule_trial_save  s    
 ,,,LL'% ' ' '   4,5,**,- + 
 
 +@*G*G' $..r   checkpoint_valuec                 J   t          d          5  |                     ||           d d d            n# 1 swxY w Y   t          d          5  | j                            | j        | j        |           d d d            n# 1 swxY w Y   |                     |d           d S )Nprocess_trial_savezcallbacks.on_trial_saver  Tr)  )r=   _process_trial_saver   on_trial_saver   r   r+  )r   r&  r  s      r   r  z TuneController._on_saving_result  s.   .// 	> 	>$$U,<===	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 344 	 	O))/$,e *   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	
 	++Ed+CCCCCs   377(BBBc                    t                               d|           	 |j        st                               d|            n	 | j                            | j        | j        ||j                   n)# t          $ r t                               d            w xY w|                    |           | j	        
                    |           |                     |           n,# t          $ r t                               d||           Y nw xY wd|j        _        | j                            |j        d          }|r|r|                     ||           dS dS dS )zProcesses a trial save.

        Acts on the decision cached during the last `_process_trial` call.

        Args:
            trial: Trial being saved.
        z Trial %s: Processing trial save.zGot empty checkpoint for trial )r  r   r&  r  a  Error encountered during processing of callbacks. Ray Train/Tune recently changed the checkpoint interface that is passed to callbacks. If you implemented your own callback with an `on_checkpoint` handler, please review the checkpoint interface and adjust your code accordingly.z&Trial %s: Error handling checkpoint %sN)r   r   r  r   on_checkpointr   r   r   r  r   on_trial_checkpointro  r   r=  r>  r   r  rb  r   )r   r&  r  r  s       r   r  z"TuneController._process_trial_save  s    	7???	#. 6FuFFGGGGO11"&/#|##3#>	 2     ! 	 	 	NN'   	 ##$4555(<<UCCC..u555 	 	 	8%AQ    	
 +/'/33ENDII 	2( 	2  11111	2 	2 	2 	2s*   %C -A1 0C 1&BAC &DDc                 |    |                                 s|r%|j        j        r|                     |           dS dS dS )z.Checkpoints trial based off trial.last_result.N)r$  r=  r  r   )r   r&  r  s      r   rk  z*TuneController._checkpoint_trial_if_needed  sY    ""$$ 	1 	1$. 1))%000001 1	1 	1r   c                     |j         }|s t                              d| d           dS ||j        _        d}|f}|                     |||i | j        | j                   dS )NzNot restoring trial z: No checkpoint found.Frestorer&  r
  r  r  r  r  T)latest_checkpoint_resultr   r   r=  r?  r  _on_restoring_resultr  )r   r&  checkpoint_resultr
  r  s        r   r  z&TuneController._schedule_trial_restore  s    !:  	LLMMMMNNN5 0A,!#!!#/- 	" 	
 	
 	
 tr   c                 0    |                      |           d S r   )_process_trial_restorer[  s      r   r  z#TuneController._on_restoring_result  s    ##E*****r   c                 8   t                               d|           |                                 t                               d|           |                     |t          j                   |                     |           | j                            |           dS )z[Processes a trial restore.

        Args:
            trial: Trial being restored.
        z#Trial %s: Processing trial restore.z(Trial %s: Restore processed successfullyN)	r   r   
on_restorer   r'   rp  r  r   rm  r  s     r   r  z%TuneController._process_trial_restore  s     	:EBBB?GGGuem444""5)))e$$$$$r   r5  c                     | j                             |j        d           |j        rd|j        _        |                     ||           t                              d|           | 	                    |           dS )zTries to recover trial.

        Notifies SearchAlgorithm and Scheduler if failure to recover.

        Args:
            trial: Trial to recover.
            exc: Exception prior to invoking this method.
        Nr  z-Trial %s: Notifying Scheduler and requeueing.)
r   r  rb  r<  r=  r>  r  r   r   _requeue_trial)r   r&  r5  s      r   r7  zTuneController._try_recover(  s|     	$((>>>? 	3.2E!+!!%3!777DeLLLE"""""r   c                    | j                             | |           |                     |t          j                   | j                            | j                            |                     | j                            |           | j	        
                    |           t          d          5  | j                             |                                 |           ddd           dS # 1 swxY w Y   dS )zNotification to TrialScheduler and requeue trial.

        This does not notify the SearchAlgorithm because the function
        evaluation is still in progress.

        )r  rj  N)r   r9  r   r'   r   r   r  indexr8  r   rm  r=   rn  r   r  s     r   r  zTuneController._requeue_trial<  s5    	**4777uU];;; 	++E22333E"""e$$$233 	E 	E,,T]]__eDDD	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	Es   2.C--C14C1c                     |j         rt          |j                   dk    rd S |                     |d|j         fd | j        d          }| j        j                            |           d S )Nr   export_modelT)r&  r
  r  r  r  r  )export_formatsr\  r  r  ri   _actor_task_eventsresolve_future)r   r&  r  s      r   rF  z%TuneController._schedule_trial_exportU  s    # 	s5+?'@'@A'E'EF **&&(- + 
 
 	.==fEEEEEr   
new_confignew_experiment_tagc                    |                     |           |                    |           t          j        |          }t	          |          |t
          <   |j        \  }}||t          <   ||t          <   t          t          |j        j                  }| j                            |           |                     |d|f||j        d| j        | j                   d S )N)logdirr"  )logger_creatorrT   r  )set_experiment_tag
set_configr.  deepcopyr,   r4   log_to_filer3   r2   r   r+   rT   trial_working_directoryrv   rm  r  _on_trial_resetr  )r   r&  r  r  extra_configstdout_filestderr_filer  s           r   r  z$TuneController._schedule_trial_reseti  s     	  !3444$$$ }Z00#-e#4#4Z #(#4 [$/[!$/[!  )N
 
 
 	""5)))!!"0 =  *- 	" 
	
 
	
 
	
 
	
 
	
r   successc                 D   | j                             |           |s_d}t                              d| d|            t	          |          }|                    |           |                     ||           d S | j        |         }|                     |d           d S )NzQTrainable runner reuse requires reset_config() to be implemented and return True.z!Could not re-use actor for trial r  r  REUSED)r  )	rv   r  r   r   r   r  r  rm   r  )r   r&  r  r   r   r  s         r   r  zTuneController._on_trial_reset  s    %%e,,, 	/ 
 LLLULLdLLMMM,T22Iy)))%%ey%AAAF,U3Mx88888r   c                 :    | j                             |           d S r   )r   r8  r  s     r   request_stop_trialz!TuneController.request_stop_trial  s    &&&&&r   c                     d| _         d S NT)r   r   s    r   request_stop_experimentz&TuneController.request_stop_experiment  s    '+$$$r   c                     | j         r7| j                                         }|                     |           | j         5d S d S r   )r   r  r   )r   r  s     r   _process_stop_requestsz%TuneController._process_stop_requests  sT     	 $$&&AOOA  	 	 	 	 	r   c                 t    | j                             |j        d           |                     ||           dS )a  Pause a trial and reset the necessary state variables for resuming later.

        Args:
            trial: Trial to pause.
            should_checkpoint: Whether or not an in-memory checkpoint should be created
                for this paused trial. Defaults to True.
        Nr#  )r   r  rb  rJ  rI  s      r   r   zTuneController.pause_trial  s?     	$((>>>""5<M"NNNNNr   c                 V    |                                   |                                  dS )zCleanup trials and callbacks.N)r  r   r   s    r   r  zTuneController.cleanup  s,    %%'''''r   c                 H    | j                                         }dD ]}||= |S )z~Gets state for trial.

        Note that this is not used as a pickling override as
        does not have all fields.
        )r   r   r   r   r   r   r   r   r   r   r   ri   rj   rk   r   r   rl   rm   ro   rp   rq   rr   rs   rt   ru   rv   rx   ry   rw   r   )__dict__r.  )r   staterr  s      r   r   zTuneController.__getstate__  s9     ""$$
  	  	A@ ar   c                 ,   |                     d          }| j                            d|           |                     d          }| j                            d|           | j                            |           |                                 | _        d S )Nr   r   )r  r  r  rf  r   r   )r   r  r   r   s       r   rD  zTuneController.__setstate__  s    ii//  ===YY}--
  
;;;U####'#B#B#D#D   r   )r   N)FFr   )Frt  )F)r  )NNNNFT)vrw  
__module____qualname__r   rI   r   r8   r
   r   r   r6   r:   r;   r   r   r   r|   r   r   r   r   r	   r   r   r   propertyr   rJ   r   r&   r   r   r   r   r   r   r  r  r'   r)  r=  r   rM  rQ  r%   rS  rW  rf  r   r   r%  r{  r  r  r  r  r  r  r   r   ro  r  r  r   r  r  r  r  r  r  r  r  r   r  r3  	ObjectRefr  r   r'  r+  r  r  r   r   r   r2  r  r   rD  rJ  r  rz   rN  rO  rZ  ra  rg  r   r   r   r  r  rk  r  r  r  r7  r  rF  r  r  r  r  r  r   r  r   rD  r   r   r   rH   rH   C   s.       /NE
 15<@.2%)04-1.2 $>B,0"LP"!h7 h7 h7 _-h7  (UCZ(89	h7
 N+h7 '"h7  -h7 h7 !c?h7 DN+h7 h7 "**:!;h7 .)h7 h7 #+8B4G+H"Ih7  !h7 h7 h7 h7T
 
 
,   X     X  # # X#&
+&@C&	& & & &$? ? ? ? =C = = = X= s    X 0 0 0 0 X0
 
 
X X X<
 
 
D 
 
 
 

")5k")2>") ") ") ")H e    @,=L ,= ,= ,= ,=\
 
HSM 
 
 
 

<t%::;< < < <
> 
> 
>+ + +  ! ! !%Xu %X %X %X %XN D 3 QU    @H H H H H
8 8 87 7 7< < < < < <(-9 -9$ -9 -9 -9 -9^*X *X *XX.!u .!c .! .! .! .!`$S#X $ $ $ $)u ) ) ) )
' ' '& & &6T< T T T Td d d dL#u # # # # #J:
5 :
 :
 :
 :
x 
5  
  
  
  
D9e 9 9 9 9 9v. .L .s . . . .2
4L 
4 
4 
4 
4+< +I + + + +D !%!%<@AE$U UU U uo	U
 U HeS\4%789U 8UI$6$<=>U U 
#-	 U U U UnD D DF FU Fc Ft F F F F$O OE Ot O O O O	 	 	D D9 D D D D L-?@   8)8 )8% )8HY<O )8 )8 )8 )8V( ( (T-5 - - - -
8 85 8T 8 8 8 8$
5 
 
 
 
(,E ,eCJ6G , , , ,2E E E  @J5 J$sCx. J J J JX< < <F "&/ // / 
'	(	/ / / /B	D 	D 	D 	D 	D-2 -2/ -2 -2 -2 -2^1 1 1 1U t    ,+% + + + + +%E % % % %##!&y,'M!N# # # #(E E E2FE F F F F( 
 
  
  	 
  
  
  
D9U 9T 9 9 9 9*' ' ', , ,  
O O O4 O O O O( ( (
( ( (T	E 	E 	E 	E 	Er   rH   c                   8    e Zd ZdZ	 ddddee         fdZd ZdS )	_TrialExecutorWrapperzWraps around TrialExecutor class, intercepts API calls and warns users
    of restricted API access.

    This is meant to facilitate restricting
    the current API exposure of TrialExecutor by TrialScheduler.
    Nr   r   whitelist_attrc                     || _         |pt                      | _        | j        D ]}t          | j         |          sJ d S r   )_trial_executorrn   _whitelist_attrhasattr)r   r   r  attrs       r   r   z_TrialExecutorWrapper.__init__  sU    
  .-6( 	7 	7D4/666666	7 	7r   c                     || j         vr-t          d          rt                              d| d           t	          | j        |          S )N!restrict_accessing_trial_executorYou are trying to access a	   interface of TrialExecutor in TrialScheduler, which is being restricted. If you believe it is reasonable for your scheduler to access this TrialExecutor API, please reach out to Ray team on GitHub. A more strict API access pattern would be enforced starting 1.12.0)r  rF   r   r  getattrr  r   r  s     r   __getattr__z!_TrialExecutorWrapper.__getattr__  sb    t+++;<< 	' ' ' '   t+T222r   r   )rw  r  r  __doc__r   rn   r   r  r   r   r   r  r    sa          )-	7 	7/	7 !	7 	7 	7 	73 3 3 3 3r   r  c            
       R    e Zd ZdZdZ	 	 d	dededee         dee         fdZ	d Z
dS )
r   zWraps around TrialRunner class, intercepts API calls and warns users
    of restricted API access.

    This is meant to facilitate restricting
    the current API exposure of TrialRunner by TrialScheduler.
    r   Ntune_controllerr   r   c                     || _         t          ||          | _        |pt                      | _        | j        D ]}t          | |          sJ d S r   )_tune_controllerr  r  rn   _runner_whitelist_attrr  )r   r  r   r   r   r  s         r   r   zTrialRunnerWrapper.__init__   sl     !043 
  
 '<&Dsuu#/ 	' 	'D4&&&&&&	' 	'r   c                     || j         k    r| j        S || j        vr-t          d          rt                              d| d           t          | j        |          S )N"restrict_accessing_tune_controllerr  a   interface of TrialRunner in TrialScheduler, which is being restricted. If you believe it is reasonable for your scheduler to access this TrialRunner API, please reach out to Ray team on GitHub. A more strict API access pattern would be enforced starting 1.12s.0)_EXECUTOR_ATTRr  r  rF   r   r  r  r  r  s     r   r  zTrialRunnerWrapper.__getattr__0  sy    4&&&''t222<== 	( ( ( (   t,d333r   )NN)rw  r  r  r  r  rH   r   r   rn   r   r  r   r   r   r   r     s          &N 0415' ''' '  (}	'
 "*#' ' ' ' 4 4 4 4 4r   r   rJ   r   c                 b   t          j        dd          }|dk    rt          |          S t          | t                    sdS d}t          j                                        dd          }t          |t          |dz                      }||k    rt          
                    d| d	           |S )
NTUNE_MAX_PENDING_TRIALS_PGrh   r`      CPUg      ?g?zxThe maximum number of pending trials has been automatically set to the number of available cluster CPUs, which is high (a   CPUs/pending trials). If you're running an experiment with a large number of trials, this could lead to scheduling overhead. In this case, consider setting the `TUNE_MAX_PENDING_TRIALS_PG` environment variable to the desired maximum number of concurrent pending trials.)r}   r   r|   r   r7   r3  cluster_resourcesr   rT  r   r  )rJ   rK  min_autoscaling_ratecluster_cpuss       r   r   r   A  s    #?HHV##%&&& j"788 q  (**..uc::L13|c7I3J3JKK000K #K K K
	
 
	
 
	
 r   c                       e Zd ZdZdefdZddedefdZ	 dded	e	e
         d
e	e         fdZdefdZed             Zd ZdS )r   aO  The TuneController does not use a RayTrialExecutor anymore.

    Instead, we pass this fake executor for searchers/schedulers to use
    as an interface.

    In the future, we should have the searchers/schedulers either interact with
    the tune controller, or define a different API for more fine-grained scheduler
    control.
    r  c                     || _         d S r   )r  )r   r  s     r   r   z_FakeRayTrialExecutor.__init__q  s     /r   Tr&  r$  c                 :    | j                             ||          S )Nr#  )r  rJ  rI  s      r   r   z!_FakeRayTrialExecutor.pause_trialt  s(    $::%6 ; 
 
 	
r   NrA  r   c                 :    | j                             ||          S )N)r&  rA  )r  r   r[  s      r   r   z_FakeRayTrialExecutor.savey  s     
 $99f9UUUr   c                     dS r  r   r  s     r   r   z-_FakeRayTrialExecutor.has_resources_for_trial  s    tr   c                     | j         j        S r   )r  rk   r   s    r   rk   z'_FakeRayTrialExecutor._resource_updater  s    $66r   c                     d S r   r   r   s    r   $force_reconcilation_on_next_step_endz:_FakeRayTrialExecutor.force_reconcilation_on_next_step_end  s    r   r  r   )rw  r  r  r  rH   r   r'   r   r   r   r
   r   r   r   r  rk   r  r   r   r   r   r   f  s         0 0 0 0 0
 
 
4 
 
 
 
 "&V VV V 
'	(	V V V VU     7 7 X7    r   r   )ur.  r   loggingr}   r   r  r   collectionsr   r   r   	functoolsr   pathlibr   typingr   r	   r
   r   r   r   r   r   r3  ray.airr   ray.air.constantsr   ray.air.executionr   r   ray.air.execution._internalr   r   ray.exceptionsr   r   ray.train._internal.sessionr   r   ray.train._internal.storager   ray.tuner   ray.tune.callbackr   r   ray.tune.errorr   r   r    ray.tune.execution.class_cacher!   #ray.tune.execution.experiment_stater"   r#   1ray.tune.execution.insufficient_resources_managerr$   #ray.tune.execution.placement_groupsr%   ray.tune.experimentr&   r'   ray.tune.experiment.trialr(   r)   r*   r+   r,   ray.tune.resultr-   r.   r/   r0   r1   r2   r3   r4   ray.tune.schedulersr5   r6   ray.tune.searchr7   r8   ray.tune.stopperr9   r:   ray.tune.tune_configr;   ray.tune.utilsr<   r=   ray.tune.utils.logr>   r?   r@   ray.tune.utils.object_cacherA   ray.tune.utils.resource_updaterrB   ray.tune.utils.serializationrC   rD   ray.util.annotationsrE   ray.util.debugrF   	getLoggerrw  r   rH   r  r   r|   r   r   r   r   r   <module>r     s      				       * * * * * * * *                   I I I I I I I I I I I I I I I I I I I I 



 # # # # # # . . . . . . L L L L L L L L E E E E E E E E 6 6 6 6 6 6 6 6 N N N N N N N N 6 6 6 6 6 6 % % % % % % 4 4 4 4 4 4 4 4 O O O O O O O O O O ; ; ; ; ; ;             F E E E E E 1 1 1 1 1 1 1 1             	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 > = = = = = = = B B B B B B B B 1 1 1 1 1 1 1 1 - - - - - - 5 5 5 5 5 5 5 5 D D D D D D D D D D 4 4 4 4 4 4 < < < < < < Q Q Q Q Q Q Q Q - - - - - - # # # # # #		8	$	$ lE lE lE lE lE lE lE lE^=3 3 3 3 3 3 3 3D (4 (4 (4 (4 (4 (4 (4 (4V" "C " " " "J" " " " " " " " " "r   