mirror of
https://github.com/wassname/ray.git
synced 2026-07-10 12:58:04 +08:00
Migrate Python C extension to Cython (#3541)
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# NOTE: These must be checked before including Cython packages to ensure we are using the right python version.
|
||||
# Segfaults could happen if we are using the wrong version.
|
||||
set(PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIRS})
|
||||
|
||||
# Find Cython executable
|
||||
get_filename_component(_python_path ${PYTHON_EXECUTABLE} PATH)
|
||||
find_program(CYTHON_EXECUTABLE
|
||||
NAMES cython cython.bat cython3
|
||||
HINTS ${_python_path})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cython REQUIRED_VARS CYTHON_EXECUTABLE)
|
||||
|
||||
include(UseCython)
|
||||
|
||||
include_directories("${NUMPY_INCLUDE_DIR}")
|
||||
include_directories("${CMAKE_CURRENT_LIST_DIR}/../src")
|
||||
include_directories("${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
# Include some generated Arrow headers.
|
||||
include_directories("${ARROW_SOURCE_DIR}/../arrow_ep-build/src")
|
||||
|
||||
# If the pyx file is a C++ file, we should specify that here.
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_LIST_DIR}/ray/_raylet.pyx
|
||||
PROPERTIES CYTHON_IS_CXX TRUE)
|
||||
|
||||
set(RAY_SRC_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../src/ray")
|
||||
|
||||
cython_add_module(
|
||||
_raylet
|
||||
${RAY_SRC_DIRECTORY}/raylet/raylet_client.cc
|
||||
${CMAKE_CURRENT_LIST_DIR}/ray/_raylet.pyx)
|
||||
|
||||
add_dependencies(_raylet ray_static)
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(_raylet "-undefined dynamic_lookup" ray_static)
|
||||
else()
|
||||
target_link_libraries(_raylet ray_static)
|
||||
endif()
|
||||
|
||||
# Make sure that the Python extensions are built before copying the files.
|
||||
add_dependencies(copy_ray _raylet)
|
||||
+12
-3
@@ -49,7 +49,12 @@ except ImportError as e:
|
||||
modin_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "modin")
|
||||
sys.path.append(modin_path)
|
||||
|
||||
from ray.raylet import ObjectID, _config # noqa: E402
|
||||
from ray._raylet import (UniqueID, ObjectID, DriverID, ClientID, ActorID,
|
||||
ActorHandleID, FunctionID, ActorClassID, TaskID,
|
||||
Config as _Config) # noqa: E402
|
||||
|
||||
_config = _Config()
|
||||
|
||||
from ray.profiling import profile # noqa: E402
|
||||
from ray.worker import (error_info, init, connect, disconnect, get, put, wait,
|
||||
remote, get_gpu_ids, get_resource_ids, get_webui_url,
|
||||
@@ -72,8 +77,12 @@ __all__ = [
|
||||
"remote", "profile", "actor", "method", "get_gpu_ids", "get_resource_ids",
|
||||
"get_webui_url", "register_custom_serializer", "shutdown",
|
||||
"is_initialized", "SCRIPT_MODE", "WORKER_MODE", "LOCAL_MODE",
|
||||
"PYTHON_MODE", "global_state", "ObjectID", "_config", "__version__",
|
||||
"internal"
|
||||
"PYTHON_MODE", "global_state", "_config", "__version__", "internal"
|
||||
]
|
||||
|
||||
__all__ += [
|
||||
"UniqueID", "ObjectID", "DriverID", "ClientID", "ActorID", "ActorHandleID",
|
||||
"FunctionID", "ActorClassID", "TaskID"
|
||||
]
|
||||
|
||||
import ctypes # noqa: E402
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
# cython: profile=False
|
||||
# distutils: language = c++
|
||||
# cython: embedsignature = True
|
||||
# cython: language_level = 3
|
||||
|
||||
from libc.stdint cimport int32_t, int64_t
|
||||
from libcpp cimport bool as c_bool
|
||||
from libcpp.memory cimport unique_ptr
|
||||
from libcpp.string cimport string as c_string
|
||||
from libcpp.utility cimport pair
|
||||
from libcpp.unordered_map cimport unordered_map
|
||||
from libcpp.vector cimport vector as c_vector
|
||||
|
||||
from ray.includes.common cimport (
|
||||
CUniqueID, CTaskID, CObjectID, CFunctionID, CActorClassID, CActorID,
|
||||
CActorHandleID, CWorkerID, CDriverID, CConfigID, CClientID,
|
||||
CLanguage, CRayStatus, LANGUAGE_CPP, LANGUAGE_JAVA, LANGUAGE_PYTHON)
|
||||
from ray.includes.libraylet cimport (
|
||||
CRayletClient, GCSProfileTableDataT, GCSProfileEventT,
|
||||
ResourceMappingType, WaitResultPair)
|
||||
from ray.includes.task cimport CTaskSpecification
|
||||
from ray.includes.ray_config cimport RayConfig
|
||||
from ray.utils import decode
|
||||
|
||||
from cython.operator import dereference, postincrement
|
||||
cimport cpython
|
||||
|
||||
include "includes/unique_ids.pxi"
|
||||
include "includes/ray_config.pxi"
|
||||
include "includes/task.pxi"
|
||||
|
||||
|
||||
if cpython.PY_MAJOR_VERSION >= 3:
|
||||
import pickle
|
||||
else:
|
||||
import cPickle as pickle
|
||||
import numpy
|
||||
|
||||
|
||||
cdef int check_status(const CRayStatus& status) nogil except -1:
|
||||
if status.ok():
|
||||
return 0
|
||||
|
||||
with gil:
|
||||
message = status.message().decode()
|
||||
raise Exception(message)
|
||||
|
||||
|
||||
cdef c_vector[CObjectID] ObjectIDsToVector(object_ids):
|
||||
"""A helper function that converts a Python list of object IDs to a vector.
|
||||
|
||||
Args:
|
||||
object_ids (list): The Python list of object IDs.
|
||||
|
||||
Returns:
|
||||
The output vector.
|
||||
"""
|
||||
cdef:
|
||||
ObjectID object_id
|
||||
c_vector[CObjectID] result
|
||||
for object_id in object_ids:
|
||||
result.push_back(object_id.data)
|
||||
return result
|
||||
|
||||
|
||||
cdef VectorToObjectIDs(c_vector[CObjectID] object_ids):
|
||||
result = []
|
||||
for i in range(object_ids.size()):
|
||||
result.append(ObjectID.from_native(object_ids[i]))
|
||||
return result
|
||||
|
||||
|
||||
def compute_put_id(TaskID task_id, int64_t put_index):
|
||||
if put_index < 1 or put_index > kMaxTaskPuts:
|
||||
raise ValueError("The range of 'put_index' should be [1, %d]" % kMaxTaskPuts)
|
||||
return ObjectID.from_native(ComputePutId(task_id.data, put_index))
|
||||
|
||||
|
||||
def compute_task_id(ObjectID object_id):
|
||||
return TaskID.from_native(ComputeTaskId(object_id.data))
|
||||
|
||||
|
||||
cdef c_bool is_simple_value(value, int *num_elements_contained):
|
||||
num_elements_contained[0] += 1
|
||||
|
||||
if num_elements_contained[0] >= RayConfig.instance().num_elements_limit():
|
||||
return False
|
||||
|
||||
if (cpython.PyInt_Check(value) or cpython.PyLong_Check(value) or value is False or
|
||||
value is True or cpython.PyFloat_Check(value) or value is None):
|
||||
return True
|
||||
|
||||
if cpython.PyBytes_CheckExact(value):
|
||||
num_elements_contained[0] += cpython.PyBytes_Size(value)
|
||||
return num_elements_contained[0] < RayConfig.instance().num_elements_limit()
|
||||
|
||||
if cpython.PyUnicode_CheckExact(value):
|
||||
num_elements_contained[0] += cpython.PyUnicode_GET_SIZE(value)
|
||||
return num_elements_contained[0] < RayConfig.instance().num_elements_limit()
|
||||
|
||||
if cpython.PyList_CheckExact(value) and cpython.PyList_Size(value) < RayConfig.instance().size_limit():
|
||||
for item in value:
|
||||
if not is_simple_value(item, num_elements_contained):
|
||||
return False
|
||||
return num_elements_contained[0] < RayConfig.instance().num_elements_limit()
|
||||
|
||||
if cpython.PyDict_CheckExact(value) and cpython.PyDict_Size(value) < RayConfig.instance().size_limit():
|
||||
# TODO(suquark): Using "items" in Python2 is not very efficient.
|
||||
for k, v in value.items():
|
||||
if not (is_simple_value(k, num_elements_contained) and is_simple_value(v, num_elements_contained)):
|
||||
return False
|
||||
return num_elements_contained[0] < RayConfig.instance().num_elements_limit()
|
||||
|
||||
if cpython.PyTuple_CheckExact(value) and cpython.PyTuple_Size(value) < RayConfig.instance().size_limit():
|
||||
for item in value:
|
||||
if not is_simple_value(item, num_elements_contained):
|
||||
return False
|
||||
return num_elements_contained[0] < RayConfig.instance().num_elements_limit()
|
||||
|
||||
if isinstance(value, numpy.ndarray):
|
||||
if value.dtype == "O":
|
||||
return False
|
||||
num_elements_contained[0] += value.nbytes
|
||||
return num_elements_contained[0] < RayConfig.instance().num_elements_limit()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def check_simple_value(value):
|
||||
"""Check if value is simple enough to be send by value.
|
||||
|
||||
This method checks if a Python object is sufficiently simple that it can be
|
||||
serialized and passed by value as an argument to a task (without being put in
|
||||
the object store). The details of which objects are sufficiently simple are
|
||||
defined by this method and are not particularly important. But for
|
||||
performance reasons, it is better to place "small" objects in the task itself
|
||||
and "large" objects in the object store.
|
||||
|
||||
Args:
|
||||
value: Python object that should be checked.
|
||||
|
||||
Returns:
|
||||
True if the value should be send by value, False otherwise.
|
||||
"""
|
||||
|
||||
cdef int num_elements_contained = 0
|
||||
return is_simple_value(value, &num_elements_contained)
|
||||
|
||||
|
||||
cdef class Language:
|
||||
cdef CLanguage lang
|
||||
def __cinit__(self, int32_t lang):
|
||||
self.lang = <CLanguage>lang
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CLanguage& lang):
|
||||
return Language(<int32_t>lang)
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, Language) and (<int32_t>self.lang) == (<int32_t>other.lang)
|
||||
|
||||
def __repr__(self):
|
||||
if <int32_t>self.lang == <int32_t>LANGUAGE_PYTHON:
|
||||
return "PYTHON"
|
||||
elif <int32_t>self.lang == <int32_t>LANGUAGE_CPP:
|
||||
return "CPP"
|
||||
elif <int32_t>self.lang == <int32_t>LANGUAGE_JAVA:
|
||||
return "JAVA"
|
||||
else:
|
||||
raise Exception("Unexpected error")
|
||||
|
||||
|
||||
# Programming language enum values.
|
||||
cdef Language LANG_PYTHON = Language.from_native(LANGUAGE_PYTHON)
|
||||
cdef Language LANG_CPP = Language.from_native(LANGUAGE_CPP)
|
||||
cdef Language LANG_JAVA = Language.from_native(LANGUAGE_JAVA)
|
||||
|
||||
|
||||
cdef unordered_map[c_string, double] resource_map_from_python_dict(resource_map):
|
||||
cdef:
|
||||
unordered_map[c_string, double] out
|
||||
c_string resource_name
|
||||
if not isinstance(resource_map, dict):
|
||||
raise TypeError("resource_map must be a dictionary")
|
||||
for key, value in resource_map.items():
|
||||
out[key.encode("ascii")] = float(value)
|
||||
return out
|
||||
|
||||
|
||||
cdef class RayletClient:
|
||||
cdef unique_ptr[CRayletClient] client
|
||||
def __cinit__(self, raylet_socket,
|
||||
ClientID client_id,
|
||||
c_bool is_worker,
|
||||
DriverID driver_id):
|
||||
# We know that we are using Python, so just skip the language parameter.
|
||||
# TODO(suquark): Should we allow unicode chars in "raylet_socket"?
|
||||
self.client.reset(new CRayletClient(raylet_socket.encode("ascii"), client_id.data,
|
||||
is_worker, driver_id.data, LANGUAGE_PYTHON))
|
||||
|
||||
def disconnect(self):
|
||||
check_status(self.client.get().Disconnect())
|
||||
|
||||
def submit_task(self, Task task_spec):
|
||||
check_status(self.client.get().SubmitTask(task_spec.execution_dependencies.get()[0], task_spec.task_spec.get()[0]))
|
||||
|
||||
def get_task(self):
|
||||
cdef:
|
||||
unique_ptr[CTaskSpecification] task_spec
|
||||
|
||||
with nogil:
|
||||
check_status(self.client.get().GetTask(&task_spec))
|
||||
return Task.make(task_spec)
|
||||
|
||||
def task_done(self):
|
||||
check_status(self.client.get().TaskDone())
|
||||
|
||||
def fetch_or_reconstruct(self, object_ids,
|
||||
c_bool fetch_only, TaskID current_task_id=TaskID.nil()):
|
||||
cdef c_vector[CObjectID] fetch_ids = ObjectIDsToVector(object_ids)
|
||||
check_status(self.client.get().FetchOrReconstruct(fetch_ids, fetch_only, current_task_id.data))
|
||||
|
||||
def notify_unblocked(self, TaskID current_task_id):
|
||||
check_status(self.client.get().NotifyUnblocked(current_task_id.data))
|
||||
|
||||
def wait(self, object_ids, int num_returns, int64_t timeout_milliseconds,
|
||||
c_bool wait_local, TaskID current_task_id):
|
||||
cdef:
|
||||
WaitResultPair result
|
||||
c_vector[CObjectID] wait_ids
|
||||
wait_ids = ObjectIDsToVector(object_ids)
|
||||
check_status(self.client.get().Wait(wait_ids, num_returns, timeout_milliseconds,
|
||||
wait_local, current_task_id.data, &result))
|
||||
return VectorToObjectIDs(result.first), VectorToObjectIDs(result.second)
|
||||
|
||||
def resource_ids(self):
|
||||
cdef:
|
||||
ResourceMappingType resource_mapping = self.client.get().GetResourceIDs()
|
||||
unordered_map[c_string, c_vector[pair[int64_t, double]]].iterator iterator = resource_mapping.begin()
|
||||
c_vector[pair[int64_t, double]] c_value
|
||||
resources_dict = {}
|
||||
while iterator != resource_mapping.end():
|
||||
key = decode(dereference(iterator).first)
|
||||
c_value = dereference(iterator).second
|
||||
ids_and_fractions = []
|
||||
for i in range(c_value.size()):
|
||||
ids_and_fractions.append((c_value[i].first, c_value[i].second))
|
||||
resources_dict[key] = ids_and_fractions
|
||||
postincrement(iterator)
|
||||
return resources_dict
|
||||
|
||||
def push_error(self, DriverID job_id, error_type, error_message,
|
||||
double timestamp):
|
||||
check_status(self.client.get().PushError(job_id.data,
|
||||
error_type.encode("ascii"),
|
||||
error_message.encode("ascii"),
|
||||
timestamp))
|
||||
|
||||
def push_profile_events(self, component_type, UniqueID component_id,
|
||||
node_ip_address, profile_data):
|
||||
cdef:
|
||||
GCSProfileTableDataT profile_info
|
||||
GCSProfileEventT *profile_event
|
||||
c_string event_type
|
||||
|
||||
if len(profile_data) == 0:
|
||||
return # Short circuit if there are no profile events.
|
||||
|
||||
profile_info.component_type = component_type.encode("ascii")
|
||||
profile_info.component_id = component_id.binary()
|
||||
profile_info.node_ip_address = node_ip_address.encode("ascii")
|
||||
|
||||
for py_profile_event in profile_data:
|
||||
profile_event = new GCSProfileEventT()
|
||||
if not isinstance(py_profile_event, dict):
|
||||
raise TypeError("Incorrect type for a profile event. Expected dict instead of '%s'" % str(type(py_profile_event)))
|
||||
# TODO(rkn): If the dictionary is formatted incorrectly, that could lead
|
||||
# to errors. E.g., if any of the strings are empty, that will cause
|
||||
# segfaults in the node manager.
|
||||
for key_string, event_data in py_profile_event.items():
|
||||
if key_string == "event_type":
|
||||
profile_event.event_type = event_data.encode("ascii")
|
||||
if profile_event.event_type.length() == 0:
|
||||
raise ValueError("'event_type' should not be a null string.")
|
||||
elif key_string == "start_time":
|
||||
profile_event.start_time = float(event_data)
|
||||
elif key_string == "end_time":
|
||||
profile_event.end_time = float(event_data)
|
||||
elif key_string == "extra_data":
|
||||
profile_event.extra_data = event_data.encode("ascii")
|
||||
if profile_event.extra_data.length() == 0:
|
||||
raise ValueError("'extra_data' should not be a null string.")
|
||||
else:
|
||||
raise ValueError("Unknown profile event key '%s'" % key_string)
|
||||
# Note that profile_info.profile_events is a vector of unique pointers, so
|
||||
# profile_event will be deallocated when profile_info goes out of scope.
|
||||
# "emplace_back" of vector has not been supported by Cython
|
||||
profile_info.profile_events.push_back(unique_ptr[GCSProfileEventT](profile_event))
|
||||
|
||||
check_status(self.client.get().PushProfileEvents(profile_info))
|
||||
|
||||
def free_objects(self, object_ids, c_bool local_only):
|
||||
cdef c_vector[CObjectID] free_ids = ObjectIDsToVector(object_ids)
|
||||
check_status(self.client.get().FreeObjects(free_ids, local_only))
|
||||
|
||||
@property
|
||||
def language(self):
|
||||
return Language.from_native(self.client.get().GetLanguage())
|
||||
|
||||
@property
|
||||
def client_id(self):
|
||||
return ClientID.from_native(self.client.get().GetClientID())
|
||||
|
||||
@property
|
||||
def driver_id(self):
|
||||
return DriverID.from_native(self.client.get().GetDriverID())
|
||||
|
||||
@property
|
||||
def is_worker(self):
|
||||
return self.client.get().IsWorker()
|
||||
+38
-33
@@ -12,12 +12,12 @@ import traceback
|
||||
|
||||
import ray.cloudpickle as pickle
|
||||
from ray.function_manager import FunctionDescriptor
|
||||
import ray.raylet
|
||||
import ray.ray_constants as ray_constants
|
||||
import ray.signature as signature
|
||||
import ray.worker
|
||||
from ray.utils import _random_string
|
||||
from ray import ObjectID
|
||||
from ray import (ObjectID, ActorID, ActorHandleID, ActorClassID, TaskID,
|
||||
DriverID)
|
||||
|
||||
DEFAULT_ACTOR_METHOD_NUM_RETURN_VALS = 1
|
||||
|
||||
@@ -38,11 +38,12 @@ def compute_actor_handle_id(actor_handle_id, num_forks):
|
||||
Returns:
|
||||
An ID for the new actor handle.
|
||||
"""
|
||||
assert isinstance(actor_handle_id, ActorHandleID)
|
||||
handle_id_hash = hashlib.sha1()
|
||||
handle_id_hash.update(actor_handle_id.id())
|
||||
handle_id_hash.update(actor_handle_id.binary())
|
||||
handle_id_hash.update(str(num_forks).encode("ascii"))
|
||||
handle_id = handle_id_hash.digest()
|
||||
return ObjectID(handle_id)
|
||||
return ActorHandleID(handle_id)
|
||||
|
||||
|
||||
def compute_actor_handle_id_non_forked(actor_handle_id, current_task_id):
|
||||
@@ -65,11 +66,13 @@ def compute_actor_handle_id_non_forked(actor_handle_id, current_task_id):
|
||||
Returns:
|
||||
An ID for the new actor handle.
|
||||
"""
|
||||
assert isinstance(actor_handle_id, ActorHandleID)
|
||||
assert isinstance(current_task_id, TaskID)
|
||||
handle_id_hash = hashlib.sha1()
|
||||
handle_id_hash.update(actor_handle_id.id())
|
||||
handle_id_hash.update(current_task_id.id())
|
||||
handle_id_hash.update(actor_handle_id.binary())
|
||||
handle_id_hash.update(current_task_id.binary())
|
||||
handle_id = handle_id_hash.digest()
|
||||
return ObjectID(handle_id)
|
||||
return ActorHandleID(handle_id)
|
||||
|
||||
|
||||
def set_actor_checkpoint(worker, actor_id, checkpoint_index, checkpoint,
|
||||
@@ -83,7 +86,8 @@ def set_actor_checkpoint(worker, actor_id, checkpoint_index, checkpoint,
|
||||
checkpoint: The state object to save.
|
||||
frontier: The task frontier at the time of the checkpoint.
|
||||
"""
|
||||
actor_key = b"Actor:" + actor_id.id()
|
||||
assert isinstance(actor_id, ActorID)
|
||||
actor_key = b"Actor:" + actor_id.binary()
|
||||
worker.redis_client.hmset(
|
||||
actor_key, {
|
||||
"checkpoint_index": checkpoint_index,
|
||||
@@ -155,7 +159,8 @@ def get_actor_checkpoint(worker, actor_id):
|
||||
exists, all objects are set to None. The checkpoint index is the .
|
||||
executed on the actor before the checkpoint was made.
|
||||
"""
|
||||
actor_key = b"Actor:" + actor_id.id()
|
||||
assert isinstance(actor_id, ActorID)
|
||||
actor_key = b"Actor:" + actor_id.binary()
|
||||
checkpoint_index, checkpoint, frontier = worker.redis_client.hmget(
|
||||
actor_key, ["checkpoint_index", "checkpoint", "frontier"])
|
||||
if checkpoint_index is not None:
|
||||
@@ -370,7 +375,7 @@ class ActorClass(object):
|
||||
raise Exception("Actors cannot be created before ray.init() "
|
||||
"has been called.")
|
||||
|
||||
actor_id = ObjectID(_random_string())
|
||||
actor_id = ActorID(_random_string())
|
||||
# The actor cursor is a dummy object representing the most recent
|
||||
# actor method invocation. For each subsequent method invocation,
|
||||
# the current cursor should be added as a dependency, and then
|
||||
@@ -423,6 +428,7 @@ class ActorClass(object):
|
||||
num_return_vals=1,
|
||||
resources=resources,
|
||||
placement_resources=actor_placement_resources)
|
||||
assert isinstance(actor_cursor, ObjectID)
|
||||
|
||||
actor_handle = ActorHandle(
|
||||
actor_id, self._modified_class.__module__, self._class_name,
|
||||
@@ -502,14 +508,17 @@ class ActorHandle(object):
|
||||
actor_method_cpus,
|
||||
actor_driver_id,
|
||||
actor_handle_id=None):
|
||||
assert isinstance(actor_id, ActorID)
|
||||
assert isinstance(actor_driver_id, DriverID)
|
||||
self._ray_actor_id = actor_id
|
||||
self._ray_module_name = module_name
|
||||
# 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 = actor_handle_id is None
|
||||
if self._ray_original_handle:
|
||||
self._ray_actor_handle_id = ObjectID.nil_id()
|
||||
self._ray_actor_handle_id = ActorHandleID.nil()
|
||||
else:
|
||||
assert isinstance(actor_handle_id, ActorHandleID)
|
||||
self._ray_actor_handle_id = actor_handle_id
|
||||
self._ray_actor_cursor = actor_cursor
|
||||
self._ray_actor_counter = 0
|
||||
@@ -646,7 +655,7 @@ class ActorHandle(object):
|
||||
# not just the first one.
|
||||
worker = ray.worker.get_global_worker()
|
||||
if (worker.mode == ray.worker.SCRIPT_MODE
|
||||
and self._ray_actor_driver_id.id() != worker.worker_id):
|
||||
and self._ray_actor_driver_id.binary() != worker.worker_id):
|
||||
# If the worker is a driver and driver id has changed because
|
||||
# Ray was shut down re-initialized, the actor is already cleaned up
|
||||
# and we don't need to send `__ray_terminate__` again.
|
||||
@@ -684,22 +693,22 @@ class ActorHandle(object):
|
||||
else:
|
||||
actor_handle_id = self._ray_actor_handle_id
|
||||
|
||||
# Note: _ray_actor_cursor and _ray_actor_creation_dummy_object_id
|
||||
# could be None.
|
||||
state = {
|
||||
"actor_id": self._ray_actor_id.id(),
|
||||
"actor_handle_id": actor_handle_id.id(),
|
||||
"actor_id": self._ray_actor_id,
|
||||
"actor_handle_id": actor_handle_id,
|
||||
"module_name": self._ray_module_name,
|
||||
"class_name": self._ray_class_name,
|
||||
"actor_cursor": self._ray_actor_cursor.id()
|
||||
if self._ray_actor_cursor is not None else None,
|
||||
"actor_cursor": self._ray_actor_cursor,
|
||||
"actor_method_names": self._ray_actor_method_names,
|
||||
"method_signatures": self._ray_method_signatures,
|
||||
"method_num_return_vals": self._ray_method_num_return_vals,
|
||||
# Actors in local mode don't have dummy objects.
|
||||
"actor_creation_dummy_object_id": self.
|
||||
_ray_actor_creation_dummy_object_id.id()
|
||||
if self._ray_actor_creation_dummy_object_id is not None else None,
|
||||
_ray_actor_creation_dummy_object_id,
|
||||
"actor_method_cpus": self._ray_actor_method_cpus,
|
||||
"actor_driver_id": self._ray_actor_driver_id.id(),
|
||||
"actor_driver_id": self._ray_actor_driver_id,
|
||||
"ray_forking": ray_forking
|
||||
}
|
||||
|
||||
@@ -711,7 +720,7 @@ class ActorHandle(object):
|
||||
# to release, since it could be unpickled and submit another
|
||||
# dependent task at any time. Therefore, we notify the backend of a
|
||||
# random handle ID that will never actually be used.
|
||||
new_actor_handle_id = ObjectID(_random_string())
|
||||
new_actor_handle_id = ActorHandleID(_random_string())
|
||||
# Notify the backend to expect this new actor handle. The backend will
|
||||
# not release the cursor for any new handles until the first task for
|
||||
# each of the new handles is submitted.
|
||||
@@ -733,7 +742,7 @@ class ActorHandle(object):
|
||||
worker.check_connected()
|
||||
|
||||
if state["ray_forking"]:
|
||||
actor_handle_id = ObjectID(state["actor_handle_id"])
|
||||
actor_handle_id = state["actor_handle_id"]
|
||||
else:
|
||||
# Right now, if the actor handle has been pickled, we create a
|
||||
# temporary actor handle id for invocations.
|
||||
@@ -747,25 +756,21 @@ class ActorHandle(object):
|
||||
# same actor is likely a performance bug. We should consider
|
||||
# logging a warning in these cases.
|
||||
actor_handle_id = compute_actor_handle_id_non_forked(
|
||||
ObjectID(state["actor_handle_id"]), worker.current_task_id)
|
||||
|
||||
# This is the driver ID of the driver that owns the actor, not
|
||||
# necessarily the driver that owns this actor handle.
|
||||
actor_driver_id = ObjectID(state["actor_driver_id"])
|
||||
state["actor_handle_id"], worker.current_task_id)
|
||||
|
||||
self.__init__(
|
||||
ObjectID(state["actor_id"]),
|
||||
state["actor_id"],
|
||||
state["module_name"],
|
||||
state["class_name"],
|
||||
ObjectID(state["actor_cursor"])
|
||||
if state["actor_cursor"] is not None else None,
|
||||
state["actor_cursor"],
|
||||
state["actor_method_names"],
|
||||
state["method_signatures"],
|
||||
state["method_num_return_vals"],
|
||||
ObjectID(state["actor_creation_dummy_object_id"])
|
||||
if state["actor_creation_dummy_object_id"] is not None else None,
|
||||
state["actor_creation_dummy_object_id"],
|
||||
state["actor_method_cpus"],
|
||||
actor_driver_id,
|
||||
# This is the driver ID of the driver that owns the actor, not
|
||||
# necessarily the driver that owns this actor handle.
|
||||
state["actor_driver_id"],
|
||||
actor_handle_id=actor_handle_id)
|
||||
|
||||
def __getstate__(self):
|
||||
@@ -887,7 +892,7 @@ def make_actor(cls, num_cpus, num_gpus, resources, actor_method_cpus,
|
||||
Class.__module__ = cls.__module__
|
||||
Class.__name__ = cls.__name__
|
||||
|
||||
class_id = _random_string()
|
||||
class_id = ActorClassID(_random_string())
|
||||
|
||||
return ActorClass(Class, class_id, checkpoint_interval,
|
||||
max_reconstructions, num_cpus, num_gpus, resources,
|
||||
|
||||
@@ -215,7 +215,7 @@ class PlasmaEventHandler:
|
||||
if not isinstance(object_id, ray.ObjectID):
|
||||
raise TypeError("Input should be an ObjectID.")
|
||||
|
||||
plain_object_id = plasma.ObjectID(object_id.id())
|
||||
plain_object_id = plasma.ObjectID(object_id.binary())
|
||||
fut = PlasmaObjectFuture(loop=self._loop, object_id=plain_object_id)
|
||||
|
||||
if check_ready:
|
||||
|
||||
@@ -91,7 +91,7 @@ def _task_table_shard(shard_index):
|
||||
for key in task_table_keys:
|
||||
task_id_binary = key[len(TASK_PREFIX):]
|
||||
results[binary_to_hex(task_id_binary)] = ray.global_state._task_table(
|
||||
ray.ObjectID(task_id_binary))
|
||||
ray.TaskID(task_id_binary))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ def parse_client_table(redis_client):
|
||||
Returns:
|
||||
A list of information about the nodes in the cluster.
|
||||
"""
|
||||
NIL_CLIENT_ID = ray.ObjectID.nil_id().id()
|
||||
NIL_CLIENT_ID = ray.ObjectID.nil().binary()
|
||||
message = redis_client.execute_command("RAY.TABLE_LOOKUP",
|
||||
ray.gcs_utils.TablePrefix.CLIENT,
|
||||
"", NIL_CLIENT_ID)
|
||||
@@ -216,8 +216,7 @@ class GlobalState(object):
|
||||
"""Fetch and parse the object table information for a single object ID.
|
||||
|
||||
Args:
|
||||
object_id_binary: A string of bytes with the object ID to get
|
||||
information about.
|
||||
object_id: An object ID to get information about.
|
||||
|
||||
Returns:
|
||||
A dictionary with information about the object ID in question.
|
||||
@@ -229,7 +228,7 @@ class GlobalState(object):
|
||||
# Return information about a single object ID.
|
||||
message = self._execute_command(object_id, "RAY.TABLE_LOOKUP",
|
||||
ray.gcs_utils.TablePrefix.OBJECT, "",
|
||||
object_id.id())
|
||||
object_id.binary())
|
||||
gcs_entry = ray.gcs_utils.GcsTableEntry.GetRootAsGcsTableEntry(
|
||||
message, 0)
|
||||
|
||||
@@ -284,15 +283,15 @@ class GlobalState(object):
|
||||
"""Fetch and parse the task table information for a single task ID.
|
||||
|
||||
Args:
|
||||
task_id_binary: A string of bytes with the task ID to get
|
||||
information about.
|
||||
task_id: A task ID to get information about.
|
||||
|
||||
Returns:
|
||||
A dictionary with information about the task ID in question.
|
||||
"""
|
||||
assert isinstance(task_id, ray.TaskID)
|
||||
message = self._execute_command(task_id, "RAY.TABLE_LOOKUP",
|
||||
ray.gcs_utils.TablePrefix.RAYLET_TASK,
|
||||
"", task_id.id())
|
||||
"", task_id.binary())
|
||||
gcs_entries = ray.gcs_utils.GcsTableEntry.GetRootAsGcsTableEntry(
|
||||
message, 0)
|
||||
|
||||
@@ -303,23 +302,23 @@ class GlobalState(object):
|
||||
|
||||
execution_spec = task_table_message.TaskExecutionSpec()
|
||||
task_spec = task_table_message.TaskSpecification()
|
||||
task_spec = ray.raylet.task_from_string(task_spec)
|
||||
function_descriptor_list = task_spec.function_descriptor_list()
|
||||
task = ray._raylet.Task.from_string(task_spec)
|
||||
function_descriptor_list = task.function_descriptor_list()
|
||||
function_descriptor = FunctionDescriptor.from_bytes_list(
|
||||
function_descriptor_list)
|
||||
task_spec_info = {
|
||||
"DriverID": task_spec.driver_id().hex(),
|
||||
"TaskID": task_spec.task_id().hex(),
|
||||
"ParentTaskID": task_spec.parent_task_id().hex(),
|
||||
"ParentCounter": task_spec.parent_counter(),
|
||||
"ActorID": (task_spec.actor_id().hex()),
|
||||
"ActorCreationID": task_spec.actor_creation_id().hex(),
|
||||
"DriverID": task.driver_id().hex(),
|
||||
"TaskID": task.task_id().hex(),
|
||||
"ParentTaskID": task.parent_task_id().hex(),
|
||||
"ParentCounter": task.parent_counter(),
|
||||
"ActorID": (task.actor_id().hex()),
|
||||
"ActorCreationID": task.actor_creation_id().hex(),
|
||||
"ActorCreationDummyObjectID": (
|
||||
task_spec.actor_creation_dummy_object_id().hex()),
|
||||
"ActorCounter": task_spec.actor_counter(),
|
||||
"Args": task_spec.arguments(),
|
||||
"ReturnObjectIDs": task_spec.returns(),
|
||||
"RequiredResources": task_spec.required_resources(),
|
||||
task.actor_creation_dummy_object_id().hex()),
|
||||
"ActorCounter": task.actor_counter(),
|
||||
"Args": task.arguments(),
|
||||
"ReturnObjectIDs": task.returns(),
|
||||
"RequiredResources": task.required_resources(),
|
||||
"FunctionID": function_descriptor.function_id.hex(),
|
||||
"FunctionHash": binary_to_hex(function_descriptor.function_hash),
|
||||
"ModuleName": function_descriptor.module_name,
|
||||
@@ -351,7 +350,7 @@ class GlobalState(object):
|
||||
"""
|
||||
self._check_connected()
|
||||
if task_id is not None:
|
||||
task_id = ray.ObjectID(hex_to_binary(task_id))
|
||||
task_id = ray.TaskID(hex_to_binary(task_id))
|
||||
return self._task_table(task_id)
|
||||
else:
|
||||
task_table_keys = self._keys(
|
||||
@@ -364,7 +363,7 @@ class GlobalState(object):
|
||||
results = {}
|
||||
for task_id_binary in task_ids_binary:
|
||||
results[binary_to_hex(task_id_binary)] = self._task_table(
|
||||
ray.ObjectID(task_id_binary))
|
||||
ray.TaskID(task_id_binary))
|
||||
return results
|
||||
|
||||
def function_table(self, function_id=None):
|
||||
@@ -439,7 +438,7 @@ class GlobalState(object):
|
||||
# events and should also support returning a window of events.
|
||||
message = self._execute_command(batch_id, "RAY.TABLE_LOOKUP",
|
||||
ray.gcs_utils.TablePrefix.PROFILE, "",
|
||||
batch_id.id())
|
||||
batch_id.binary())
|
||||
|
||||
if message is None:
|
||||
return []
|
||||
@@ -877,9 +876,10 @@ class GlobalState(object):
|
||||
Returns:
|
||||
A list of the error messages for this job.
|
||||
"""
|
||||
assert isinstance(job_id, ray.DriverID)
|
||||
message = self.redis_client.execute_command(
|
||||
"RAY.TABLE_LOOKUP", ray.gcs_utils.TablePrefix.ERROR_INFO, "",
|
||||
job_id.id())
|
||||
job_id.binary())
|
||||
|
||||
# If there are no errors, return early.
|
||||
if message is None:
|
||||
@@ -891,7 +891,7 @@ class GlobalState(object):
|
||||
for i in range(gcs_entries.EntriesLength()):
|
||||
error_data = ray.gcs_utils.ErrorTableData.GetRootAsErrorTableData(
|
||||
gcs_entries.Entries(i), 0)
|
||||
assert job_id.id() == error_data.JobId()
|
||||
assert job_id.binary() == error_data.JobId()
|
||||
error_message = {
|
||||
"type": decode(error_data.Type()),
|
||||
"message": decode(error_data.ErrorMessage()),
|
||||
@@ -912,6 +912,7 @@ class GlobalState(object):
|
||||
that job.
|
||||
"""
|
||||
if job_id is not None:
|
||||
assert isinstance(job_id, ray.DriverID)
|
||||
return self._error_messages(job_id)
|
||||
|
||||
error_table_keys = self.redis_client.keys(
|
||||
@@ -922,6 +923,6 @@ class GlobalState(object):
|
||||
]
|
||||
|
||||
return {
|
||||
binary_to_hex(job_id): self._error_messages(ray.ObjectID(job_id))
|
||||
binary_to_hex(job_id): self._error_messages(ray.DriverID(job_id))
|
||||
for job_id in job_ids
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ class FunctionDescriptor(object):
|
||||
ray.ObjectID to represent the function descriptor.
|
||||
"""
|
||||
if self.is_for_driver_task:
|
||||
return ray.ObjectID.nil_id()
|
||||
return ray.FunctionID.nil()
|
||||
function_id_hash = hashlib.sha1()
|
||||
# Include the function module and name in the hash.
|
||||
function_id_hash.update(self.module_name.encode("ascii"))
|
||||
@@ -232,7 +232,7 @@ class FunctionDescriptor(object):
|
||||
function_id_hash.update(self._function_source_hash)
|
||||
# Compute the function ID.
|
||||
function_id = function_id_hash.digest()
|
||||
return ray.ObjectID(function_id)
|
||||
return ray.FunctionID(function_id)
|
||||
|
||||
def get_function_descriptor_list(self):
|
||||
"""Return a list of bytes representing the function descriptor.
|
||||
@@ -355,13 +355,13 @@ class FunctionActorManager(object):
|
||||
check_oversized_pickle(pickled_function,
|
||||
remote_function._function_name,
|
||||
"remote function", self._worker)
|
||||
key = (b"RemoteFunction:" + self._worker.task_driver_id.id() + b":" +
|
||||
remote_function._function_descriptor.function_id.id())
|
||||
key = (b"RemoteFunction:" + self._worker.task_driver_id.binary() + b":"
|
||||
+ remote_function._function_descriptor.function_id.binary())
|
||||
self._worker.redis_client.hmset(
|
||||
key, {
|
||||
"driver_id": self._worker.task_driver_id.id(),
|
||||
"driver_id": self._worker.task_driver_id.binary(),
|
||||
"function_id": remote_function._function_descriptor.
|
||||
function_id.id(),
|
||||
function_id.binary(),
|
||||
"name": remote_function._function_name,
|
||||
"module": function.__module__,
|
||||
"function": pickled_function,
|
||||
@@ -377,8 +377,8 @@ class FunctionActorManager(object):
|
||||
"driver_id", "function_id", "name", "function", "num_return_vals",
|
||||
"module", "resources", "max_calls"
|
||||
])
|
||||
function_id = ray.ObjectID(function_id_str)
|
||||
driver_id = ray.ObjectID(driver_id_str)
|
||||
function_id = ray.FunctionID(function_id_str)
|
||||
driver_id = ray.DriverID(driver_id_str)
|
||||
function_name = decode(function_name)
|
||||
max_calls = int(max_calls)
|
||||
module = decode(module)
|
||||
@@ -406,7 +406,7 @@ class FunctionActorManager(object):
|
||||
traceback_str,
|
||||
driver_id=driver_id,
|
||||
data={
|
||||
"function_id": function_id.id(),
|
||||
"function_id": function_id.binary(),
|
||||
"function_name": function_name
|
||||
})
|
||||
else:
|
||||
@@ -423,7 +423,8 @@ class FunctionActorManager(object):
|
||||
max_calls=max_calls))
|
||||
# Add the function to the function table.
|
||||
self._worker.redis_client.rpush(
|
||||
b"FunctionTable:" + function_id.id(), self._worker.worker_id)
|
||||
b"FunctionTable:" + function_id.binary(),
|
||||
self._worker.worker_id)
|
||||
|
||||
def get_execution_info(self, driver_id, function_descriptor):
|
||||
"""Get the FunctionExecutionInfo of a remote function.
|
||||
@@ -524,14 +525,14 @@ class FunctionActorManager(object):
|
||||
"You might have started a background thread in a non-actor task, "
|
||||
"please make sure the thread finishes before the task finishes.")
|
||||
driver_id = self._worker.task_driver_id
|
||||
key = (b"ActorClass:" + driver_id.id() + b":" +
|
||||
function_descriptor.function_id.id())
|
||||
key = (b"ActorClass:" + driver_id.binary() + b":" +
|
||||
function_descriptor.function_id.binary())
|
||||
actor_class_info = {
|
||||
"class_name": Class.__name__,
|
||||
"module": Class.__module__,
|
||||
"class": pickle.dumps(Class),
|
||||
"checkpoint_interval": checkpoint_interval,
|
||||
"driver_id": driver_id.id(),
|
||||
"driver_id": driver_id.binary(),
|
||||
"actor_method_names": json.dumps(list(actor_method_names))
|
||||
}
|
||||
|
||||
@@ -556,8 +557,8 @@ class FunctionActorManager(object):
|
||||
# because of https://github.com/ray-project/ray/issues/1146.
|
||||
|
||||
def load_actor(self, driver_id, function_descriptor):
|
||||
key = (b"ActorClass:" + driver_id.id() + b":" +
|
||||
function_descriptor.function_id.id())
|
||||
key = (b"ActorClass:" + driver_id.binary() + b":" +
|
||||
function_descriptor.function_id.binary())
|
||||
# Wait for the actor class key to have been imported by the
|
||||
# import thread. TODO(rkn): It shouldn't be possible to end
|
||||
# up in an infinite loop here, but we should push an error to
|
||||
@@ -588,7 +589,7 @@ class FunctionActorManager(object):
|
||||
|
||||
class_name = decode(class_name)
|
||||
module = decode(module)
|
||||
driver_id = ray.ObjectID(driver_id_str)
|
||||
driver_id = ray.DriverID(driver_id_str)
|
||||
checkpoint_interval = int(checkpoint_interval)
|
||||
actor_method_names = json.loads(decode(actor_method_names))
|
||||
|
||||
@@ -645,7 +646,7 @@ class FunctionActorManager(object):
|
||||
ray_constants.REGISTER_ACTOR_PUSH_ERROR,
|
||||
traceback_str,
|
||||
driver_id,
|
||||
data={"actor_id": actor_id.id()})
|
||||
data={"actor_id": actor_id.binary()})
|
||||
# TODO(rkn): In the future, it might make sense to have the worker
|
||||
# exit here. However, currently that would lead to hanging if
|
||||
# someone calls ray.get on a method invoked on the actor.
|
||||
|
||||
@@ -58,7 +58,7 @@ def construct_error_message(driver_id, error_type, message, timestamp):
|
||||
The serialized object.
|
||||
"""
|
||||
builder = flatbuffers.Builder(0)
|
||||
driver_offset = builder.CreateString(driver_id.id())
|
||||
driver_offset = builder.CreateString(driver_id.binary())
|
||||
error_type_offset = builder.CreateString(error_type)
|
||||
message_offset = builder.CreateString(message)
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ class ImportThread(object):
|
||||
|
||||
if (utils.decode(run_on_other_drivers) == "False"
|
||||
and self.worker.mode == ray.SCRIPT_MODE
|
||||
and driver_id != self.worker.task_driver_id.id()):
|
||||
and driver_id != self.worker.task_driver_id.binary()):
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -131,5 +131,5 @@ class ImportThread(object):
|
||||
self.worker,
|
||||
ray_constants.FUNCTION_TO_RUN_PUSH_ERROR,
|
||||
traceback_str,
|
||||
driver_id=ray.ObjectID(driver_id),
|
||||
driver_id=ray.DriverID(driver_id),
|
||||
data={"name": name})
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
from libcpp.string cimport string as c_string
|
||||
from libcpp cimport bool as c_bool
|
||||
|
||||
from libc.stdint cimport int64_t
|
||||
from libcpp.unordered_map cimport unordered_map
|
||||
from libcpp.vector cimport vector as c_vector
|
||||
|
||||
from ray.includes.unique_ids cimport (
|
||||
CUniqueID, TaskID as CTaskID, ObjectID as CObjectID,
|
||||
FunctionID as CFunctionID, ActorClassID as CActorClassID, ActorID as CActorID,
|
||||
ActorHandleID as CActorHandleID, WorkerID as CWorkerID,
|
||||
DriverID as CDriverID, ConfigID as CConfigID, ClientID as CClientID)
|
||||
|
||||
|
||||
cdef extern from "ray/status.h" namespace "ray" nogil:
|
||||
cdef cppclass StatusCode:
|
||||
pass
|
||||
|
||||
cdef cppclass CRayStatus "ray::Status":
|
||||
RayStatus()
|
||||
RayStatus(StatusCode code, const c_string &msg)
|
||||
RayStatus(const CRayStatus &s);
|
||||
|
||||
@staticmethod
|
||||
CRayStatus OK()
|
||||
@staticmethod
|
||||
CRayStatus OutOfMemory()
|
||||
@staticmethod
|
||||
CRayStatus KeyError()
|
||||
@staticmethod
|
||||
CRayStatus Invalid()
|
||||
@staticmethod
|
||||
CRayStatus IOError()
|
||||
@staticmethod
|
||||
CRayStatus TypeError()
|
||||
@staticmethod
|
||||
CRayStatus UnknownError()
|
||||
@staticmethod
|
||||
CRayStatus NotImplemented()
|
||||
@staticmethod
|
||||
CRayStatus RedisError()
|
||||
|
||||
c_bool ok()
|
||||
c_bool IsOutOfMemory()
|
||||
c_bool IsKeyError()
|
||||
c_bool IsInvalid()
|
||||
c_bool IsIOError()
|
||||
c_bool IsTypeError()
|
||||
c_bool IsUnknownError()
|
||||
c_bool IsNotImplemented()
|
||||
c_bool IsRedisError()
|
||||
|
||||
c_string ToString()
|
||||
c_string CodeAsString()
|
||||
StatusCode code()
|
||||
c_string message()
|
||||
|
||||
# We can later add more of the common status factory methods as needed
|
||||
cdef CRayStatus RayStatus_OK "Status::OK"()
|
||||
cdef CRayStatus RayStatus_Invalid "Status::Invalid"()
|
||||
|
||||
|
||||
cdef extern from "ray/status.h" namespace "ray::StatusCode" nogil:
|
||||
cdef StatusCode StatusCode_OK "OK"
|
||||
cdef StatusCode StatusCode_OutOfMemory "OutOfMemory"
|
||||
cdef StatusCode StatusCode_KeyError "KeyError"
|
||||
cdef StatusCode StatusCode_TypeError "TypeError"
|
||||
cdef StatusCode StatusCode_Invalid "Invalid"
|
||||
cdef StatusCode StatusCode_IOError "IOError"
|
||||
cdef StatusCode StatusCode_UnknownError "UnknownError"
|
||||
cdef StatusCode StatusCode_NotImplemented "NotImplemented"
|
||||
cdef StatusCode StatusCode_RedisError "RedisError"
|
||||
|
||||
|
||||
cdef extern from "ray/id.h" namespace "ray" nogil:
|
||||
const CTaskID FinishTaskId(const CTaskID &task_id)
|
||||
const CObjectID ComputeReturnId(const CTaskID &task_id,
|
||||
int64_t return_index)
|
||||
const CObjectID ComputePutId(const CTaskID &task_id, int64_t put_index)
|
||||
const CTaskID ComputeTaskId(const CObjectID &object_id)
|
||||
const CTaskID GenerateTaskId(const CDriverID &driver_id,
|
||||
const CTaskID &parent_task_id,
|
||||
int parent_task_counter)
|
||||
int64_t ComputeObjectIndex(const CObjectID &object_id)
|
||||
|
||||
|
||||
cdef extern from "ray/gcs/format/gcs_generated.h" nogil:
|
||||
cdef cppclass GCSArg "Arg":
|
||||
pass
|
||||
|
||||
cdef cppclass CLanguage "Language":
|
||||
pass
|
||||
|
||||
|
||||
# This is a workaround for C++ enum class since Cython has no corresponding representation.
|
||||
cdef extern from "ray/gcs/format/gcs_generated.h" namespace "Language" nogil:
|
||||
cdef CLanguage LANGUAGE_PYTHON "Language::PYTHON"
|
||||
cdef CLanguage LANGUAGE_CPP "Language::CPP"
|
||||
cdef CLanguage LANGUAGE_JAVA "Language::JAVA"
|
||||
|
||||
|
||||
cdef extern from "ray/raylet/scheduling_resources.h" namespace "ray::raylet" nogil:
|
||||
cdef cppclass ResourceSet "ResourceSet":
|
||||
ResourceSet()
|
||||
ResourceSet(const unordered_map[c_string, double] &resource_map)
|
||||
ResourceSet(const c_vector[c_string] &resource_labels, const c_vector[double] resource_capacity)
|
||||
c_bool operator==(const ResourceSet &rhs) const
|
||||
c_bool IsEqual(const ResourceSet &other) const
|
||||
c_bool IsSubset(const ResourceSet &other) const
|
||||
c_bool IsSuperset(const ResourceSet &other) const
|
||||
c_bool AddResource(const c_string &resource_name, double capacity)
|
||||
c_bool RemoveResource(const c_string &resource_name)
|
||||
c_bool AddResourcesStrict(const ResourceSet &other)
|
||||
void AddResources(const ResourceSet &other)
|
||||
c_bool SubtractResourcesStrict(const ResourceSet &other)
|
||||
c_bool GetResource(const c_string &resource_name, double *value) const
|
||||
double GetNumCpus() const
|
||||
c_bool IsEmpty() const
|
||||
const unordered_map[c_string, double] &GetResourceMap() const
|
||||
const c_string ToString() const
|
||||
@@ -0,0 +1,64 @@
|
||||
from libc.stdint cimport int64_t
|
||||
from libcpp cimport bool as c_bool
|
||||
from libcpp.memory cimport unique_ptr
|
||||
from libcpp.string cimport string as c_string
|
||||
from libcpp.utility cimport pair
|
||||
from libcpp.unordered_map cimport unordered_map
|
||||
from libcpp.vector cimport vector as c_vector
|
||||
|
||||
|
||||
from ray.includes.common cimport (
|
||||
CUniqueID, CTaskID, CObjectID, CFunctionID, CActorClassID, CActorID,
|
||||
CActorHandleID, CWorkerID, CDriverID, CConfigID, CClientID,
|
||||
CLanguage, CRayStatus)
|
||||
from ray.includes.task cimport CTaskSpecification
|
||||
|
||||
|
||||
cdef extern from "ray/gcs/format/gcs_generated.h" nogil:
|
||||
cdef cppclass GCSProfileEventT "ProfileEventT":
|
||||
c_string event_type
|
||||
double start_time
|
||||
double end_time
|
||||
c_string extra_data
|
||||
GCSProfileEventT()
|
||||
|
||||
cdef cppclass GCSProfileTableDataT "ProfileTableDataT":
|
||||
c_string component_type
|
||||
c_string component_id
|
||||
c_string node_ip_address
|
||||
c_vector[unique_ptr[GCSProfileEventT]] profile_events
|
||||
GCSProfileTableDataT()
|
||||
|
||||
|
||||
ctypedef unordered_map[c_string, c_vector[pair[int64_t, double]]] ResourceMappingType
|
||||
ctypedef pair[c_vector[CObjectID], c_vector[CObjectID]] WaitResultPair
|
||||
|
||||
|
||||
cdef extern from "ray/raylet/raylet_client.h" nogil:
|
||||
cdef cppclass CRayletClient "RayletClient":
|
||||
CRayletClient(const c_string &raylet_socket,
|
||||
const CClientID &client_id,
|
||||
c_bool is_worker, const CDriverID &driver_id,
|
||||
const CLanguage &language)
|
||||
CRayStatus Disconnect()
|
||||
CRayStatus SubmitTask(const c_vector[CObjectID] &execution_dependencies,
|
||||
const CTaskSpecification &task_spec)
|
||||
CRayStatus GetTask(unique_ptr[CTaskSpecification] *task_spec)
|
||||
CRayStatus TaskDone()
|
||||
CRayStatus FetchOrReconstruct(c_vector[CObjectID] &object_ids,
|
||||
c_bool fetch_only,
|
||||
const CTaskID ¤t_task_id)
|
||||
CRayStatus NotifyUnblocked(const CTaskID ¤t_task_id)
|
||||
CRayStatus Wait(const c_vector[CObjectID] &object_ids, int num_returns,
|
||||
int64_t timeout_milliseconds, c_bool wait_local,
|
||||
const CTaskID ¤t_task_id, WaitResultPair *result)
|
||||
CRayStatus PushError(const CDriverID &job_id, const c_string &type,
|
||||
const c_string &error_message, double timestamp)
|
||||
CRayStatus PushProfileEvents(const GCSProfileTableDataT &profile_events)
|
||||
CRayStatus FreeObjects(const c_vector[CObjectID] &object_ids,
|
||||
c_bool local_only)
|
||||
CLanguage GetLanguage() const
|
||||
CClientID GetClientID() const
|
||||
CDriverID GetDriverID() const
|
||||
c_bool IsWorker() const
|
||||
const ResourceMappingType &GetResourceIDs() const
|
||||
@@ -0,0 +1,83 @@
|
||||
from libc.stdint cimport int64_t, uint64_t
|
||||
from libcpp.string cimport string as c_string
|
||||
from libcpp.unordered_map cimport unordered_map
|
||||
|
||||
|
||||
cdef extern from "ray/ray_config.h" nogil:
|
||||
cdef cppclass RayConfig "RayConfig":
|
||||
@staticmethod
|
||||
RayConfig &instance()
|
||||
|
||||
int64_t ray_protocol_version() const
|
||||
|
||||
int64_t handler_warning_timeout_ms() const
|
||||
|
||||
int64_t heartbeat_timeout_milliseconds() const
|
||||
|
||||
int64_t debug_dump_period_milliseconds() const
|
||||
|
||||
int64_t num_heartbeats_timeout() const
|
||||
|
||||
uint64_t num_heartbeats_warning() const
|
||||
|
||||
int64_t initial_reconstruction_timeout_milliseconds() const
|
||||
|
||||
int64_t get_timeout_milliseconds() const
|
||||
|
||||
uint64_t max_lineage_size() const
|
||||
|
||||
int64_t worker_get_request_size() const
|
||||
|
||||
int64_t worker_fetch_request_size() const
|
||||
|
||||
int64_t actor_max_dummy_objects() const
|
||||
|
||||
int64_t num_connect_attempts() const
|
||||
|
||||
int64_t connect_timeout_milliseconds() const
|
||||
|
||||
int64_t local_scheduler_fetch_timeout_milliseconds() const
|
||||
|
||||
int64_t local_scheduler_reconstruction_timeout_milliseconds() const
|
||||
|
||||
int64_t max_num_to_reconstruct() const
|
||||
|
||||
int64_t local_scheduler_fetch_request_size() const
|
||||
|
||||
int64_t kill_worker_timeout_milliseconds() const
|
||||
|
||||
int64_t max_time_for_handler_milliseconds() const
|
||||
|
||||
int64_t size_limit() const
|
||||
|
||||
int64_t num_elements_limit() const
|
||||
|
||||
int64_t max_time_for_loop() const
|
||||
|
||||
int64_t redis_db_connect_retries()
|
||||
|
||||
int64_t redis_db_connect_wait_milliseconds() const
|
||||
|
||||
int64_t plasma_default_release_delay() const
|
||||
|
||||
int64_t L3_cache_size_bytes() const
|
||||
|
||||
int64_t max_tasks_to_spillback() const
|
||||
|
||||
int64_t actor_creation_num_spillbacks_warning() const
|
||||
|
||||
int node_manager_forward_task_retry_timeout_milliseconds() const
|
||||
|
||||
int object_manager_pull_timeout_ms() const
|
||||
|
||||
int object_manager_push_timeout_ms() const
|
||||
|
||||
int object_manager_repeated_push_delay_ms() const
|
||||
|
||||
uint64_t object_manager_default_chunk_size() const
|
||||
|
||||
int num_workers_per_process() const
|
||||
|
||||
int64_t max_task_lease_timeout_ms() const
|
||||
|
||||
void initialize(const unordered_map[c_string, int] &config_map)
|
||||
@@ -0,0 +1,146 @@
|
||||
from ray.includes.ray_config cimport RayConfig
|
||||
|
||||
cdef class Config:
|
||||
@staticmethod
|
||||
def ray_protocol_version():
|
||||
return RayConfig.instance().ray_protocol_version()
|
||||
|
||||
@staticmethod
|
||||
def handler_warning_timeout_ms():
|
||||
return RayConfig.instance().handler_warning_timeout_ms()
|
||||
|
||||
@staticmethod
|
||||
def heartbeat_timeout_milliseconds():
|
||||
return RayConfig.instance().heartbeat_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def debug_dump_period_milliseconds():
|
||||
return RayConfig.instance().debug_dump_period_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def num_heartbeats_timeout():
|
||||
return RayConfig.instance().num_heartbeats_timeout()
|
||||
|
||||
@staticmethod
|
||||
def num_heartbeats_warning():
|
||||
return RayConfig.instance().num_heartbeats_warning()
|
||||
|
||||
@staticmethod
|
||||
def initial_reconstruction_timeout_milliseconds():
|
||||
return RayConfig.instance().initial_reconstruction_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def get_timeout_milliseconds():
|
||||
return RayConfig.instance().get_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def max_lineage_size():
|
||||
return RayConfig.instance().max_lineage_size()
|
||||
|
||||
@staticmethod
|
||||
def worker_get_request_size():
|
||||
return RayConfig.instance().worker_get_request_size()
|
||||
|
||||
@staticmethod
|
||||
def worker_fetch_request_size():
|
||||
return RayConfig.instance().worker_fetch_request_size()
|
||||
|
||||
@staticmethod
|
||||
def actor_max_dummy_objects():
|
||||
return RayConfig.instance().actor_max_dummy_objects()
|
||||
|
||||
@staticmethod
|
||||
def num_connect_attempts():
|
||||
return RayConfig.instance().num_connect_attempts()
|
||||
|
||||
@staticmethod
|
||||
def connect_timeout_milliseconds():
|
||||
return RayConfig.instance().connect_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def local_scheduler_fetch_timeout_milliseconds():
|
||||
return RayConfig.instance().local_scheduler_fetch_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def local_scheduler_reconstruction_timeout_milliseconds():
|
||||
return RayConfig.instance().local_scheduler_reconstruction_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def max_num_to_reconstruct():
|
||||
return RayConfig.instance().max_num_to_reconstruct()
|
||||
|
||||
@staticmethod
|
||||
def local_scheduler_fetch_request_size():
|
||||
return RayConfig.instance().local_scheduler_fetch_request_size()
|
||||
|
||||
@staticmethod
|
||||
def kill_worker_timeout_milliseconds():
|
||||
return RayConfig.instance().kill_worker_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def max_time_for_handler_milliseconds():
|
||||
return RayConfig.instance().max_time_for_handler_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def size_limit():
|
||||
return RayConfig.instance().size_limit()
|
||||
|
||||
@staticmethod
|
||||
def num_elements_limit():
|
||||
return RayConfig.instance().num_elements_limit()
|
||||
|
||||
@staticmethod
|
||||
def max_time_for_loop():
|
||||
return RayConfig.instance().max_time_for_loop()
|
||||
|
||||
@staticmethod
|
||||
def redis_db_connect_retries():
|
||||
return RayConfig.instance().redis_db_connect_retries()
|
||||
|
||||
@staticmethod
|
||||
def redis_db_connect_wait_milliseconds():
|
||||
return RayConfig.instance().redis_db_connect_wait_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def plasma_default_release_delay():
|
||||
return RayConfig.instance().plasma_default_release_delay()
|
||||
|
||||
@staticmethod
|
||||
def L3_cache_size_bytes():
|
||||
return RayConfig.instance().L3_cache_size_bytes()
|
||||
|
||||
@staticmethod
|
||||
def max_tasks_to_spillback():
|
||||
return RayConfig.instance().max_tasks_to_spillback()
|
||||
|
||||
@staticmethod
|
||||
def actor_creation_num_spillbacks_warning():
|
||||
return RayConfig.instance().actor_creation_num_spillbacks_warning()
|
||||
|
||||
@staticmethod
|
||||
def node_manager_forward_task_retry_timeout_milliseconds():
|
||||
return RayConfig.instance().node_manager_forward_task_retry_timeout_milliseconds()
|
||||
|
||||
@staticmethod
|
||||
def object_manager_pull_timeout_ms():
|
||||
return RayConfig.instance().object_manager_pull_timeout_ms()
|
||||
|
||||
@staticmethod
|
||||
def object_manager_push_timeout_ms():
|
||||
return RayConfig.instance().object_manager_push_timeout_ms()
|
||||
|
||||
@staticmethod
|
||||
def object_manager_repeated_push_delay_ms():
|
||||
return RayConfig.instance().object_manager_repeated_push_delay_ms()
|
||||
|
||||
@staticmethod
|
||||
def object_manager_default_chunk_size():
|
||||
return RayConfig.instance().object_manager_default_chunk_size()
|
||||
|
||||
@staticmethod
|
||||
def num_workers_per_process():
|
||||
return RayConfig.instance().num_workers_per_process()
|
||||
|
||||
@staticmethod
|
||||
def max_task_lease_timeout_ms():
|
||||
return RayConfig.instance().max_task_lease_timeout_ms()
|
||||
@@ -0,0 +1,102 @@
|
||||
from libc.stdint cimport int64_t, uint8_t
|
||||
from libcpp cimport bool as c_bool
|
||||
from libcpp.memory cimport unique_ptr, shared_ptr
|
||||
from libcpp.string cimport string as c_string
|
||||
from libcpp.unordered_map cimport unordered_map
|
||||
from libcpp.vector cimport vector as c_vector
|
||||
|
||||
from ray.includes.common cimport (
|
||||
CUniqueID, CTaskID, CObjectID, CFunctionID, CActorClassID, CActorID,
|
||||
CActorHandleID, CWorkerID, CDriverID, CConfigID, CClientID,
|
||||
CLanguage, ResourceSet)
|
||||
|
||||
|
||||
cdef extern from "ray/raylet/task_execution_spec.h" namespace "ray::raylet" nogil:
|
||||
cdef cppclass CTaskExecutionSpecification "ray::raylet::TaskExecutionSpecification":
|
||||
CTaskExecutionSpecification(const c_vector[CObjectID] &&dependencies)
|
||||
CTaskExecutionSpecification(const c_vector[CObjectID] &&dependencies, int num_forwards)
|
||||
c_vector[CObjectID] ExecutionDependencies() const
|
||||
void SetExecutionDependencies(const c_vector[CObjectID] &dependencies)
|
||||
int NumForwards() const
|
||||
void IncrementNumForwards()
|
||||
int64_t LastTimestamp() const
|
||||
void SetLastTimestamp(int64_t new_timestamp)
|
||||
|
||||
|
||||
cdef extern from "ray/raylet/task_spec.h" namespace "ray::raylet" nogil:
|
||||
cdef cppclass CTaskArgument "ray::raylet::TaskArgument":
|
||||
pass
|
||||
|
||||
cdef cppclass CTaskArgumentByReference "ray::raylet::TaskArgumentByReference":
|
||||
CTaskArgumentByReference(const c_vector[CObjectID] &references);
|
||||
|
||||
cdef cppclass CTaskArgumentByValue "ray::raylet::TaskArgumentByValue":
|
||||
CTaskArgumentByValue(const uint8_t *value, size_t length);
|
||||
|
||||
cdef cppclass CTaskSpecification "ray::raylet::TaskSpecification":
|
||||
CTaskSpecification(const CDriverID &driver_id, const CTaskID &parent_task_id,
|
||||
int64_t parent_counter,
|
||||
const c_vector[shared_ptr[CTaskArgument]] &task_arguments,
|
||||
int64_t num_returns,
|
||||
const unordered_map[c_string, double] &required_resources,
|
||||
const CLanguage &language,
|
||||
const c_vector[c_string] &function_descriptor)
|
||||
CTaskSpecification(
|
||||
const CDriverID &driver_id, const CTaskID &parent_task_id, int64_t parent_counter,
|
||||
const CActorID &actor_creation_id, const CObjectID &actor_creation_dummy_object_id,
|
||||
int64_t max_actor_reconstructions, const CActorID &actor_id,
|
||||
const CActorHandleID &actor_handle_id, int64_t actor_counter,
|
||||
const c_vector[CActorHandleID] &new_actor_handles,
|
||||
const c_vector[shared_ptr[CTaskArgument]] &task_arguments,
|
||||
int64_t num_returns,
|
||||
const unordered_map[c_string, double] &required_resources,
|
||||
const unordered_map[c_string, double] &required_placement_resources,
|
||||
const CLanguage &language, const c_vector[c_string] &function_descriptor)
|
||||
CTaskSpecification(const c_string &string)
|
||||
c_string SerializeAsString() const
|
||||
|
||||
CTaskID TaskId() const
|
||||
CDriverID DriverId() const
|
||||
CTaskID ParentTaskId() const
|
||||
int64_t ParentCounter() const
|
||||
c_vector[c_string] FunctionDescriptor() const
|
||||
c_string FunctionDescriptorString() const
|
||||
int64_t NumArgs() const
|
||||
int64_t NumReturns() const
|
||||
c_bool ArgByRef(int64_t arg_index) const
|
||||
int ArgIdCount(int64_t arg_index) const
|
||||
CObjectID ArgId(int64_t arg_index, int64_t id_index) const
|
||||
CObjectID ReturnId(int64_t return_index) const
|
||||
const uint8_t *ArgVal(int64_t arg_index) const
|
||||
size_t ArgValLength(int64_t arg_index) const
|
||||
double GetRequiredResource(const c_string &resource_name) const
|
||||
const ResourceSet GetRequiredResources() const
|
||||
const ResourceSet GetRequiredPlacementResources() const
|
||||
c_bool IsDriverTask() const
|
||||
CLanguage GetLanguage() const
|
||||
|
||||
c_bool IsActorCreationTask() const
|
||||
c_bool IsActorTask() const
|
||||
CActorID ActorCreationId() const
|
||||
CObjectID ActorCreationDummyObjectId() const
|
||||
int64_t MaxActorReconstructions() const
|
||||
CActorID ActorId() const
|
||||
CActorHandleID ActorHandleId() const
|
||||
int64_t ActorCounter() const
|
||||
CObjectID ActorDummyObject() const
|
||||
c_vector[CActorHandleID] NewActorHandles() const
|
||||
|
||||
|
||||
cdef extern from "ray/raylet/task.h" namespace "ray::raylet" nogil:
|
||||
cdef cppclass CTask "ray::raylet::Task":
|
||||
CTask(const CTaskExecutionSpecification &execution_spec,
|
||||
const CTaskSpecification &task_spec)
|
||||
const CTaskExecutionSpecification &GetTaskExecutionSpec() const
|
||||
const CTaskSpecification &GetTaskSpecification() const
|
||||
void SetExecutionDependencies(const c_vector[CObjectID] &dependencies)
|
||||
void IncrementNumForwards()
|
||||
const c_vector[CObjectID] &GetDependencies() const
|
||||
void CopyTaskExecutionSpec(const CTask &task)
|
||||
|
||||
cdef c_string SerializeTaskAsString(const c_vector[CObjectID] *dependencies,
|
||||
const CTaskSpecification *task_spec)
|
||||
@@ -0,0 +1,185 @@
|
||||
from libc.stdint cimport uint8_t
|
||||
from libcpp.memory cimport shared_ptr, make_shared, static_pointer_cast
|
||||
from ray.includes.task cimport CTaskSpecification, CTaskArgument, CTaskArgumentByValue, CTaskArgumentByReference, SerializeTaskAsString
|
||||
|
||||
from ray.utils import _random_string
|
||||
|
||||
cdef class Task:
|
||||
cdef:
|
||||
unique_ptr[CTaskSpecification] task_spec
|
||||
unique_ptr[c_vector[CObjectID]] execution_dependencies
|
||||
|
||||
def __init__(self, DriverID driver_id, function_descriptor, arguments,
|
||||
int num_returns, TaskID parent_task_id, int parent_counter,
|
||||
ActorID actor_creation_id,
|
||||
ObjectID actor_creation_dummy_object_id,
|
||||
int32_t max_actor_reconstructions, ActorID actor_id,
|
||||
ActorHandleID actor_handle_id, int actor_counter,
|
||||
new_actor_handles, execution_arguments, resource_map,
|
||||
placement_resource_map):
|
||||
cdef:
|
||||
unordered_map[c_string, double] required_resources
|
||||
unordered_map[c_string, double] required_placement_resources
|
||||
c_vector[shared_ptr[CTaskArgument]] task_args
|
||||
c_vector[CActorHandleID] task_new_actor_handles
|
||||
c_vector[c_string] c_function_descriptor
|
||||
c_string pickled_str
|
||||
c_vector[CObjectID] references
|
||||
|
||||
for item in function_descriptor:
|
||||
if not isinstance(item, bytes):
|
||||
raise TypeError("'function_descriptor' takes a list of byte strings.")
|
||||
c_function_descriptor.push_back(item)
|
||||
|
||||
# Parse the resource map.
|
||||
if resource_map is not None:
|
||||
required_resources = resource_map_from_python_dict(resource_map)
|
||||
if required_resources.count(b"CPU") == 0:
|
||||
required_resources[b"CPU"] = 1.0
|
||||
if placement_resource_map is not None:
|
||||
required_placement_resources = resource_map_from_python_dict(placement_resource_map)
|
||||
|
||||
# Parse the arguments from the list.
|
||||
for arg in arguments:
|
||||
if isinstance(arg, ObjectID):
|
||||
references = c_vector[CObjectID]()
|
||||
references.push_back((<ObjectID>arg).data)
|
||||
task_args.push_back(static_pointer_cast[CTaskArgument, CTaskArgumentByReference](make_shared[CTaskArgumentByReference](references)))
|
||||
else:
|
||||
pickled_str = pickle.dumps(arg, protocol=pickle.HIGHEST_PROTOCOL)
|
||||
task_args.push_back(static_pointer_cast[CTaskArgument, CTaskArgumentByValue](make_shared[CTaskArgumentByValue](<uint8_t *>pickled_str.c_str(), pickled_str.size())))
|
||||
|
||||
for new_actor_handle in new_actor_handles:
|
||||
task_new_actor_handles.push_back((<ActorHandleID?>new_actor_handle).data)
|
||||
|
||||
self.task_spec.reset(new CTaskSpecification(
|
||||
CUniqueID(driver_id.data), parent_task_id.data, parent_counter, actor_creation_id.data,
|
||||
actor_creation_dummy_object_id.data, max_actor_reconstructions, CUniqueID(actor_id.data),
|
||||
CUniqueID(actor_handle_id.data), actor_counter, task_new_actor_handles, task_args, num_returns,
|
||||
required_resources, required_placement_resources, LANGUAGE_PYTHON,
|
||||
c_function_descriptor))
|
||||
|
||||
# Set the task's execution dependencies.
|
||||
self.execution_dependencies.reset(new c_vector[CObjectID]())
|
||||
if execution_arguments is not None:
|
||||
for execution_arg in execution_arguments:
|
||||
self.execution_dependencies.get().push_back((<ObjectID?>execution_arg).data)
|
||||
|
||||
@staticmethod
|
||||
cdef make(unique_ptr[CTaskSpecification]& task_spec):
|
||||
cdef Task self = Task.__new__(Task)
|
||||
self.task_spec.reset(task_spec.release())
|
||||
# The created task does not include any execution dependencies.
|
||||
self.execution_dependencies.reset(new c_vector[CObjectID]())
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def from_string(const c_string& task_spec_str):
|
||||
"""Convert a string to a Ray task specification Python object.
|
||||
|
||||
Args:
|
||||
task_spec_str: String representation of the task specification.
|
||||
|
||||
Returns:
|
||||
Python task specification object.
|
||||
"""
|
||||
cdef Task self = Task.__new__(Task)
|
||||
# TODO(pcm): Use flatbuffers validation here.
|
||||
self.task_spec.reset(new CTaskSpecification(task_spec_str))
|
||||
# The created task does not include any execution dependencies.
|
||||
self.execution_dependencies.reset(new c_vector[CObjectID]())
|
||||
return self
|
||||
|
||||
def to_string(self):
|
||||
"""Convert a Ray task specification Python object to a string.
|
||||
|
||||
Returns:
|
||||
String representing the task specification.
|
||||
"""
|
||||
return self.task_spec.get().SerializeAsString()
|
||||
|
||||
def _serialized_raylet_task(self):
|
||||
return SerializeTaskAsString(self.execution_dependencies.get(), self.task_spec.get())
|
||||
|
||||
def driver_id(self):
|
||||
"""Return the driver ID for this task."""
|
||||
return DriverID.from_native(self.task_spec.get().DriverId())
|
||||
|
||||
def task_id(self):
|
||||
"""Return the task ID for this task."""
|
||||
return TaskID.from_native(self.task_spec.get().TaskId())
|
||||
|
||||
def parent_task_id(self):
|
||||
"""Return the task ID of the parent task."""
|
||||
return TaskID.from_native(self.task_spec.get().ParentTaskId())
|
||||
|
||||
def parent_counter(self):
|
||||
"""Return the parent counter of this task."""
|
||||
return self.task_spec.get().ParentCounter()
|
||||
|
||||
def function_descriptor_list(self):
|
||||
"""Return the function descriptor for this task."""
|
||||
cdef c_vector[c_string] function_descriptor = self.task_spec.get().FunctionDescriptor()
|
||||
results = []
|
||||
for i in range(function_descriptor.size()):
|
||||
results.append(function_descriptor[i])
|
||||
return results
|
||||
|
||||
def arguments(self):
|
||||
"""Return the arguments for the task."""
|
||||
cdef:
|
||||
CTaskSpecification *task_spec = self.task_spec.get()
|
||||
int64_t num_args = task_spec.NumArgs()
|
||||
int count
|
||||
arg_list = []
|
||||
for i in range(num_args):
|
||||
count = task_spec.ArgIdCount(i)
|
||||
if count > 0:
|
||||
assert count == 1
|
||||
arg_list.append(ObjectID.from_native(task_spec.ArgId(i, 0)))
|
||||
else:
|
||||
serialized_str = task_spec.ArgVal(i)[:task_spec.ArgValLength(i)]
|
||||
obj = pickle.loads(serialized_str)
|
||||
arg_list.append(obj)
|
||||
return arg_list
|
||||
|
||||
def returns(self):
|
||||
"""Return the object IDs for the return values of the task."""
|
||||
cdef CTaskSpecification *task_spec = self.task_spec.get()
|
||||
return_id_list = []
|
||||
for i in range(task_spec.NumReturns()):
|
||||
return_id_list.append(ObjectID.from_native(task_spec.ReturnId(i)))
|
||||
return return_id_list
|
||||
|
||||
def required_resources(self):
|
||||
"""Return the resource dictionary of the task."""
|
||||
cdef:
|
||||
unordered_map[c_string, double] resource_map = self.task_spec.get().GetRequiredResources().GetResourceMap()
|
||||
c_string resource_name
|
||||
double resource_value
|
||||
unordered_map[c_string, double].iterator iterator = resource_map.begin()
|
||||
|
||||
required_resources = {}
|
||||
while iterator != resource_map.end():
|
||||
resource_name = dereference(iterator).first
|
||||
py_resource_name = str(resource_name) # bytes for Py2, unicode for Py3
|
||||
resource_value = dereference(iterator).second
|
||||
required_resources[py_resource_name] = resource_value
|
||||
postincrement(iterator)
|
||||
return required_resources
|
||||
|
||||
def actor_creation_id(self):
|
||||
"""Return the actor creation ID for the task."""
|
||||
return ActorID.from_native(self.task_spec.get().ActorCreationId())
|
||||
|
||||
def actor_creation_dummy_object_id(self):
|
||||
"""Return the actor creation dummy object ID for the task."""
|
||||
return ObjectID.from_native(self.task_spec.get().ActorCreationDummyObjectId())
|
||||
|
||||
def actor_id(self):
|
||||
"""Return the actor ID for this task."""
|
||||
return ActorID.from_native(self.task_spec.get().ActorId())
|
||||
|
||||
def actor_counter(self):
|
||||
"""Return the actor counter for this task."""
|
||||
return self.task_spec.get().ActorCounter()
|
||||
@@ -0,0 +1,34 @@
|
||||
from libcpp cimport bool as c_bool
|
||||
from libcpp.string cimport string as c_string
|
||||
from libc.stdint cimport uint8_t
|
||||
|
||||
cdef extern from "ray/id.h" namespace "ray" nogil:
|
||||
cdef cppclass CUniqueID "ray::UniqueID":
|
||||
CUniqueID()
|
||||
CUniqueID(const CUniqueID &from_id)
|
||||
@staticmethod
|
||||
CUniqueID from_random()
|
||||
@staticmethod
|
||||
CUniqueID from_binary(const c_string & binary)
|
||||
@staticmethod
|
||||
const CUniqueID nil()
|
||||
size_t hash() const
|
||||
c_bool is_nil() const
|
||||
c_bool operator==(const CUniqueID& rhs) const
|
||||
c_bool operator!=(const CUniqueID& rhs) const
|
||||
const uint8_t *data() const
|
||||
uint8_t *mutable_data();
|
||||
size_t size() const;
|
||||
c_string binary() const;
|
||||
c_string hex() const;
|
||||
|
||||
ctypedef CUniqueID TaskID
|
||||
ctypedef CUniqueID ObjectID
|
||||
ctypedef CUniqueID FunctionID
|
||||
ctypedef CUniqueID ActorID
|
||||
ctypedef CUniqueID ActorClassID
|
||||
ctypedef CUniqueID ActorHandleID
|
||||
ctypedef CUniqueID WorkerID
|
||||
ctypedef CUniqueID DriverID
|
||||
ctypedef CUniqueID ConfigID
|
||||
ctypedef CUniqueID ClientID
|
||||
@@ -0,0 +1,280 @@
|
||||
"""This is a module for unique IDs in Ray.
|
||||
We define different types for different IDs for type safety.
|
||||
|
||||
See https://github.com/ray-project/ray/issues/3721.
|
||||
"""
|
||||
|
||||
from ray.includes.common cimport (
|
||||
CUniqueID, CTaskID, CObjectID, CFunctionID, CActorClassID, CActorID,
|
||||
CActorHandleID, CWorkerID, CDriverID, CConfigID, CClientID,
|
||||
ComputePutId, ComputeTaskId)
|
||||
|
||||
from ray.utils import decode
|
||||
|
||||
|
||||
def check_id(b):
|
||||
if not isinstance(b, bytes):
|
||||
raise TypeError("Unsupported type: " + str(type(b)))
|
||||
if len(b) != kUniqueIDSize:
|
||||
raise ValueError("ID string needs to have length " + str(kUniqueIDSize))
|
||||
|
||||
|
||||
cdef extern from "ray/constants.h" nogil:
|
||||
cdef int64_t kUniqueIDSize
|
||||
cdef int64_t kMaxTaskPuts
|
||||
|
||||
|
||||
cdef class UniqueID:
|
||||
cdef CUniqueID data
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CUniqueID& cpp_id):
|
||||
cdef UniqueID self = UniqueID.__new__(UniqueID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_binary(cls, id_bytes):
|
||||
if not isinstance(id_bytes, bytes):
|
||||
raise TypeError("Expect bytes, got " + str(type(id_bytes)))
|
||||
return cls(id_bytes)
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return UniqueID.from_native(CUniqueID.nil())
|
||||
|
||||
def __hash__(self):
|
||||
return self.data.hash()
|
||||
|
||||
def is_nil(self):
|
||||
return self.data.is_nil()
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.binary() == other.binary()
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.binary() != other.binary()
|
||||
|
||||
def size(self):
|
||||
return self.data.size()
|
||||
|
||||
def __len__(self):
|
||||
return self.size()
|
||||
|
||||
def binary(self):
|
||||
return self.data.binary()
|
||||
|
||||
def __bytes__(self):
|
||||
return self.binary()
|
||||
|
||||
def hex(self):
|
||||
return decode(self.data.hex())
|
||||
|
||||
def __hex__(self):
|
||||
return self.hex()
|
||||
|
||||
def __repr__(self):
|
||||
return "UniqueID(" + self.hex() + ")"
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
def __reduce__(self):
|
||||
return type(self), (self.binary(),)
|
||||
|
||||
def redis_shard_hash(self):
|
||||
# NOTE: The hash function used here must match the one in GetRedisContext in
|
||||
# src/ray/gcs/tables.h. Changes to the hash function should only be made
|
||||
# through std::hash in src/common/common.h
|
||||
return self.data.hash()
|
||||
|
||||
|
||||
cdef class ObjectID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CObjectID& cpp_id):
|
||||
cdef ObjectID self = ObjectID.__new__(ObjectID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return ObjectID.from_native(CObjectID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "ObjectID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class TaskID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CTaskID& cpp_id):
|
||||
cdef TaskID self = TaskID.__new__(TaskID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return TaskID.from_native(CTaskID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "TaskID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class ClientID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CClientID& cpp_id):
|
||||
cdef ClientID self = ClientID.__new__(ClientID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return ClientID.from_native(CClientID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "ClientID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class DriverID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CDriverID& cpp_id):
|
||||
cdef DriverID self = DriverID.__new__(DriverID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return DriverID.from_native(CDriverID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "DriverID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class ActorID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CActorID& cpp_id):
|
||||
cdef ActorID self = ActorID.__new__(ActorID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return ActorID.from_native(CActorID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "ActorID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class ActorHandleID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CActorHandleID& cpp_id):
|
||||
cdef ActorHandleID self = ActorHandleID.__new__(ActorHandleID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return ActorHandleID.from_native(CActorHandleID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "ActorHandleID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class FunctionID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CFunctionID& cpp_id):
|
||||
cdef FunctionID self = FunctionID.__new__(FunctionID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return FunctionID.from_native(CFunctionID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "FunctionID(" + self.hex() + ")"
|
||||
|
||||
|
||||
cdef class ActorClassID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
if not id:
|
||||
self.data = CUniqueID()
|
||||
else:
|
||||
check_id(id)
|
||||
self.data = CUniqueID.from_binary(id)
|
||||
|
||||
@staticmethod
|
||||
cdef from_native(const CActorClassID& cpp_id):
|
||||
cdef ActorClassID self = ActorClassID.__new__(ActorClassID)
|
||||
self.data = cpp_id
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def nil():
|
||||
return ActorClassID.from_native(CActorClassID.nil())
|
||||
|
||||
def __repr__(self):
|
||||
return "ActorClassID(" + self.hex() + ")"
|
||||
@@ -2,7 +2,6 @@ from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import ray.raylet
|
||||
import ray.worker
|
||||
from ray import profiling
|
||||
|
||||
|
||||
@@ -160,9 +160,9 @@ class Monitor(object):
|
||||
object_table_objects = self.state.object_table()
|
||||
driver_object_id_bins = set()
|
||||
for object_id, _ in object_table_objects.items():
|
||||
task_id_bin = ray.raylet.compute_task_id(object_id).id()
|
||||
task_id_bin = ray._raylet.compute_task_id(object_id).binary()
|
||||
if task_id_bin in driver_task_id_bins:
|
||||
driver_object_id_bins.add(object_id.id())
|
||||
driver_object_id_bins.add(object_id.binary())
|
||||
|
||||
def to_shard_index(id_bin):
|
||||
return binary_to_object_id(id_bin).redis_shard_hash() % len(
|
||||
|
||||
@@ -97,6 +97,10 @@ class Profiler(object):
|
||||
time.sleep(1)
|
||||
self.flush_profile_data()
|
||||
except AttributeError:
|
||||
# TODO(suquark): It is a bad idea to ignore "AttributeError".
|
||||
# It has caused some very unexpected behaviors when implementing
|
||||
# new features (related to AttributeError).
|
||||
|
||||
# This is to suppress errors that occur at shutdown.
|
||||
pass
|
||||
|
||||
@@ -120,7 +124,7 @@ class Profiler(object):
|
||||
component_type = "driver"
|
||||
|
||||
self.worker.raylet_client.push_profile_events(
|
||||
component_type, ray.ObjectID(self.worker.worker_id),
|
||||
component_type, ray.UniqueID(self.worker.worker_id),
|
||||
self.worker.node_ip_address, events)
|
||||
|
||||
def add_event(self, event):
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from ray.core.src.ray.raylet.libraylet_library_python import (
|
||||
Task, RayletClient, ObjectID, check_simple_value, compute_task_id,
|
||||
task_from_string, task_to_string, _config, RayCommonError)
|
||||
|
||||
__all__ = [
|
||||
"Task", "RayletClient", "ObjectID", "check_simple_value",
|
||||
"compute_task_id", "task_from_string", "task_to_string",
|
||||
"start_local_scheduler", "_config", "RayCommonError"
|
||||
]
|
||||
@@ -39,14 +39,14 @@ class TaskPool(object):
|
||||
Assumes obj_id only is one id."""
|
||||
|
||||
for worker, obj_id in self.completed():
|
||||
plasma_id = ray.pyarrow.plasma.ObjectID(obj_id.id())
|
||||
plasma_id = ray.pyarrow.plasma.ObjectID(obj_id.binary())
|
||||
(ray.worker.global_worker.raylet_client.fetch_or_reconstruct(
|
||||
[obj_id], True))
|
||||
self._fetching.append((worker, obj_id))
|
||||
|
||||
remaining = []
|
||||
for worker, obj_id in self._fetching:
|
||||
plasma_id = ray.pyarrow.plasma.ObjectID(obj_id.id())
|
||||
plasma_id = ray.pyarrow.plasma.ObjectID(obj_id.binary())
|
||||
if ray.worker.global_worker.plasma_client.contains(plasma_id):
|
||||
yield (worker, obj_id)
|
||||
else:
|
||||
|
||||
@@ -23,13 +23,13 @@ def pin_in_object_store(obj):
|
||||
obj_id = ray.put(_to_pinnable(obj))
|
||||
_pinned_objects.append(ray.get(obj_id))
|
||||
return "{}{}".format(PINNED_OBJECT_PREFIX,
|
||||
base64.b64encode(obj_id.id()).decode("utf-8"))
|
||||
base64.b64encode(obj_id.binary()).decode("utf-8"))
|
||||
|
||||
|
||||
def get_pinned_object(pinned_id):
|
||||
"""Retrieve a pinned object from the object store."""
|
||||
|
||||
from ray.raylet import ObjectID
|
||||
from ray import ObjectID
|
||||
|
||||
return _from_pinnable(
|
||||
ray.get(
|
||||
|
||||
+3
-4
@@ -15,7 +15,6 @@ import time
|
||||
import uuid
|
||||
|
||||
import ray.gcs_utils
|
||||
import ray.raylet
|
||||
import ray.ray_constants as ray_constants
|
||||
|
||||
|
||||
@@ -67,7 +66,7 @@ def push_error_to_driver(worker,
|
||||
will be serialized with json and stored in Redis.
|
||||
"""
|
||||
if driver_id is None:
|
||||
driver_id = ray.ObjectID.nil_id()
|
||||
driver_id = ray.DriverID.nil()
|
||||
data = {} if data is None else data
|
||||
worker.raylet_client.push_error(driver_id, error_type, message,
|
||||
time.time())
|
||||
@@ -96,7 +95,7 @@ def push_error_to_driver_through_redis(redis_client,
|
||||
will be serialized with json and stored in Redis.
|
||||
"""
|
||||
if driver_id is None:
|
||||
driver_id = ray.ObjectID.nil_id()
|
||||
driver_id = ray.DriverID.nil()
|
||||
data = {} if data is None else data
|
||||
# Do everything in Python and through the Python Redis client instead
|
||||
# of through the raylet.
|
||||
@@ -105,7 +104,7 @@ def push_error_to_driver_through_redis(redis_client,
|
||||
redis_client.execute_command("RAY.TABLE_APPEND",
|
||||
ray.gcs_utils.TablePrefix.ERROR_INFO,
|
||||
ray.gcs_utils.TablePubsub.ERROR_INFO,
|
||||
driver_id.id(), error_data)
|
||||
driver_id.binary(), error_data)
|
||||
|
||||
|
||||
def is_cython(obj):
|
||||
|
||||
+42
-41
@@ -32,10 +32,9 @@ import ray.serialization as serialization
|
||||
import ray.services as services
|
||||
import ray.signature
|
||||
import ray.tempfile_services as tempfile_services
|
||||
import ray.raylet
|
||||
import ray.ray_constants as ray_constants
|
||||
from ray import import_thread
|
||||
from ray import ObjectID
|
||||
from ray import ObjectID, DriverID, ActorID, ActorHandleID, ClientID, TaskID
|
||||
from ray import profiling
|
||||
from ray.function_manager import (FunctionActorManager, FunctionDescriptor)
|
||||
import ray.parameter
|
||||
@@ -161,7 +160,8 @@ class Worker(object):
|
||||
self.serialization_context_map = {}
|
||||
self.function_actor_manager = FunctionActorManager(self)
|
||||
# Identity of the driver that this worker is processing.
|
||||
self.task_driver_id = ObjectID.nil_id()
|
||||
# It is a DriverID.
|
||||
self.task_driver_id = DriverID.nil()
|
||||
self._task_context = threading.local()
|
||||
|
||||
@property
|
||||
@@ -182,13 +182,13 @@ class Worker(object):
|
||||
# If this is running on the main thread, initialize it to
|
||||
# NIL. The actual value will set when the worker receives
|
||||
# a task from raylet backend.
|
||||
self._task_context.current_task_id = ObjectID.nil_id()
|
||||
self._task_context.current_task_id = TaskID.nil()
|
||||
else:
|
||||
# If this is running on a separate thread, then the mapping
|
||||
# to the current task ID may not be correct. Generate a
|
||||
# random task ID so that the backend can differentiate
|
||||
# between different threads.
|
||||
self._task_context.current_task_id = ObjectID(random_string())
|
||||
self._task_context.current_task_id = TaskID(random_string())
|
||||
if getattr(self, '_multithreading_warned', False) is not True:
|
||||
logger.warning(
|
||||
"Calling ray.get or ray.wait in a separate thread "
|
||||
@@ -286,7 +286,7 @@ class Worker(object):
|
||||
try:
|
||||
self.plasma_client.put(
|
||||
value,
|
||||
object_id=pyarrow.plasma.ObjectID(object_id.id()),
|
||||
object_id=pyarrow.plasma.ObjectID(object_id.binary()),
|
||||
memcopy_threads=self.memcopy_threads,
|
||||
serialization_context=self.get_serialization_context(
|
||||
self.task_driver_id))
|
||||
@@ -450,7 +450,7 @@ class Worker(object):
|
||||
# smaller fetches so as to not block the manager for a prolonged period
|
||||
# of time in a single call.
|
||||
plain_object_ids = [
|
||||
plasma.ObjectID(object_id.id()) for object_id in object_ids
|
||||
plasma.ObjectID(object_id.binary()) for object_id in object_ids
|
||||
]
|
||||
for i in range(0, len(object_ids),
|
||||
ray._config.worker_fetch_request_size()):
|
||||
@@ -567,16 +567,16 @@ class Worker(object):
|
||||
with profiling.profile("submit_task", worker=self):
|
||||
if actor_id is None:
|
||||
assert actor_handle_id is None
|
||||
actor_id = ObjectID.nil_id()
|
||||
actor_handle_id = ObjectID.nil_id()
|
||||
actor_id = ActorID.nil()
|
||||
actor_handle_id = ActorHandleID.nil()
|
||||
else:
|
||||
assert actor_handle_id is not None
|
||||
|
||||
if actor_creation_id is None:
|
||||
actor_creation_id = ObjectID.nil_id()
|
||||
actor_creation_id = ActorID.nil()
|
||||
|
||||
if actor_creation_dummy_object_id is None:
|
||||
actor_creation_dummy_object_id = ObjectID.nil_id()
|
||||
actor_creation_dummy_object_id = ObjectID.nil()
|
||||
|
||||
# Put large or complex arguments that are passed by value in the
|
||||
# object store first.
|
||||
@@ -584,7 +584,7 @@ class Worker(object):
|
||||
for arg in args:
|
||||
if isinstance(arg, ObjectID):
|
||||
args_for_local_scheduler.append(arg)
|
||||
elif ray.raylet.check_simple_value(arg):
|
||||
elif ray._raylet.check_simple_value(arg):
|
||||
args_for_local_scheduler.append(arg)
|
||||
else:
|
||||
args_for_local_scheduler.append(put(arg))
|
||||
@@ -625,7 +625,8 @@ class Worker(object):
|
||||
# Submit the task to local scheduler.
|
||||
function_descriptor_list = (
|
||||
function_descriptor.get_function_descriptor_list())
|
||||
task = ray.raylet.Task(
|
||||
assert isinstance(driver_id, DriverID)
|
||||
task = ray._raylet.Task(
|
||||
driver_id,
|
||||
function_descriptor_list,
|
||||
args_for_local_scheduler,
|
||||
@@ -693,7 +694,7 @@ class Worker(object):
|
||||
# Run the function on all workers.
|
||||
self.redis_client.hmset(
|
||||
key, {
|
||||
"driver_id": self.task_driver_id.id(),
|
||||
"driver_id": self.task_driver_id.binary(),
|
||||
"function_id": function_to_run_id,
|
||||
"function": pickled_function,
|
||||
"run_on_other_drivers": str(run_on_other_drivers)
|
||||
@@ -880,7 +881,7 @@ class Worker(object):
|
||||
str(failure_object),
|
||||
driver_id=self.task_driver_id,
|
||||
data={
|
||||
"function_id": function_id.id(),
|
||||
"function_id": function_id.binary(),
|
||||
"function_name": function_name,
|
||||
"module_name": function_descriptor.module_name,
|
||||
"class_name": function_descriptor.class_name
|
||||
@@ -939,14 +940,14 @@ class Worker(object):
|
||||
with _changeproctitle(title, next_title):
|
||||
self._process_task(task, execution_info)
|
||||
# Reset the state fields so the next task can run.
|
||||
self.task_context.current_task_id = ObjectID.nil_id()
|
||||
self.task_context.current_task_id = TaskID.nil()
|
||||
self.task_context.task_index = 0
|
||||
self.task_context.put_index = 1
|
||||
if self.actor_id.is_nil():
|
||||
# Don't need to reset task_driver_id if the worker is an
|
||||
# actor. Because the following tasks should all have the
|
||||
# same driver id.
|
||||
self.task_driver_id = ObjectID.nil_id()
|
||||
self.task_driver_id = DriverID.nil()
|
||||
|
||||
# Increase the task execution counter.
|
||||
self.function_actor_manager.increase_task_counter(
|
||||
@@ -1100,17 +1101,16 @@ def error_applies_to_driver(error_key, worker=global_worker):
|
||||
+ ray_constants.ID_SIZE), error_key
|
||||
# If the driver ID in the error message is a sequence of all zeros, then
|
||||
# the message is intended for all drivers.
|
||||
driver_id = ObjectID(error_key[len(ERROR_KEY_PREFIX):(
|
||||
driver_id = DriverID(error_key[len(ERROR_KEY_PREFIX):(
|
||||
len(ERROR_KEY_PREFIX) + ray_constants.ID_SIZE)])
|
||||
return (driver_id == worker.task_driver_id
|
||||
or driver_id == ObjectID.nil_id())
|
||||
return (driver_id == worker.task_driver_id or driver_id == DriverID.nil())
|
||||
|
||||
|
||||
def error_info(worker=global_worker):
|
||||
"""Return information about failed tasks."""
|
||||
worker.check_connected()
|
||||
return (global_state.error_messages(job_id=worker.task_driver_id) +
|
||||
global_state.error_messages(job_id=ObjectID.nil_id()))
|
||||
global_state.error_messages(job_id=DriverID.nil()))
|
||||
|
||||
|
||||
def _initialize_serialization(driver_id, worker=global_worker):
|
||||
@@ -1127,7 +1127,7 @@ def _initialize_serialization(driver_id, worker=global_worker):
|
||||
|
||||
# Define a custom serializer and deserializer for handling Object IDs.
|
||||
def object_id_custom_serializer(obj):
|
||||
return obj.id()
|
||||
return obj.binary()
|
||||
|
||||
def object_id_custom_deserializer(serialized_obj):
|
||||
return ObjectID(serialized_obj)
|
||||
@@ -1656,8 +1656,8 @@ def listen_error_messages_raylet(worker, task_error_queue):
|
||||
gcs_entry.Entries(0), 0)
|
||||
job_id = error_data.JobId()
|
||||
if job_id not in [
|
||||
worker.task_driver_id.id(),
|
||||
ObjectID.nil_id().id()
|
||||
worker.task_driver_id.binary(),
|
||||
DriverID.nil().binary()
|
||||
]:
|
||||
continue
|
||||
|
||||
@@ -1768,23 +1768,23 @@ def connect(info,
|
||||
else:
|
||||
# This is the code path of driver mode.
|
||||
if driver_id is None:
|
||||
driver_id = ObjectID(random_string())
|
||||
driver_id = DriverID(random_string())
|
||||
|
||||
if not isinstance(driver_id, ObjectID):
|
||||
raise Exception("The type of given driver id must be ObjectID.")
|
||||
if not isinstance(driver_id, DriverID):
|
||||
raise Exception("The type of given driver id must be DriverID.")
|
||||
|
||||
worker.worker_id = driver_id.id()
|
||||
worker.worker_id = driver_id.binary()
|
||||
|
||||
# When tasks are executed on remote workers in the context of multiple
|
||||
# drivers, the task driver ID is used to keep track of which driver is
|
||||
# responsible for the task so that error messages will be propagated to
|
||||
# the correct driver.
|
||||
if mode != WORKER_MODE:
|
||||
worker.task_driver_id = ObjectID(worker.worker_id)
|
||||
worker.task_driver_id = DriverID(worker.worker_id)
|
||||
|
||||
# All workers start out as non-actors. A worker can be turned into an actor
|
||||
# after it is created.
|
||||
worker.actor_id = ObjectID.nil_id()
|
||||
worker.actor_id = ActorID.nil()
|
||||
worker.connected = True
|
||||
worker.set_mode(mode)
|
||||
|
||||
@@ -1910,18 +1910,18 @@ def connect(info,
|
||||
nil_actor_counter = 0
|
||||
|
||||
function_descriptor = FunctionDescriptor.for_driver_task()
|
||||
driver_task = ray.raylet.Task(
|
||||
driver_task = ray._raylet.Task(
|
||||
worker.task_driver_id,
|
||||
function_descriptor.get_function_descriptor_list(),
|
||||
[], # arguments.
|
||||
0, # num_returns.
|
||||
ObjectID(random_string()), # parent_task_id.
|
||||
TaskID(random_string()), # parent_task_id.
|
||||
0, # parent_counter.
|
||||
ObjectID.nil_id(), # actor_creation_id.
|
||||
ObjectID.nil_id(), # actor_creation_dummy_object_id.
|
||||
ActorID.nil(), # actor_creation_id.
|
||||
ObjectID.nil(), # actor_creation_dummy_object_id.
|
||||
0, # max_actor_reconstructions.
|
||||
ObjectID.nil_id(), # actor_id.
|
||||
ObjectID.nil_id(), # actor_handle_id.
|
||||
ActorID.nil(), # actor_id.
|
||||
ActorHandleID.nil(), # actor_handle_id.
|
||||
nil_actor_counter, # actor_counter.
|
||||
[], # new_actor_handles.
|
||||
[], # execution_dependencies.
|
||||
@@ -1933,18 +1933,18 @@ def connect(info,
|
||||
global_state._execute_command(driver_task.task_id(), "RAY.TABLE_ADD",
|
||||
ray.gcs_utils.TablePrefix.RAYLET_TASK,
|
||||
ray.gcs_utils.TablePubsub.RAYLET_TASK,
|
||||
driver_task.task_id().id(),
|
||||
driver_task.task_id().binary(),
|
||||
driver_task._serialized_raylet_task())
|
||||
|
||||
# Set the driver's current task ID to the task ID assigned to the
|
||||
# driver task.
|
||||
worker.task_context.current_task_id = driver_task.task_id()
|
||||
|
||||
worker.raylet_client = ray.raylet.RayletClient(
|
||||
worker.raylet_client = ray._raylet.RayletClient(
|
||||
raylet_socket,
|
||||
worker.worker_id,
|
||||
ClientID(worker.worker_id),
|
||||
is_worker,
|
||||
worker.current_task_id,
|
||||
DriverID(worker.current_task_id.binary()),
|
||||
)
|
||||
|
||||
# Start the import thread
|
||||
@@ -2144,6 +2144,7 @@ def register_custom_serializer(cls,
|
||||
|
||||
if driver_id is None:
|
||||
driver_id = worker.task_driver_id
|
||||
assert isinstance(driver_id, DriverID)
|
||||
|
||||
def register_class_for_serialization(worker_info):
|
||||
# TODO(rkn): We need to be more thoughtful about what to do if custom
|
||||
@@ -2228,7 +2229,7 @@ def put(value, worker=global_worker):
|
||||
if worker.mode == LOCAL_MODE:
|
||||
# In LOCAL_MODE, ray.put is the identity operation.
|
||||
return value
|
||||
object_id = worker.raylet_client.compute_put_id(
|
||||
object_id = ray._raylet.compute_put_id(
|
||||
worker.current_task_id,
|
||||
worker.task_context.put_index,
|
||||
)
|
||||
|
||||
+1
-2
@@ -22,8 +22,7 @@ import setuptools.command.build_ext as _build_ext
|
||||
ray_files = [
|
||||
"ray/core/src/ray/thirdparty/redis/src/redis-server",
|
||||
"ray/core/src/ray/gcs/redis_module/libray_redis_module.so",
|
||||
"ray/core/src/plasma/plasma_store_server",
|
||||
"ray/core/src/ray/raylet/libraylet_library_python.so",
|
||||
"ray/core/src/plasma/plasma_store_server", "ray/_raylet.so",
|
||||
"ray/core/src/ray/raylet/raylet_monitor", "ray/core/src/ray/raylet/raylet",
|
||||
"ray/WebUI.ipynb"
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user