mirror of
https://github.com/wassname/ray.git
synced 2026-07-03 12:03:10 +08:00
Enable function_descriptor in backend to replace the function_id (#3028)
This commit is contained in:
committed by
Robert Nishihara
parent
3822b20319
commit
fb33fa9097
+46
-41
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user