Enable function_descriptor in backend to replace the function_id (#3028)

This commit is contained in:
Yuhong Guo
2018-12-19 07:53:59 +08:00
committed by Robert Nishihara
parent 3822b20319
commit fb33fa9097
20 changed files with 557 additions and 282 deletions
+46 -41
View File
@@ -10,7 +10,7 @@ import sys
import traceback
import ray.cloudpickle as pickle
from ray.function_manager import FunctionActorManager
from ray.function_manager import FunctionDescriptor
import ray.raylet
import ray.ray_constants as ray_constants
import ray.signature as signature
@@ -76,18 +76,6 @@ def compute_actor_handle_id_non_forked(actor_id, actor_handle_id,
return ray.ObjectID(handle_id)
def compute_actor_creation_function_id(class_id):
"""Compute the function ID for an actor creation task.
Args:
class_id: The ID of the actor class.
Returns:
The function ID of the actor creation event.
"""
return ray.ObjectID(class_id)
def set_actor_checkpoint(worker, actor_id, checkpoint_index, checkpoint,
frontier):
"""Set the most recent checkpoint associated with a given actor ID.
@@ -287,6 +275,23 @@ class ActorClass(object):
self._actor_methods = inspect.getmembers(
self._modified_class, ray.utils.is_function_or_method)
self._actor_method_names = [
method_name for method_name, _ in self._actor_methods
]
constructor_name = "__init__"
if constructor_name not in self._actor_method_names:
# Add __init__ if it does not exist.
# Actor creation will be executed with __init__ together.
# Assign an __init__ function will avoid many checks later on.
def __init__(self):
pass
self._modified_class.__init__ = __init__
self._actor_method_names.append(constructor_name)
self._actor_methods.append((constructor_name, __init__))
# Extract the signatures of each of the methods. This will be used
# to catch some errors if the methods are called with inappropriate
# arguments.
@@ -300,7 +305,6 @@ class ActorClass(object):
signature.check_signature_supported(method, warn=True)
self._method_signatures[method_name] = signature.extract_signature(
method, ignore_first=not ray.utils.is_class_method(method))
# Set the default number of return values for this method.
if hasattr(method, "__ray_num_return_vals__"):
self._actor_method_num_return_vals[method_name] = (
@@ -309,10 +313,6 @@ class ActorClass(object):
self._actor_method_num_return_vals[method_name] = (
DEFAULT_ACTOR_METHOD_NUM_RETURN_VALS)
self._actor_method_names = [
method_name for method_name, _ in self._actor_methods
]
def __call__(self, *args, **kwargs):
raise Exception("Actors methods cannot be instantiated directly. "
"Instead of running '{}()', try '{}.remote()'.".format(
@@ -386,14 +386,14 @@ class ActorClass(object):
# Instead, instantiate the actor locally and add it to the worker's
# dictionary
if worker.mode == ray.LOCAL_MODE:
worker.actors[actor_id] = self._modified_class.__new__(
self._modified_class)
worker.actors[actor_id] = self._modified_class(
*copy.deepcopy(args), **copy.deepcopy(kwargs))
else:
# Export the actor.
if not self._exported:
worker.function_actor_manager.export_actor_class(
self._class_id, self._modified_class,
self._actor_method_names, self._checkpoint_interval)
self._modified_class, self._actor_method_names,
self._checkpoint_interval)
self._exported = True
resources = ray.utils.resources_from_resource_arguments(
@@ -409,10 +409,19 @@ class ActorClass(object):
actor_placement_resources = resources.copy()
actor_placement_resources["CPU"] += 1
creation_args = [self._class_id]
function_id = compute_actor_creation_function_id(self._class_id)
if args is None:
args = []
if kwargs is None:
kwargs = {}
function_name = "__init__"
function_signature = self._method_signatures[function_name]
creation_args = signature.extend_args(function_signature, args,
kwargs)
function_descriptor = FunctionDescriptor(
self._modified_class.__module__, function_name,
self._modified_class.__name__)
[actor_cursor] = worker.submit_task(
function_id,
function_descriptor,
creation_args,
actor_creation_id=actor_id,
max_actor_reconstructions=self._max_reconstructions,
@@ -424,19 +433,10 @@ class ActorClass(object):
# creation task.
actor_counter = 1
actor_handle = ActorHandle(
actor_id, self._class_name, actor_cursor, actor_counter,
self._actor_method_names, self._method_signatures,
self._actor_method_num_return_vals, actor_cursor,
self._actor_method_cpus, worker.task_driver_id)
# Call __init__ as a remote function.
if "__init__" in actor_handle._ray_actor_method_names:
actor_handle.__init__.remote(*args, **kwargs)
else:
if len(args) != 0 or len(kwargs) != 0:
raise Exception("Arguments cannot be passed to the actor "
"constructor because this actor class has no "
"__init__ method.")
actor_id, self._modified_class.__module__, self._class_name,
actor_cursor, actor_counter, self._actor_method_names,
self._method_signatures, self._actor_method_num_return_vals,
actor_cursor, self._actor_method_cpus, worker.task_driver_id)
return actor_handle
@@ -458,6 +458,7 @@ class ActorHandle(object):
Attributes:
_ray_actor_id: The ID of the corresponding actor.
_ray_module_name: The module name of this actor.
_ray_actor_handle_id: The ID of this handle. If this is the "original"
handle for an actor (as opposed to one created by passing another
handle into a task), then this ID must be NIL_ID. If this
@@ -496,6 +497,7 @@ class ActorHandle(object):
def __init__(self,
actor_id,
module_name,
class_name,
actor_cursor,
actor_counter,
@@ -510,6 +512,7 @@ class ActorHandle(object):
# False if this actor handle was created by forking or pickling. True
# if it was created by the _serialization_helper function.
self._ray_original_handle = previous_actor_handle_id is None
self._ray_module_name = module_name
self._ray_actor_id = actor_id
if self._ray_original_handle:
@@ -602,10 +605,10 @@ class ActorHandle(object):
else:
actor_handle_id = self._ray_actor_handle_id
function_id = FunctionActorManager.compute_actor_method_function_id(
self._ray_class_name, method_name)
function_descriptor = FunctionDescriptor(
self._ray_module_name, method_name, self._ray_class_name)
object_ids = worker.submit_task(
function_id,
function_descriptor,
args,
actor_id=self._ray_actor_id,
actor_handle_id=actor_handle_id,
@@ -706,6 +709,7 @@ class ActorHandle(object):
"""
state = {
"actor_id": self._ray_actor_id.id(),
"module_name": self._ray_module_name,
"class_name": self._ray_class_name,
"actor_forks": self._ray_actor_forks,
"actor_cursor": self._ray_actor_cursor.id()
@@ -753,6 +757,7 @@ class ActorHandle(object):
self.__init__(
ray.ObjectID(state["actor_id"]),
state["module_name"],
state["class_name"],
ray.ObjectID(state["actor_cursor"])
if state["actor_cursor"] is not None else None,