mirror of
https://github.com/wassname/ray.git
synced 2026-08-09 12:20:09 +08:00
Optimize O(n^2) behavior in dependency resolver (#6509)
* Optimize O(n^2) behavior in dependency resolver * fix check * checks
This commit is contained in:
@@ -3,57 +3,68 @@
|
|||||||
namespace ray {
|
namespace ray {
|
||||||
|
|
||||||
struct TaskState {
|
struct TaskState {
|
||||||
TaskState(TaskSpecification t, absl::flat_hash_set<ObjectID> deps)
|
TaskState(TaskSpecification t,
|
||||||
: task(t), local_dependencies(deps) {}
|
absl::flat_hash_map<ObjectID, std::shared_ptr<RayObject>> deps)
|
||||||
|
: task(t), local_dependencies(deps), dependencies_remaining(deps.size()) {}
|
||||||
/// The task to be run.
|
/// The task to be run.
|
||||||
TaskSpecification task;
|
TaskSpecification task;
|
||||||
/// The remaining dependencies to resolve for this task.
|
/// The local dependencies to resolve for this task. Objects are nullptr if not yet
|
||||||
absl::flat_hash_set<ObjectID> local_dependencies;
|
/// resolved.
|
||||||
|
absl::flat_hash_map<ObjectID, std::shared_ptr<RayObject>> local_dependencies;
|
||||||
|
/// Number of local dependencies that aren't yet resolved (have nullptrs in the above
|
||||||
|
/// map).
|
||||||
|
size_t dependencies_remaining;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DoInlineObjectValue(const ObjectID &obj_id, std::shared_ptr<RayObject> value,
|
void InlineDependencies(
|
||||||
TaskSpecification &task) {
|
absl::flat_hash_map<ObjectID, std::shared_ptr<RayObject>> dependencies,
|
||||||
|
TaskSpecification &task) {
|
||||||
auto &msg = task.GetMutableMessage();
|
auto &msg = task.GetMutableMessage();
|
||||||
bool found = false;
|
size_t found = 0;
|
||||||
for (size_t i = 0; i < task.NumArgs(); i++) {
|
for (size_t i = 0; i < task.NumArgs(); i++) {
|
||||||
auto count = task.ArgIdCount(i);
|
auto count = task.ArgIdCount(i);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
const auto &id = task.ArgId(i, 0);
|
const auto &id = task.ArgId(i, 0);
|
||||||
if (id == obj_id) {
|
const auto &it = dependencies.find(id);
|
||||||
|
if (it != dependencies.end()) {
|
||||||
|
RAY_CHECK(it->second);
|
||||||
auto *mutable_arg = msg.mutable_args(i);
|
auto *mutable_arg = msg.mutable_args(i);
|
||||||
mutable_arg->clear_object_ids();
|
mutable_arg->clear_object_ids();
|
||||||
if (value->IsInPlasmaError()) {
|
if (it->second->IsInPlasmaError()) {
|
||||||
// Promote the object id to plasma.
|
// Promote the object id to plasma.
|
||||||
mutable_arg->add_object_ids(
|
mutable_arg->add_object_ids(
|
||||||
obj_id.WithTransportType(TaskTransportType::RAYLET).Binary());
|
it->first.WithTransportType(TaskTransportType::RAYLET).Binary());
|
||||||
} else {
|
} else {
|
||||||
// Inline the object value.
|
// Inline the object value.
|
||||||
if (value->HasData()) {
|
if (it->second->HasData()) {
|
||||||
const auto &data = value->GetData();
|
const auto &data = it->second->GetData();
|
||||||
mutable_arg->set_data(data->Data(), data->Size());
|
mutable_arg->set_data(data->Data(), data->Size());
|
||||||
}
|
}
|
||||||
if (value->HasMetadata()) {
|
if (it->second->HasMetadata()) {
|
||||||
const auto &metadata = value->GetMetadata();
|
const auto &metadata = it->second->GetMetadata();
|
||||||
mutable_arg->set_metadata(metadata->Data(), metadata->Size());
|
mutable_arg->set_metadata(metadata->Data(), metadata->Size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found = true;
|
found++;
|
||||||
|
} else {
|
||||||
|
RAY_CHECK(!id.IsDirectCallType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RAY_CHECK(found) << "obj id " << obj_id << " not found";
|
// Each dependency could be inlined more than once.
|
||||||
|
RAY_CHECK(found >= dependencies.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalDependencyResolver::ResolveDependencies(TaskSpecification &task,
|
void LocalDependencyResolver::ResolveDependencies(TaskSpecification &task,
|
||||||
std::function<void()> on_complete) {
|
std::function<void()> on_complete) {
|
||||||
absl::flat_hash_set<ObjectID> local_dependencies;
|
absl::flat_hash_map<ObjectID, std::shared_ptr<RayObject>> local_dependencies;
|
||||||
for (size_t i = 0; i < task.NumArgs(); i++) {
|
for (size_t i = 0; i < task.NumArgs(); i++) {
|
||||||
auto count = task.ArgIdCount(i);
|
auto count = task.ArgIdCount(i);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
RAY_CHECK(count <= 1) << "multi args not implemented";
|
RAY_CHECK(count <= 1) << "multi args not implemented";
|
||||||
const auto &id = task.ArgId(i, 0);
|
const auto &id = task.ArgId(i, 0);
|
||||||
if (id.IsDirectCallType()) {
|
if (id.IsDirectCallType()) {
|
||||||
local_dependencies.insert(id);
|
local_dependencies.emplace(id, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,16 +78,17 @@ void LocalDependencyResolver::ResolveDependencies(TaskSpecification &task,
|
|||||||
std::make_shared<TaskState>(task, std::move(local_dependencies));
|
std::make_shared<TaskState>(task, std::move(local_dependencies));
|
||||||
num_pending_ += 1;
|
num_pending_ += 1;
|
||||||
|
|
||||||
for (const auto &obj_id : state->local_dependencies) {
|
for (const auto &it : state->local_dependencies) {
|
||||||
|
const ObjectID &obj_id = it.first;
|
||||||
in_memory_store_->GetAsync(
|
in_memory_store_->GetAsync(
|
||||||
obj_id, [this, state, obj_id, on_complete](std::shared_ptr<RayObject> obj) {
|
obj_id, [this, state, obj_id, on_complete](std::shared_ptr<RayObject> obj) {
|
||||||
RAY_CHECK(obj != nullptr);
|
RAY_CHECK(obj != nullptr);
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
{
|
{
|
||||||
absl::MutexLock lock(&mu_);
|
absl::MutexLock lock(&mu_);
|
||||||
state->local_dependencies.erase(obj_id);
|
state->local_dependencies[obj_id] = std::move(obj);
|
||||||
DoInlineObjectValue(obj_id, obj, state->task);
|
if (--state->dependencies_remaining == 0) {
|
||||||
if (state->local_dependencies.empty()) {
|
InlineDependencies(state->local_dependencies, state->task);
|
||||||
complete = true;
|
complete = true;
|
||||||
num_pending_ -= 1;
|
num_pending_ -= 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user