o
    $iol                     @   s^  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 d dlmZ d dl	m
Z
mZmZmZmZmZ d dlZd dlmZ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 d d
l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*m+Z+ d dl,m-Z- zd dl.Z/d dl.m0Z0 W n e1y   dZ/dZ0Y nw e2e3Z4e-ddG dd dZ5dS )    N)Number)Path)AnyDictListOptionalTupleUnion)EXPR_PROGRESS_FILEEXPR_RESULT_FILETRAINING_ITERATION)_exists_at_fs_pathget_fs_and_path)
Checkpoint)"_find_newest_experiment_checkpoint)TuneController)Trial)CONFIG_PREFIXDEFAULT_METRIC)flatten_dict)TuneFunctionDecoder)is_nanis_nan_or_infunflattened_lookup)	PublicAPI)	DataFramebeta)	stabilityc                   @   s  e Zd ZdZddddddeeejf dee	j
j deee  dee dee f
d	d
Zdee fddZdedefddZdeeef fddZdIdedeeef fddZedefddZedefddZedefddZedefddZedefdd Zedefd!d"Zd#d$ Zedefd%d&Zedeeef fd'd(Z edefd)d*Z!edeeef fd+d,Z"	dJd-ee d.ee defd/d0Z#	dKded-ee dee$ee%f  fd1d2Z&		dJded-ee d.ee dee fd3d4Z'			5	6dLd-ee d.ee d7ed8edee f
d9d:Z(			5dMd-ee d.ee d7edee fd;d<Z)	>dNdee fd?d@Z*d-edefdAdBZ+d.edefdCdDZ,	dJd-ee d.ee deee-f fdEdFZ.deee-f fdGdHZ/dS )OExperimentAnalysisa  Analyze results from a Ray Train/Tune experiment.

    To use this class, the run must store the history of reported metrics
    in log files (e.g., `result.json` and `progress.csv`).
    This is the default behavior, unless default loggers are explicitly excluded
    with the `TUNE_DISABLE_AUTO_CALLBACK_LOGGERS=1` environment variable.

    Parameters:
        experiment_checkpoint_path: Path to an `experiment_state.json` file,
            or a directory that contains an `experiment_state.json` file.
        default_metric: Default metric for comparing results. Can be
            overwritten with the ``metric`` parameter in the respective
            functions.
        default_mode: Default mode for comparing results. Has to be one
            of [min, max]. Can be overwritten with the ``mode`` parameter
            in the respective functions.
        trials: List of trials that can be accessed via `analysis.trials`.
    N)storage_filesystemtrialsdefault_metricdefault_modeexperiment_checkpoint_pathr   r    r!   r"   c                C   s   || _ |r|dvrtd|| _| j d u r| jd urt| _ |r#|| _nt|\| _}t|}|dr>tj	
|| _|| _n)|| _t| j| jd}|d u rdtjd}td| d| jj d| j d	|| _|pl|  | _|  | _|  | _d S )
Nminmaxz2`default_mode` has to be None or one of [min, max]z.json)experiment_pathfs*z%No experiment snapshot file of form 'z' was found at: (z, z)
Please check if you specified the correct experiment path, which should be a combination of the `storage_path` and `name` specified in your run.)r!   
ValueErrorr"   r   _fsr   strendswithospathdirname_experiment_fs_path_experiment_json_fs_pathr   r   CKPT_FILE_TMPLformat	type_name_load_trialsr    _fetch_trial_dataframes_trial_dataframesget_all_configs_configs)selfr#   r   r    r!   r"   experiment_json_fs_pathpattern r>   b/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/ray/tune/analysis/experiment_analysis.py__init__8   s@   	


zExperimentAnalysis.__init__returnc           
      C   s   | j | j}tj| td}W d    n1 sw   Y  t| j}g }|d }|D ].\}}t	j
|dd}|| t|j}	|j |	_| j |	_|j|	_||	 || q-|S )N)cls
trial_dataTstub)r+   open_input_streamr2   jsonloadsreadallr   r   r1   r   from_json_staterestore_run_metadatacopystorageparentas_posixstorage_fs_pathr   nameexperiment_dir_nameset_storageappend)
r;   fexperiment_stateexperiment_fs_pathr    trial_statestrial_json_statetrial_runtime_metadatatrialnew_storager>   r>   r?   r6   l   s    


zExperimentAnalysis._load_trialsr[   c           
   	   C   sP  dt i}|jd u rt S t|jjt }t|jjt }t	|jj
|re|jj
|(}| dd}|sCt W  d    S dd |dD }W d    n1 sWw   Y  tj|dd}|S t	|jj
|r|jj
|}| d}	W d    n1 sw   Y  tjt|	|d}|S td	| d
t dt d|jj )Ntrial_idzutf-8
c                 S   s   g | ]}t |qS r>   )rG   rH   ).0rowr>   r>   r?   
<listcomp>       z=ExperimentAnalysis._fetch_trial_dataframe.<locals>.<listcomp>/)sep)dtypezCould not fetch metrics for z: both z and z were not found at )r,   last_resultr   r   rM   trial_fs_pathr   rO   r
   r   r   rF   rI   decoderstripsplitpdjson_normalizeread_csvioStringIOFileNotFoundError)
r;   r[   force_dtypejson_fs_pathcsv_fs_pathrU   content	json_listdfcsv_strr>   r>   r?   _fetch_trial_dataframe   s8   
z)ExperimentAnalysis._fetch_trial_dataframec                 C   s   g }i }| j D ]+}z
| |||j< W q ty2 } z|||f t ||j< W Y d}~qd}~ww |rLddd |D }tdt	| d|  |S )zyFetches trial dataframes from files.

        Returns:
            A dictionary mapping trial_id -> pd.DataFrame
        Nr^   c                 S   s$   g | ]\}}d | dt | qS )z- z: )repr)r_   r[   errorr>   r>   r?   ra      s   $ z>ExperimentAnalysis._fetch_trial_dataframes.<locals>.<listcomp>zFailed to fetch metrics for z trial(s):
)
r    rx   r]   	ExceptionrT   r   joinloggerwarninglen)r;   failures	trial_dfsr[   efail_strr>   r>   r?   r7      s&   
z*ExperimentAnalysis._fetch_trial_dataframesFprefixc                    s    fdd| j D S )zReturns all trial hyperparameter configurations.

        Args:
            prefix: If True, flattens the config dict
                and prepends `config/`.

        Returns:
            Dict[str, Dict]: Mapping trial_id -> config dict
        c                    s(   i | ]}|j  rtt|jin|jqS r>   )r]   r   r   configr_   r[   r   r>   r?   
<dictcomp>   s
    z6ExperimentAnalysis.get_all_configs.<locals>.<dictcomp>r    )r;   r   r>   r   r?   r9      s   

z"ExperimentAnalysis.get_all_configsc                 C      | j S )zPath pointing to the experiment directory on persistent storage.

        This can point to a remote storage location (e.g. S3) or to a local
        location (path on the head node).)r1   r;   r>   r>   r?   r'      s   z"ExperimentAnalysis.experiment_pathc                 C   $   | j r| js
td| | j | jS )a)  Get the best trial of the experiment

        The best trial is determined by comparing the last trial results
        using the `metric` and `mode` parameters passed to `tune.run()`.

        If you didn't pass these parameters, use
        `get_best_trial(metric, mode, scope)` instead.
        zTo fetch the `best_trial`, pass a `metric` and `mode` parameter to `tune.run()`. Alternatively, use the `get_best_trial(metric, mode)` method to set the metric and mode explicitly.)r!   r"   r*   get_best_trialr   r>   r>   r?   
best_trial   
   
zExperimentAnalysis.best_trialc                 C   r   )a8  Get the config of the best trial of the experiment

        The best trial is determined by comparing the last trial results
        using the `metric` and `mode` parameters passed to `tune.run()`.

        If you didn't pass these parameters, use
        `get_best_config(metric, mode, scope)` instead.
        zTo fetch the `best_config`, pass a `metric` and `mode` parameter to `tune.run()`. Alternatively, use the `get_best_config(metric, mode)` method to set the metric and mode explicitly.)r!   r"   r*   get_best_configr   r>   r>   r?   best_config   r   zExperimentAnalysis.best_configc                 C   sJ   | j r| js
td| j}|std| j  d| j d| || j | jS )a  Get the checkpoint path of the best trial of the experiment

        The best trial is determined by comparing the last trial results
        using the `metric` and `mode` parameters passed to `tune.run()`.

        If you didn't pass these parameters, use
        `get_best_checkpoint(trial, metric, mode)` instead.

        Returns:
            :class:`Checkpoint <ray.tune.Checkpoint>` object.
        zTo fetch the `best_checkpoint`, pass a `metric` and `mode` parameter to `tune.run()`. Alternatively, use the `get_best_checkpoint(trial, metric, mode)` method to set the metric and mode explicitly.zONo best trial found. Please check if you specified the correct default metric (z) and mode (z).)r!   r"   r*   r   get_best_checkpoint)r;   r   r>   r>   r?   best_checkpoint   s    
z"ExperimentAnalysis.best_checkpointc                 C   s"   | j r| js
td| j| jj S )a  Get the full result dataframe of the best trial of the experiment

        The best trial is determined by comparing the last trial results
        using the `metric` and `mode` parameters passed to `tune.run()`.

        If you didn't pass these parameters, use
        `get_best_trial(metric, mode)` and use it to look for the dataframe
        in the `self.trial_dataframes` dict.
        zQTo fetch the `best_result`, pass a `metric` and `mode` parameter to `tune.run()`.)r!   r"   r*   trial_dataframesr   r]   r   r>   r>   r?   best_dataframe  s
   z!ExperimentAnalysis.best_dataframec                 C   s   | j r| js
td| jjS )aH  Get the last result of the best trial of the experiment

        The best trial is determined by comparing the last trial results
        using the `metric` and `mode` parameters passed to `tune.run()`.

        If you didn't pass these parameters, use
        `get_best_trial(metric, mode, scope).last_result` instead.
        zTo fetch the `best_result`, pass a `metric` and `mode` parameter to `tune.run()`. Alternatively, use `get_best_trial(metric, mode).last_result` to set the metric and mode explicitly and fetch the last result.)r!   r"   r*   r   rf   r   r>   r>   r?   best_result)  s
   
zExperimentAnalysis.best_resultc                 C   s   t jddS )NTUNE_RESULT_DELIMrc   )r.   environgetr   r>   r>   r?   
_delimiter<  s   zExperimentAnalysis._delimiterc                 C   s0   t stdt| j|  d}t jj|gddS )aM  Get the best result of the experiment as a pandas dataframe.

        The best trial is determined by comparing the last trial results
        using the `metric` and `mode` parameters passed to `tune.run()`.

        If you didn't pass these parameters, use
        `get_best_trial(metric, mode, scope).last_result` instead.
        zD`best_result_df` requires pandas. Install with `pip install pandas`.	delimiterr]   index)rk   r*   r   r   r   r   from_records)r;   r   r>   r>   r?   best_result_df?  s   
z!ExperimentAnalysis.best_result_dfc                 C   s   dd | j D S )z7Get the last result of the all trials of the experimentc                 S   s   i | ]}|j |jqS r>   )r]   rf   r   r>   r>   r?   r   U  rb   z.ExperimentAnalysis.results.<locals>.<dictcomp>r   r   r>   r>   r?   resultsR  s   zExperimentAnalysis.resultsc                    s,   t stdt jj fdd jD ddS )z/Get all the last results as a pandas dataframe.z@`results_df` requires pandas. Install with `pip install pandas`.c                    s   g | ]}t |j  d qS )r   )r   rf   r   r   r   r>   r?   ra   _  s    z1ExperimentAnalysis.results_df.<locals>.<listcomp>r]   r   )rk   r*   r   r   r    r   r>   r   r?   
results_dfW  s   
zExperimentAnalysis.results_dfc                 C   r   )zList of all dataframes of the trials.

        Each dataframe is indexed by iterations and contains reported
        metrics.
        )r8   r   r>   r>   r?   r   f  s   z#ExperimentAnalysis.trial_dataframesmetricmodec                 C   s   |r
|dvr
t d|r|st d| j||d}| jdd}| D ]\}}||v r:|| | || j|d q#tt| S )a  Returns a pandas.DataFrame object constructed from the trials.

        This function will look through all observed results of each trial
        and return the one corresponding to the passed ``metric`` and
        ``mode``: If ``mode=min``, it returns the result with the lowest
        *ever* observed ``metric`` for this trial (this is not necessarily
        the last)! For ``mode=max``, it's the highest, respectively. If
        ``metric=None`` or ``mode=None``, the last result will be returned.

        Args:
            metric: Key for trial info to order on. If None, uses last result.
            mode: One of [None, "min", "max"].

        Returns:
            pd.DataFrame: Constructed from a result dict of each trial.
        r$   *If set, `mode` has to be one of [min, max]z^If a `mode` is passed to `ExperimentAnalysis.dataframe(), you'll also have to pass a `metric`!)r   r   Tr   )logdir)	r*   _retrieve_rowsr9   itemsupdaterk   r   listvalues)r;   r   r   rowsall_configsr/   r   r>   r>   r?   	dataframeo  s   zExperimentAnalysis.dataframec                    s8    p| j pt |jjj}dd |D } fdd|D S )a  Get all checkpoints and a specified metric of a trial.

        Args:
            trial: The log directory of a trial, or a trial instance.
            metric: key for trial info to return, e.g. "mean_accuracy".
                "training_iteration" is used by default if no value was
                passed to ``self.default_metric``.

        Returns:
            List of [Checkpoint, metric] for all checkpoints of the trial.
        c                 S   s   g | ]}|j |jfqS r>   )
checkpointmetrics)r_   checkpoint_resultr>   r>   r?   ra     s    
zIExperimentAnalysis._get_trial_checkpoints_with_metric.<locals>.<listcomp>c                    s   g | ]\}}|t  |fqS r>   )r   )r_   r   r   r   r>   r?   ra     s    )r!   r   run_metadatacheckpoint_managerbest_checkpoint_results)r;   r[   r   r   best_checkpointsr>   r   r?   "_get_trial_checkpoints_with_metric  s   
z5ExperimentAnalysis._get_trial_checkpoints_with_metricc                    s|   |p| j pt}| |}| ||}ttdd |}|s(td| d dS |dkr.dnd t| fd	dd
\}}|S )aJ  Gets best persistent checkpoint path of provided trial.

        Any checkpoints with an associated metric value of ``nan`` will be filtered out.

        Args:
            trial: The log directory of a trial, or a trial instance.
            metric: key of trial info to return, e.g. "mean_accuracy".
                "training_iteration" is used by default if no value was
                passed to ``self.default_metric``.
            mode: One of [min, max]. Defaults to ``self.default_mode``.

        Returns:
            A :class:`Checkpoint <ray.tune.Checkpoint>` object
        c                 S   s   t | d  S N   )r   xr>   r>   r?   <lambda>  s    z8ExperimentAnalysis.get_best_checkpoint.<locals>.<lambda>z)No checkpoints have been found for trial .Nr%   r   c                    s    | d  S r   r>   r   score_order_factorr>   r?   r     s    )key)	r!   r   _validate_moder   r   filterr}   rz   r&   )r;   r[   r   r   checkpoints_and_metricsr   _r>   r   r?   r     s   

z&ExperimentAnalysis.get_best_checkpointlastTscopefilter_nan_and_infc           	      C   s   t | jdkr| jd S | |}| |}|dvr"td||d}d}| jD ]D}||jvr1q)|dv r=|j| | }n|j| | }|rKt|rKq)|du rT|}|}q)|dkra||k ra|}|}q)|dkrm||krm|}|}q)|sut	d	 |S )
a  Retrieve the best trial object.

        Compares all trials' scores on ``metric``.
        If ``metric`` is not specified, ``self.default_metric`` will be used.
        If `mode` is not specified, ``self.default_mode`` will be used.
        These values are usually initialized by passing the ``metric`` and
        ``mode`` parameters to ``tune.run()``.

        Args:
            metric: Key for trial info to order on. Defaults to
                ``self.default_metric``.
            mode: One of [min, max]. Defaults to ``self.default_mode``.
            scope: One of [all, last, avg, last-5-avg, last-10-avg].
                If `scope=last`, only look at each trial's final step for
                `metric`, and compare across trials based on `mode=[min,max]`.
                If `scope=avg`, consider the simple average over all steps
                for `metric` and compare across trials based on
                `mode=[min,max]`. If `scope=last-5-avg` or `scope=last-10-avg`,
                consider the simple average over the last 5 or 10 steps for
                `metric` and compare across trials based on `mode=[min,max]`.
                If `scope=all`, find each trial's min/max score for `metric`
                based on `mode`, and compare trials based on `mode=[min,max]`.
            filter_nan_and_inf: If True (default), NaN or infinite
                values are disregarded and these trials are never selected as
                the best trial.

        Returns:
            The best trial for the provided metric. If no trials contain the provided
                metric, or if the value for the metric is NaN for all trials,
                then returns None.
        r   r   )allr   avg
last-5-avglast-10-avgzExperimentAnalysis: attempting to get best trial for metric {} for scope {} not in ["all", "last", "avg", "last-5-avg", "last-10-avg"]. If you didn't pass a `metric` parameter to `tune.run()`, you have to pass one when fetching the best trial.N)r   r   r   r   r&   r%   zGCould not find best trial. Did you pass the correct `metric` parameter?)
r   r    _validate_metricr   r*   r4   metric_analysisr   r}   r~   )	r;   r   r   r   r   r   best_metric_scorer[   metric_scorer>   r>   r?   r     sJ   &


	

z!ExperimentAnalysis.get_best_trialc                 C   s   |  |||}|r|jS dS )a.  Retrieve the best config corresponding to the trial.

        Compares all trials' scores on `metric`.
        If ``metric`` is not specified, ``self.default_metric`` will be used.
        If `mode` is not specified, ``self.default_mode`` will be used.
        These values are usually initialized by passing the ``metric`` and
        ``mode`` parameters to ``tune.run()``.

        Args:
            metric: Key for trial info to order on. Defaults to
                ``self.default_metric``.
            mode: One of [min, max]. Defaults to ``self.default_mode``.
            scope: One of [all, last, avg, last-5-avg, last-10-avg].
                If `scope=last`, only look at each trial's final step for
                `metric`, and compare across trials based on `mode=[min,max]`.
                If `scope=avg`, consider the simple average over all steps
                for `metric` and compare across trials based on
                `mode=[min,max]`. If `scope=last-5-avg` or `scope=last-10-avg`,
                consider the simple average over the last 5 or 10 steps for
                `metric` and compare across trials based on `mode=[min,max]`.
                If `scope=all`, find each trial's min/max score for `metric`
                based on `mode`, and compare trials based on `mode=[min,max]`.
        N)r   r   )r;   r   r   r   r   r>   r>   r?   r   4  s   z"ExperimentAnalysis.get_best_configtraining_iterationr&   c                 C   s   |p|  ||}| |tdS )a  Gets the last checkpoint of the provided trial,
        i.e., with the highest "training_iteration".

        If no trial is specified, it loads the best trial according to the
        provided metric and mode (defaults to max. training iteration).

        Args:
            trial: If None, load the best trial automatically.
            metric: If no trial is specified, use this metric to identify
                the best trial and load the last checkpoint from this trial.
            mode: If no trial is specified, use the metric and this mode
                to identify the best trial and load the last checkpoint from it.

        Returns:
            Path for last checkpoint of trial
        r&   )r   r   r   )r;   r[   r   r   r>   r>   r?   get_last_checkpointT  s   z&ExperimentAnalysis.get_last_checkpointc                 C   s   |s	| j s	td|p| j S )NzjNo `metric` has been passed and  `default_metric` has not been set. Please specify the `metric` parameter.)r!   r*   )r;   r   r>   r>   r?   r   j  s
   

z#ExperimentAnalysis._validate_metricc                 C   s0   |s	| j s	td|r|dvrtd|p| j S )NzdNo `mode` has been passed and  `default_mode` has not been set. Please specify the `mode` parameter.r$   r   )r"   r*   )r;   r   r>   r>   r?   r   r  s   

z!ExperimentAnalysis._validate_modec              	   C   s   |d u s
|dv s
J |r|sJ i }| j  D ]C\}}|jrq||vr&d}n|dkr1||  }n|dkr<||  }nd}z|j|  ||< W q tyZ   t	d
| Y qw |S )N)r&   r%   r   r&   r%   z2Warning: Non-numerical value(s) encountered for {})r   r   emptyidxmaxidxminilocto_dict	TypeErrorr}   r~   r4   )r;   r   r   r   r/   rv   idxr>   r>   r?   r   |  s*   z!ExperimentAnalysis._retrieve_rowsc                    s:   | j  }dtdtfdd  fdd|d D |d< |S )zEnsure that trials are marked as stubs when pickling,
        so that they can be loaded later without the trainable
        being registered.
        r[   rA   c                 S   s*   | j r| S t| jdd}||   |S )NTrD   )rE   r   trainable_name__setstate____getstate__)r[   
trial_copyr>   r>   r?   make_stub_if_needed  s
   z<ExperimentAnalysis.__getstate__.<locals>.make_stub_if_neededc                    s   g | ]} |qS r>   r>   )r_   tr   r>   r?   ra     s    z3ExperimentAnalysis.__getstate__.<locals>.<listcomp>r    )__dict__rL   r   )r;   stater>   r   r?   r     s   
zExperimentAnalysis.__getstate__)F)NN)N)NNr   T)NNr   )Nr   r&   )0__name__
__module____qualname____doc__r	   r,   r.   PathLiker   pyarrowr(   
FileSystemr   r   r@   r6   r   rx   r   r7   boolr9   propertyr'   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r>   r>   r>   r?   r   #   s    


4	
(
!
*
Z
!


r   )6rL   rn   rG   loggingr.   numbersr   pathlibr   typingr   r   r   r   r   r	   
pyarrow.fsr   ray.air.constantsr
   r   r   ray.train._internal.storager   r   ray.tuner   #ray.tune.execution.experiment_stater   "ray.tune.execution.tune_controllerr   ray.tune.experimentr   ray.tune.resultr   r   ray.tune.utilsr   ray.tune.utils.serializationr   ray.tune.utils.utilr   r   r   ray.util.annotationsr   pandasrk   r   ImportError	getLoggerr   r}   r   r>   r>   r>   r?   <module>   s<     
