class_docstr: Tracks experiment specifications.
  
  Implicitly registers the Trainable if needed. The args here take
  the same meaning as the arguments defined `tune.py:run`.
  
  .. code-block:: python
  
      experiment_spec = Experiment(
          "my_experiment_name",
          my_func,
          stop={"mean_accuracy": 100},
          config={
              "alpha": tune.grid_search([0.2, 0.4, 0.6]),
              "beta": tune.grid_search([1, 2]),
          },
          resources_per_trial={
              "cpu": 1,
              "gpu": 0
          },
          num_samples=10,
          local_dir="~/ray_results",
          checkpoint_freq=10,
          max_failures=2)
class_docstr_tok: ["Tracks","experiment","specifications",".","Implicitly","registers","the","Trainable","if","needed",".","The","args","here","take","the","same","meaning","as","the","arguments","defined","`","tune.py",":","run","`",".","..","code-block",":",":","python","experiment_spec","=","Experiment","(","``","my_experiment_name","''",",","my_func",",","stop=","{","``","mean_accuracy","''",":","100","}",",","config=","{","``","alpha","''",":","tune.grid_search","(","[","0.2",",","0.4",",","0.6","]",")",",","``","beta","''",":","tune.grid_search","(","[","1",",","2","]",")",",","}",",","resources_per_trial=","{","``","cpu","''",":","1",",","``","gpu","''",":","0","}",",","num_samples=10",",","local_dir=","''","~\/ray_results","''",",","checkpoint_freq=10",",","max_failures=2",")"]
code: def __init__(
      self,
      name: str,
      run: Union[str, Callable, Type],
      *,
      stop: Optional[
          Union[Mapping, Stopper, Callable[[str, Mapping], bool]]
      ] = None,
      time_budget_s: Optional[
          Union[int, float, datetime.timedelta]
      ] = None,
      config: Optional[Dict[str, Any]] = None,
      resources_per_trial: Union[
          None,
          Mapping[str, Union[float, int, Mapping]],
          "PlacementGroupFactory",
      ] = None,
      num_samples: int = 1,
      storage_path: Optional[str] = None,
      storage_filesystem: Optional["pyarrow.fs.FileSystem"] = None,
      sync_config: Optional[Union[SyncConfig, dict]] = None,
      checkpoint_config: Optional[Union[CheckpointConfig, dict]] = None,
      trial_name_creator: Optional[Callable[["Trial"], str]] = None,
      trial_dirname_creator: Optional[Callable[["Trial"], str]] = None,
      log_to_file: bool = False,
      export_formats: Optional[Sequence] = None,
      max_failures: int = 0,
      restore: Optional[str] = None,
      # Deprecated
      local_dir: Optional[str] = None,
  ):
      if isinstance(checkpoint_config, dict):
          checkpoint_config = CheckpointConfig(**checkpoint_config)
      else:
          checkpoint_config = checkpoint_config or CheckpointConfig()
  
      if is_function_trainable(run):
          if checkpoint_config.checkpoint_at_end:
              raise ValueError(
                  "'checkpoint_at_end' cannot be used with a function trainable. "
                  "You should include one last call to "
                  "`ray.train.report(metrics=..., checkpoint=...)` "
                  "at the end of your training loop to get this behavior."
              )
          if checkpoint_config.checkpoint_frequency:
              raise ValueError(
                  "'checkpoint_frequency' cannot be set for a function trainable. "
                  "You will need to report a checkpoint every "
                  "`checkpoint_frequency` iterations within your training loop using "
                  "`ray.train.report(metrics=..., checkpoint=...)` "
                  "to get this behavior."
              )
      try:
          self._run_identifier = Experiment.register_if_needed(run)
      except RpcError as e:
          if (
              e.rpc_code
              == ray._raylet.GRPC_STATUS_CODE_RESOURCE_EXHAUSTED
          ):
              raise TuneError(
                  f"The Trainable/training function is too large for grpc resource "
                  f"limit. Check that its definition is not implicitly capturing a "
                  f"large array or other object in scope. "
                  f"Tip: use tune.with_parameters() to put large objects "
                  f"in the Ray object store. \n"
                  f"Original exception: {traceback.format_exc()}"
              )
          else:
              raise e
  
      if not name:
          name = StorageContext.get_experiment_dir_name(run)
  
      self.storage = self._storage_context_cls(
          storage_path=storage_path,
          storage_filesystem=storage_filesystem,
          sync_config=sync_config,
          experiment_dir_name=name,
      )
      logger.debug(f"StorageContext on the DRIVER:\n{self.storage}")
  
      config = config or {}
  
      self._stopper = None
      stopping_criteria = {}
      if not stop:
          pass
      elif isinstance(stop, list):
          bad_stoppers = [s for s in stop if not isinstance(s, Stopper)]
          if bad_stoppers:
              stopper_types = [type(s) for s in stop]
              raise ValueError(
                  "If you pass a list as the `stop` argument to "
                  "`train.RunConfig()`, each element must be an instance of "
                  f"`tune.stopper.Stopper`. Got {stopper_types}."
              )
          self._stopper = CombinedStopper(*stop)
      elif isinstance(stop, dict):
          stopping_criteria = stop
      elif callable(stop):
          if FunctionStopper.is_valid_function(stop):
              self._stopper = FunctionStopper(stop)
          elif isinstance(stop, Stopper):
              self._stopper = stop
          else:
              raise ValueError(
                  "Provided stop object must be either a dict, "
                  "a function, or a subclass of "
                  f"`ray.tune.Stopper`. Got {type(stop)}."
              )
      else:
          raise ValueError(
              f"Invalid stop criteria: {stop}. Must be a "
              f"callable or dict. Got {type(stop)}."
          )
  
      if time_budget_s:
          if self._stopper:
              self._stopper = CombinedStopper(
                  self._stopper, TimeoutStopper(time_budget_s)
              )
          else:
              self._stopper = TimeoutStopper(time_budget_s)
  
      stdout_file, stderr_file = _validate_log_to_file(log_to_file)
  
      spec = {
          "run": self._run_identifier,
          "stop": stopping_criteria,
          "time_budget_s": time_budget_s,
          "config": config,
          "resources_per_trial": resources_per_trial,
          "num_samples": num_samples,
          "checkpoint_config": checkpoint_config,
          "trial_name_creator": trial_name_creator,
          "trial_dirname_creator": trial_dirname_creator,
          "log_to_file": (stdout_file, stderr_file),
          "export_formats": export_formats or [],
          "max_failures": max_failures,
          "restore": (
              Path(restore).expanduser().absolute().as_posix()
              if restore
              else None
          ),
          "storage": self.storage,
      }
      self.spec = spec
  
imports: import copy
  import datetime
  from functools import partial
  import logging
  from pathlib import Path
  from pickle import PicklingError
  import pprint
  import traceback
  from typing import Any, Dict, Optional, Sequence, Union, Callable, Type, List, Mapping, TYPE_CHECKING
  import ray
  from ray.exceptions import RpcError
  from ray.train import CheckpointConfig, SyncConfig
  from ray.train._internal.storage import StorageContext
  from ray.tune.error import TuneError
  from ray.tune.registry import register_trainable, is_function_trainable
  from ray.tune.stopper import CombinedStopper, FunctionStopper, Stopper, TimeoutStopper
  from ray.util.annotations import DeveloperAPI, Deprecated
label_desc: Use image node_id 1 to create a new Experiment object  with example: obj = Experiment(name, run)