class_docstr: A utility scheduler to dynamically change resources of live trials.
  
  .. versionadded:: 1.5.0
  
  .. note::
      Experimental. API may change in future releases.
  
  The ResourceChangingScheduler works by wrapping around any other
  scheduler and adjusting the resource requirements of live trials
  in response to the decisions of the wrapped scheduler
  through a user-specified ``resources_allocation_function``.
  
  An example of such a function can be found in
  :doc:`/tune/examples/includes/xgboost_dynamic_resources_example`.
  
  If the functional API is used, the current trial resources can be obtained
  by calling `tune.get_trial_resources()` inside the training function.
  The function should be able to
  :ref:`load and save checkpoints <tune-function-trainable-checkpointing>`
  (the latter preferably every iteration).
  
  If the Trainable (class) API is used, you can obtain the current trial
  resources through the ``Trainable.trial_resources`` property.
  
  Cannot be used if ``reuse_actors`` is True in ``tune.TuneConfig()``. A ValueError
  will be raised in that case.
  
  Args:
      base_scheduler: The scheduler to provide decisions
          about trials. If None, a default FIFOScheduler will be used.
      resources_allocation_function: The callable used to change
          live trial resource requiements during tuning. This callable
          will be called on each trial as it finishes one step of training.
          The callable must take four arguments: ``TrialRunner``, current
          ``Trial``, current result :class:`dict` and the
          ``ResourceChangingScheduler`` calling it. The callable must
          return a ``PlacementGroupFactory``
          or None (signifying no need for an update). If
          ``resources_allocation_function`` is None, no resource
          requirements will be changed at any time.
          By default, :class:`DistributeResources` will be used,
          distributing available CPUs and GPUs over all running trials
          in a robust way, without any prioritization.
  
  Warning:
      If the ``resources_allocation_function`` sets trial resource
      requirements to values bigger than possible, the trial will
      not run. Ensure that your callable accounts for that possibility
      by setting upper limits. Consult :class:`DistributeResources`
      to see how that may be done.
  
  Example:
      .. code-block:: python
  
          base_scheduler = ASHAScheduler(max_t=16)
          def my_resources_allocation_function(
              tune_controller: "TuneController",
              trial: Trial,
              result: Dict[str, Any],
              scheduler: "ResourceChangingScheduler"
          ) -> Optional[Union[PlacementGroupFactory, Resource]]:
              # logic here
              # usage of PlacementGroupFactory is strongly preferred
              return PlacementGroupFactory(...)
          scheduler = ResourceChangingScheduler(
                          base_scheduler,
                          my_resources_allocation_function
                      )
  
      See :doc:`/tune/examples/includes/xgboost_dynamic_resources_example` for a
      more detailed example.
class_docstr_tok: ["A","utility","scheduler","to","dynamically","change","resources","of","live","trials",".","..","versionadded",":",":","1.5.0","..","note",":",":","Experimental",".","API","may","change","in","future","releases",".","The","ResourceChangingScheduler","works","by","wrapping","around","any","other","scheduler","and","adjusting","the","resource","requirements","of","live","trials","in","response","to","the","decisions","of","the","wrapped","scheduler","through","a","user-specified","``","resources_allocation_function","``",".","An","example","of","such","a","function","can","be","found","in",":","doc",":","`","\/tune\/examples\/includes\/xgboost_dynamic_resources_example","`",".","If","the","functional","API","is","used",",","the","current","trial","resources","can","be","obtained","by","calling","`","tune.get_trial_resources","(",")","`","inside","the","training","function",".","The","function","should","be","able","to",":","ref",":","`","load","and","save","checkpoints","<","tune-function-trainable-checkpointing",">","`","(","the","latter","preferably","every","iteration",")",".","If","the","Trainable","(","class",")","API","is","used",",","you","can","obtain","the","current","trial","resources","through","the","``","Trainable.trial_resources","``","property",".","Can","not","be","used","if","``","reuse_actors","``","is","True","in","``","tune.TuneConfig","(",")","``",".","A","ValueError","will","be","raised","in","that","case",".","Args",":","base_scheduler",":","The","scheduler","to","provide","decisions","about","trials",".","If","None",",","a","default","FIFOScheduler","will","be","used",".","resources_allocation_function",":","The","callable","used","to","change","live","trial","resource","requiements","during","tuning",".","This","callable","will","be","called","on","each","trial","as","it","finishes","one","step","of","training",".","The","callable","must","take","four","arguments",":","``","TrialRunner","``",",","current","``","Trial","``",",","current","result",":","class",":","`","dict","`","and","the","``","ResourceChangingScheduler","``","calling","it",".","The","callable","must","return","a","``","PlacementGroupFactory","``","or","None","(","signifying","no","need","for","an","update",")",".","If","``","resources_allocation_function","``","is","None",",","no","resource","requirements","will","be","changed","at","any","time",".","By","default",",",":","class",":","`","DistributeResources","`","will","be","used",",","distributing","available","CPUs","and","GPUs","over","all","running","trials","in","a","robust","way",",","without","any","prioritization",".","Warning",":","If","the","``","resources_allocation_function","``","sets","trial","resource","requirements","to","values","bigger","than","possible",",","the","trial","will","not","run",".","Ensure","that","your","callable","accounts","for","that","possibility","by","setting","upper","limits",".","Consult",":","class",":","`","DistributeResources","`","to","see","how","that","may","be","done",".","Example",":","..","code-block",":",":","python","base_scheduler","=","ASHAScheduler","(","max_t=16",")","def","my_resources_allocation_function","(","tune_controller",":","``","TuneController","''",",","trial",":","Trial",",","result",":","Dict","[","str",",","Any","]",",","scheduler",":","``","ResourceChangingScheduler","''",")","-",">","Optional","[","Union","[","PlacementGroupFactory",",","Resource","]","]",":","#","logic","here","#","usage","of","PlacementGroupFactory","is","strongly","preferred","return","PlacementGroupFactory","(","...",")","scheduler","=","ResourceChangingScheduler","(","base_scheduler",",","my_resources_allocation_function",")","See",":","doc",":","`","\/tune\/examples\/includes\/xgboost_dynamic_resources_example","`","for","a","more","detailed","example","."]
code: def choose_trial_to_run(
      self, tune_controller: "TuneController", **kwargs
  ) -> Optional[Trial]:
      if getattr(tune_controller, "_reuse_actors", False):
          raise ValueError(
              "ResourceChangingScheduler cannot be used with "
              "`reuse_actors=True`. FIX THIS by setting "
              "`reuse_actors=False` in `tune.TuneConfig()`."
          )
  
      any_resources_changed = False
  
      new_trials_to_reallocate = {}
      for trial, new_resources in self._trials_to_reallocate.items():
          if trial.status == Trial.RUNNING:
              new_trials_to_reallocate[trial] = new_resources
              logger.debug(
                  f"{trial} is still running, skipping for now"
              )
              continue
          any_resources_changed = (
              any_resources_changed
              or self.set_trial_resources(trial, new_resources)
          )
      self._trials_to_reallocate = new_trials_to_reallocate
  
      trial = self._base_scheduler.choose_trial_to_run(
          tune_controller, **kwargs
      )
      return trial
  
imports: from copy import deepcopy
  import numpy
  import logging
  from typing import Dict, Any, List, Optional, Set, Tuple, Union, Callable, TYPE_CHECKING
  import pickle
  import warnings
  from ray.air.execution.resources.request import _sum_bundles
  from ray.util.annotations import PublicAPI
  from ray.tune.schedulers.trial_scheduler import FIFOScheduler, TrialScheduler
  from ray.tune.experiment import Trial
  from ray.tune.execution.placement_groups import PlacementGroupFactory
label_desc: Use image node_id 10 for calling the ResourceChangingScheduler obj's underlying member method code with example usage: obj.choose_trial_to_run(tune_controller) and returns: trial