mirror of
https://github.com/wassname/ray.git
synced 2026-07-08 22:07:19 +08:00
[sgd] Replaced class Resources in sgd with use_gpu (#5252)
This commit is contained in:
@@ -10,7 +10,8 @@ import os
|
||||
from six import string_types
|
||||
|
||||
from ray.tune import TuneError
|
||||
from ray.tune.trial import Trial, json_to_resources
|
||||
from ray.tune.trial import Trial
|
||||
from ray.tune.resources import json_to_resources
|
||||
from ray.tune.logger import _SafeFallbackEncoder
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ import traceback
|
||||
import ray
|
||||
from ray.tune.error import AbortTrialExecution
|
||||
from ray.tune.logger import NoopLogger
|
||||
from ray.tune.trial import Trial, Resources, Checkpoint
|
||||
from ray.tune.trial import Trial, Checkpoint
|
||||
from ray.tune.resources import Resources
|
||||
from ray.tune.trial_executor import TrialExecutor
|
||||
from ray.tune.util import warn_if_slow
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from collections import namedtuple
|
||||
import logging
|
||||
import json
|
||||
# For compatibility under py2 to consider unicode as str
|
||||
from six import string_types
|
||||
|
||||
from numbers import Number
|
||||
|
||||
from ray.tune import TuneError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Resources(
|
||||
namedtuple("Resources", [
|
||||
"cpu", "gpu", "extra_cpu", "extra_gpu", "custom_resources",
|
||||
"extra_custom_resources"
|
||||
])):
|
||||
"""Ray resources required to schedule a trial.
|
||||
|
||||
Attributes:
|
||||
cpu (float): Number of CPUs to allocate to the trial.
|
||||
gpu (float): Number of GPUs to allocate to the trial.
|
||||
extra_cpu (float): Extra CPUs to reserve in case the trial needs to
|
||||
launch additional Ray actors that use CPUs.
|
||||
extra_gpu (float): Extra GPUs to reserve in case the trial needs to
|
||||
launch additional Ray actors that use GPUs.
|
||||
custom_resources (dict): Mapping of resource to quantity to allocate
|
||||
to the trial.
|
||||
extra_custom_resources (dict): Extra custom resources to reserve in
|
||||
case the trial needs to launch additional Ray actors that use
|
||||
any of these custom resources.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __new__(cls,
|
||||
cpu,
|
||||
gpu,
|
||||
extra_cpu=0,
|
||||
extra_gpu=0,
|
||||
custom_resources=None,
|
||||
extra_custom_resources=None):
|
||||
custom_resources = custom_resources or {}
|
||||
extra_custom_resources = extra_custom_resources or {}
|
||||
leftovers = set(custom_resources) ^ set(extra_custom_resources)
|
||||
|
||||
for value in leftovers:
|
||||
custom_resources.setdefault(value, 0)
|
||||
extra_custom_resources.setdefault(value, 0)
|
||||
|
||||
all_values = [cpu, gpu, extra_cpu, extra_gpu]
|
||||
all_values += list(custom_resources.values())
|
||||
all_values += list(extra_custom_resources.values())
|
||||
assert len(custom_resources) == len(extra_custom_resources)
|
||||
for entry in all_values:
|
||||
assert isinstance(entry, Number), "Improper resource value."
|
||||
return super(Resources,
|
||||
cls).__new__(cls, cpu, gpu, extra_cpu, extra_gpu,
|
||||
custom_resources, extra_custom_resources)
|
||||
|
||||
def summary_string(self):
|
||||
summary = "{} CPUs, {} GPUs".format(self.cpu + self.extra_cpu,
|
||||
self.gpu + self.extra_gpu)
|
||||
custom_summary = ", ".join([
|
||||
"{} {}".format(self.get_res_total(res), res)
|
||||
for res in self.custom_resources
|
||||
])
|
||||
if custom_summary:
|
||||
summary += " ({})".format(custom_summary)
|
||||
return summary
|
||||
|
||||
def cpu_total(self):
|
||||
return self.cpu + self.extra_cpu
|
||||
|
||||
def gpu_total(self):
|
||||
return self.gpu + self.extra_gpu
|
||||
|
||||
def get_res_total(self, key):
|
||||
return self.custom_resources.get(
|
||||
key, 0) + self.extra_custom_resources.get(key, 0)
|
||||
|
||||
def get(self, key):
|
||||
return self.custom_resources.get(key, 0)
|
||||
|
||||
def is_nonnegative(self):
|
||||
all_values = [self.cpu, self.gpu, self.extra_cpu, self.extra_gpu]
|
||||
all_values += list(self.custom_resources.values())
|
||||
all_values += list(self.extra_custom_resources.values())
|
||||
return all(v >= 0 for v in all_values)
|
||||
|
||||
@classmethod
|
||||
def subtract(cls, original, to_remove):
|
||||
cpu = original.cpu - to_remove.cpu
|
||||
gpu = original.gpu - to_remove.gpu
|
||||
extra_cpu = original.extra_cpu - to_remove.extra_cpu
|
||||
extra_gpu = original.extra_gpu - to_remove.extra_gpu
|
||||
all_resources = set(original.custom_resources).union(
|
||||
set(to_remove.custom_resources))
|
||||
new_custom_res = {
|
||||
k: original.custom_resources.get(k, 0) -
|
||||
to_remove.custom_resources.get(k, 0)
|
||||
for k in all_resources
|
||||
}
|
||||
extra_custom_res = {
|
||||
k: original.extra_custom_resources.get(k, 0) -
|
||||
to_remove.extra_custom_resources.get(k, 0)
|
||||
for k in all_resources
|
||||
}
|
||||
return Resources(cpu, gpu, extra_cpu, extra_gpu, new_custom_res,
|
||||
extra_custom_res)
|
||||
|
||||
def to_json(self):
|
||||
return resources_to_json(self)
|
||||
|
||||
|
||||
def json_to_resources(data):
|
||||
if data is None or data == "null":
|
||||
return None
|
||||
if isinstance(data, string_types):
|
||||
data = json.loads(data)
|
||||
for k in data:
|
||||
if k in ["driver_cpu_limit", "driver_gpu_limit"]:
|
||||
raise TuneError(
|
||||
"The field `{}` is no longer supported. Use `extra_cpu` "
|
||||
"or `extra_gpu` instead.".format(k))
|
||||
if k not in Resources._fields:
|
||||
raise ValueError(
|
||||
"Unknown resource field {}, must be one of {}".format(
|
||||
k, Resources._fields))
|
||||
return Resources(
|
||||
data.get("cpu", 1), data.get("gpu", 0), data.get("extra_cpu", 0),
|
||||
data.get("extra_gpu", 0), data.get("custom_resources"),
|
||||
data.get("extra_custom_resources"))
|
||||
|
||||
|
||||
def resources_to_json(resources):
|
||||
if resources is None:
|
||||
return None
|
||||
return {
|
||||
"cpu": resources.cpu,
|
||||
"gpu": resources.gpu,
|
||||
"extra_cpu": resources.extra_cpu,
|
||||
"extra_gpu": resources.extra_gpu,
|
||||
"custom_resources": resources.custom_resources.copy(),
|
||||
"extra_custom_resources": resources.extra_custom_resources.copy()
|
||||
}
|
||||
@@ -11,7 +11,8 @@ from ray.tune import Trainable
|
||||
from ray.tune.ray_trial_executor import RayTrialExecutor
|
||||
from ray.tune.registry import _global_registry, TRAINABLE_CLASS
|
||||
from ray.tune.suggest import BasicVariantGenerator
|
||||
from ray.tune.trial import Trial, Checkpoint, Resources
|
||||
from ray.tune.trial import Trial, Checkpoint
|
||||
from ray.tune.resources import Resources
|
||||
|
||||
|
||||
class RayTrialExecutorTest(unittest.TestCase):
|
||||
|
||||
@@ -27,9 +27,9 @@ from ray.tune.result import (DEFAULT_RESULTS_DIR, TIMESTEPS_TOTAL, DONE,
|
||||
from ray.tune.logger import Logger
|
||||
from ray.tune.util import pin_in_object_store, get_pinned_object
|
||||
from ray.tune.experiment import Experiment
|
||||
from ray.tune.trial import (Trial, ExportFormat, Resources, resources_to_json,
|
||||
json_to_resources)
|
||||
from ray.tune.trial import Trial, ExportFormat
|
||||
from ray.tune.trial_runner import TrialRunner
|
||||
from ray.tune.resources import Resources, json_to_resources, resources_to_json
|
||||
from ray.tune.suggest import grid_search, BasicVariantGenerator
|
||||
from ray.tune.suggest.suggestion import (_MockSuggestionAlgorithm,
|
||||
SuggestionAlgorithm)
|
||||
|
||||
@@ -18,8 +18,9 @@ from ray.tune.schedulers import (HyperBandScheduler, AsyncHyperBandScheduler,
|
||||
TrialScheduler)
|
||||
|
||||
from ray.tune.schedulers.pbt import explore
|
||||
from ray.tune.trial import Trial, Resources, Checkpoint
|
||||
from ray.tune.trial import Trial, Checkpoint
|
||||
from ray.tune.trial_executor import TrialExecutor
|
||||
from ray.tune.resources import Resources
|
||||
|
||||
from ray.rllib import _register_all
|
||||
_register_all()
|
||||
|
||||
+1
-144
@@ -2,21 +2,14 @@ from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from collections import namedtuple
|
||||
import ray.cloudpickle as cloudpickle
|
||||
import copy
|
||||
from datetime import datetime
|
||||
import logging
|
||||
import json
|
||||
import uuid
|
||||
import time
|
||||
import tempfile
|
||||
import os
|
||||
from numbers import Number
|
||||
|
||||
# For compatibility under py2 to consider unicode as str
|
||||
from six import string_types
|
||||
|
||||
import ray
|
||||
from ray.tune import TuneError
|
||||
from ray.tune.logger import pretty_print, UnifiedLogger
|
||||
@@ -28,6 +21,7 @@ from ray.tune.result import (DEFAULT_RESULTS_DIR, DONE, HOSTNAME, PID,
|
||||
TIME_TOTAL_S, TRAINING_ITERATION, TIMESTEPS_TOTAL,
|
||||
EPISODE_REWARD_MEAN, MEAN_LOSS, MEAN_ACCURACY)
|
||||
from ray.utils import binary_to_hex, hex_to_binary
|
||||
from ray.tune.resources import Resources, json_to_resources, resources_to_json
|
||||
|
||||
DEBUG_PRINT_INTERVAL = 5
|
||||
MAX_LEN_IDENTIFIER = int(os.environ.get("MAX_LEN_IDENTIFIER", 130))
|
||||
@@ -38,143 +32,6 @@ def date_str():
|
||||
return datetime.today().strftime("%Y-%m-%d_%H-%M-%S")
|
||||
|
||||
|
||||
class Resources(
|
||||
namedtuple("Resources", [
|
||||
"cpu", "gpu", "extra_cpu", "extra_gpu", "custom_resources",
|
||||
"extra_custom_resources"
|
||||
])):
|
||||
"""Ray resources required to schedule a trial.
|
||||
|
||||
Attributes:
|
||||
cpu (float): Number of CPUs to allocate to the trial.
|
||||
gpu (float): Number of GPUs to allocate to the trial.
|
||||
extra_cpu (float): Extra CPUs to reserve in case the trial needs to
|
||||
launch additional Ray actors that use CPUs.
|
||||
extra_gpu (float): Extra GPUs to reserve in case the trial needs to
|
||||
launch additional Ray actors that use GPUs.
|
||||
custom_resources (dict): Mapping of resource to quantity to allocate
|
||||
to the trial.
|
||||
extra_custom_resources (dict): Extra custom resources to reserve in
|
||||
case the trial needs to launch additional Ray actors that use
|
||||
any of these custom resources.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __new__(cls,
|
||||
cpu,
|
||||
gpu,
|
||||
extra_cpu=0,
|
||||
extra_gpu=0,
|
||||
custom_resources=None,
|
||||
extra_custom_resources=None):
|
||||
custom_resources = custom_resources or {}
|
||||
extra_custom_resources = extra_custom_resources or {}
|
||||
leftovers = set(custom_resources) ^ set(extra_custom_resources)
|
||||
|
||||
for value in leftovers:
|
||||
custom_resources.setdefault(value, 0)
|
||||
extra_custom_resources.setdefault(value, 0)
|
||||
|
||||
all_values = [cpu, gpu, extra_cpu, extra_gpu]
|
||||
all_values += list(custom_resources.values())
|
||||
all_values += list(extra_custom_resources.values())
|
||||
assert len(custom_resources) == len(extra_custom_resources)
|
||||
for entry in all_values:
|
||||
assert isinstance(entry, Number), "Improper resource value."
|
||||
return super(Resources,
|
||||
cls).__new__(cls, cpu, gpu, extra_cpu, extra_gpu,
|
||||
custom_resources, extra_custom_resources)
|
||||
|
||||
def summary_string(self):
|
||||
summary = "{} CPUs, {} GPUs".format(self.cpu + self.extra_cpu,
|
||||
self.gpu + self.extra_gpu)
|
||||
custom_summary = ", ".join([
|
||||
"{} {}".format(self.get_res_total(res), res)
|
||||
for res in self.custom_resources
|
||||
])
|
||||
if custom_summary:
|
||||
summary += " ({})".format(custom_summary)
|
||||
return summary
|
||||
|
||||
def cpu_total(self):
|
||||
return self.cpu + self.extra_cpu
|
||||
|
||||
def gpu_total(self):
|
||||
return self.gpu + self.extra_gpu
|
||||
|
||||
def get_res_total(self, key):
|
||||
return self.custom_resources.get(
|
||||
key, 0) + self.extra_custom_resources.get(key, 0)
|
||||
|
||||
def get(self, key):
|
||||
return self.custom_resources.get(key, 0)
|
||||
|
||||
def is_nonnegative(self):
|
||||
all_values = [self.cpu, self.gpu, self.extra_cpu, self.extra_gpu]
|
||||
all_values += list(self.custom_resources.values())
|
||||
all_values += list(self.extra_custom_resources.values())
|
||||
return all(v >= 0 for v in all_values)
|
||||
|
||||
@classmethod
|
||||
def subtract(cls, original, to_remove):
|
||||
cpu = original.cpu - to_remove.cpu
|
||||
gpu = original.gpu - to_remove.gpu
|
||||
extra_cpu = original.extra_cpu - to_remove.extra_cpu
|
||||
extra_gpu = original.extra_gpu - to_remove.extra_gpu
|
||||
all_resources = set(original.custom_resources).union(
|
||||
set(to_remove.custom_resources))
|
||||
new_custom_res = {
|
||||
k: original.custom_resources.get(k, 0) -
|
||||
to_remove.custom_resources.get(k, 0)
|
||||
for k in all_resources
|
||||
}
|
||||
extra_custom_res = {
|
||||
k: original.extra_custom_resources.get(k, 0) -
|
||||
to_remove.extra_custom_resources.get(k, 0)
|
||||
for k in all_resources
|
||||
}
|
||||
return Resources(cpu, gpu, extra_cpu, extra_gpu, new_custom_res,
|
||||
extra_custom_res)
|
||||
|
||||
def to_json(self):
|
||||
return resources_to_json(self)
|
||||
|
||||
|
||||
def json_to_resources(data):
|
||||
if data is None or data == "null":
|
||||
return None
|
||||
if isinstance(data, string_types):
|
||||
data = json.loads(data)
|
||||
for k in data:
|
||||
if k in ["driver_cpu_limit", "driver_gpu_limit"]:
|
||||
raise TuneError(
|
||||
"The field `{}` is no longer supported. Use `extra_cpu` "
|
||||
"or `extra_gpu` instead.".format(k))
|
||||
if k not in Resources._fields:
|
||||
raise ValueError(
|
||||
"Unknown resource field {}, must be one of {}".format(
|
||||
k, Resources._fields))
|
||||
return Resources(
|
||||
data.get("cpu", 1), data.get("gpu", 0), data.get("extra_cpu", 0),
|
||||
data.get("extra_gpu", 0), data.get("custom_resources"),
|
||||
data.get("extra_custom_resources"))
|
||||
|
||||
|
||||
def resources_to_json(resources):
|
||||
if resources is None:
|
||||
return None
|
||||
return {
|
||||
"cpu": resources.cpu,
|
||||
"gpu": resources.gpu,
|
||||
"extra_cpu": resources.extra_cpu,
|
||||
"extra_gpu": resources.extra_gpu,
|
||||
"custom_resources": resources.custom_resources.copy(),
|
||||
"extra_custom_resources": resources.extra_custom_resources.copy()
|
||||
}
|
||||
|
||||
|
||||
def has_trainable(trainable_name):
|
||||
return ray.tune.registry._global_registry.contains(
|
||||
ray.tune.registry.TRAINABLE_CLASS, trainable_name)
|
||||
|
||||
Reference in New Issue
Block a user