o
    ci(                     @   s   d dl mZmZ d dlZd dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ ed	d
G dd dZdS )    )OptionalUnionN)Result)RayTaskError)ExperimentAnalysis)	TuneError)Trial)	PublicAPIbeta)	stabilityc                   @   s"  e Zd ZdZdefddZedefddZede	j
jfdd	Z	
	
		d)dee dee dededef
ddZ	
	
d*dee dee dejfddZdefddZdedefddZedd Zedd Zed d! Zed"edeeeef  fd#d$Zd"edefd%d&Z defd'd(Z!d
S )+
ResultGrida2  A set of ``Result`` objects for interacting with Ray Tune results.

    You can use it to inspect the trials and obtain the best result.

    The constructor is a private API. This object can only be created as a result of
    ``Tuner.fit()``.

    Example:
    .. testcode::

        import random
        from ray import tune
        def random_error_trainable(config):
            if random.random() < 0.5:
                return {"loss": 0.0}
            else:
                raise ValueError("This is an error")
        tuner = tune.Tuner(
            random_error_trainable,
            run_config=tune.RunConfig(name="example-experiment"),
            tune_config=tune.TuneConfig(num_samples=10),
        )
        try:
            result_grid = tuner.fit()
        except ValueError:
            pass
        for i in range(len(result_grid)):
            result = result_grid[i]
            if not result.error:
                    print(f"Trial finishes successfully with metrics"
                       f"{result.metrics}.")
            else:
                    print(f"Trial failed with error {result.error}.")

    .. testoutput::
        :hide:

        ...

    You can also use ``result_grid`` for more advanced analysis.

    >>> # Get the best result based on a particular metric.
    >>> best_result = result_grid.get_best_result( # doctest: +SKIP
    ...     metric="loss", mode="min")
    >>> # Get the best checkpoint corresponding to the best result.
    >>> best_checkpoint = best_result.checkpoint # doctest: +SKIP
    >>> # Get a dataframe for the last reported results of all of the trials
    >>> df = result_grid.get_dataframe() # doctest: +SKIP
    >>> # Get a dataframe for the minimum loss seen for each trial
    >>> df = result_grid.get_dataframe(metric="loss", mode="min") # doctest: +SKIP

    Note that trials of all statuses are included in the final result grid.
    If a trial is not in terminated state, its latest result and checkpoint as
    seen by Tune will be provided.

    See :doc:`/tune/examples/tune_analyze_results` for more usage examples.
    experiment_analysisc                    s"   | _  fdd j jD  _d S )Nc                    s   g | ]}  |qS  )_trial_to_result).0trialselfr   H/home/ubuntu/.local/lib/python3.10/site-packages/ray/tune/result_grid.py
<listcomp>O   s    
z'ResultGrid.__init__.<locals>.<listcomp>)_experiment_analysistrials_results)r   r   r   r   r   __init__J   s   
zResultGrid.__init__returnc                 C      | j 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).)r   experiment_pathr   r   r   r   r   S   s   zResultGrid.experiment_pathc                 C   r   )zReturn the filesystem that can be used to access the experiment path.

        Returns:
            pyarrow.fs.FileSystem implementation.
        )r   _fsr   r   r   r   
filesystem[   s   zResultGrid.filesystemNlastTmetricmodescopefilter_nan_and_infc                 C   s   t | jjdkr| | jjd S |s| jjstd|s%| jjs%td| jj||||d}|sGd|p7| jj d}||r@dnd	7 }t|| |S )
a  Get the best result from all the trials run.

        Args:
            metric: Key for trial info to order on. Defaults to
                the metric specified in your Tuner's ``TuneConfig``.
            mode: One of [min, max]. Defaults to the mode specified
                in your Tuner's ``TuneConfig``.
            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.
           r   zNo metric is provided. Either pass in a `metric` arg to `get_best_result` or specify a metric in the `TuneConfig` of your `Tuner`.z|No mode is provided. Either pass in a `mode` arg to `get_best_result` or specify a mode in the `TuneConfig` of your `Tuner`.)r    r!   r"   r#   z*No best trial found for the given metric: z3. This means that no trial has reported this metricz~, or all values reported for this metric are NaN. To not ignore NaN values, you can set the `filter_nan_and_inf` arg to False..)	lenr   r   r   default_metric
ValueErrordefault_modeget_best_trialRuntimeError)r   r    r!   r"   r#   
best_trial	error_msgr   r   r   get_best_resultd   s8   

zResultGrid.get_best_resultfilter_metricfilter_modec                 C   s   | j j||dS )a4  Return dataframe of all trials with their configs and reported results.

        Per default, this returns the last reported results for each trial.

        If ``filter_metric`` and ``filter_mode`` are set, the results from each
        trial are filtered for this metric and mode. For example, if
        ``filter_metric="some_metric"`` and ``filter_mode="max"``, for each trial,
        every received result is checked, and the one where ``some_metric`` is
        maximal is returned.


        Example:

            .. testcode::

                import ray.tune

                def training_loop_per_worker(config):
                    ray.tune.report({"accuracy": 0.8})

                result_grid = ray.tune.Tuner(
                    trainable=training_loop_per_worker,
                    run_config=ray.tune.RunConfig(name="my_tune_run")
                ).fit()

                # Get last reported results per trial
                df = result_grid.get_dataframe()

                # Get best ever reported accuracy per trial
                df = result_grid.get_dataframe(
                    filter_metric="accuracy", filter_mode="max"
                )

            .. testoutput::
                :hide:

                ...

        Args:
            filter_metric: Metric to filter best result for.
            filter_mode: If ``filter_metric`` is given, one of ``["min", "max"]``
                to specify if we should find the minimum or maximum result.

        Returns:
            Pandas DataFrame with each trial as a row and their results as columns.
        )r    r!   )r   	dataframe)r   r/   r0   r   r   r   get_dataframe   s   3zResultGrid.get_dataframec                 C   s
   t | jS N)r&   r   r   r   r   r   __len__   s   
zResultGrid.__len__ic                 C   s
   | j | S )z$Returns the i'th result in the grid.)r   )r   r5   r   r   r   __getitem__   s   
zResultGrid.__getitem__c                 C   s   dd | D S )z)Returns the exceptions of errored trials.c                 S   s   g | ]}|j r|j qS r   )errorr   resultr   r   r   r          z%ResultGrid.errors.<locals>.<listcomp>r   r   r   r   r   errors   s   zResultGrid.errorsc                 C      t dd | jjD S )z%Returns the number of errored trials.c                 S      g | ]
}|j tjkr|qS r   )statusr   ERRORr   tr   r   r   r      s    z)ResultGrid.num_errors.<locals>.<listcomp>r&   r   r   r   r   r   r   
num_errors   s   zResultGrid.num_errorsc                 C   r<   )z:Returns the number of terminated (but not errored) trials.c                 S   r=   r   )r>   r   
TERMINATEDr@   r   r   r   r      s
    z-ResultGrid.num_terminated.<locals>.<listcomp>rB   r   r   r   r   num_terminated   s
   zResultGrid.num_terminatedr   c                 C   s    | j tjkrd S |  p|  S r3   )r>   r   rD   get_pickled_error	get_error)r   r   r   r   _populate_exception   s   zResultGrid._populate_exceptionc              	   C   sj   |j j}d }|jr|jj}|j}dd |D }| jj|j}t	||j
 | ||j| jj||d}|S )Nc                 S   s   g | ]}|j |jfqS r   )
checkpointmetrics)r   checkpoint_resultr   r   r   r     s    
z/ResultGrid._trial_to_result.<locals>.<listcomp>)rI   rJ   r7   path_storage_filesystemmetrics_dataframebest_checkpoints)run_metadatacheckpoint_managerlatest_checkpoint_resultrI   best_checkpoint_resultsr   trial_dataframesgettrial_idr   last_resultcopyrH   rL   r   )r   r   cpmrI   rS   rO   
metrics_dfr9   r   r   r   r      s&   	zResultGrid._trial_to_resultc                 C   s$   dd | D }d |}d| dS )Nc                 S   s   g | ]}|j d dqS )   )indent)_reprr8   r   r   r   r     r:   z'ResultGrid.__repr__.<locals>.<listcomp>z,
zResultGrid<[
z
]>)join)r   all_results_reprr   r   r   __repr__  s   
zResultGrid.__repr__)NNr   T)NN)"__name__
__module____qualname____doc__r   r   propertystrr   pyarrowfs
FileSystemr   r   boolr   r.   pd	DataFramer2   intr4   r6   r;   rC   rE   staticmethodr   r   r   r   rH   r   r`   r   r   r   r   r      sZ    :
	

C
7



 r   )typingr   r   pandasrk   rg   ray.air.resultr   ray.exceptionsr   ray.tune.analysisr   ray.tune.errorr   ray.tune.experimentr   ray.utilr	   r   r   r   r   r   <module>   s    