Add placement group java api (#9611)

* add part code

* add part code

* add part code

* fix code style

* fix review comment

* fix review comment

* add part code

* add part code

* add part code

* add part code

* fix review comment

* fix review comment

* fix code style

* fix review comment

* fix lint error

* fix lint error

Co-authored-by: 灵洵 <fengbin.ffb@antfin.com>
This commit is contained in:
fangfengbin
2020-07-25 15:39:05 +08:00
committed by GitHub
co-authored by 灵洵
parent 5dc4b6686e
commit 28d5f9696d
22 changed files with 403 additions and 26 deletions
+6 -6
View File
@@ -119,18 +119,18 @@ struct ActorCreationOptions {
using PlacementStrategy = rpc::PlacementStrategy;
struct PlacementGroupCreationOptions {
PlacementGroupCreationOptions() {}
PlacementGroupCreationOptions() = default;
PlacementGroupCreationOptions(
const std::string &name, PlacementStrategy strategy,
const std::vector<std::unordered_map<std::string, double>> &bundles)
: strategy(strategy), bundles(bundles), name(name) {}
std::string name, PlacementStrategy strategy,
std::vector<std::unordered_map<std::string, double>> bundles)
: name(std::move(name)), strategy(strategy), bundles(std::move(bundles)) {}
/// The name of the placement group.
const std::string name;
/// The strategy to place the bundle in Placement Group.
const PlacementStrategy strategy = rpc::PACK;
/// The resource bundles in this placement group.
const std::vector<std::unordered_map<std::string, double>> bundles;
/// The name of the placement group.
const std::string name;
};
} // namespace ray
@@ -25,7 +25,7 @@ extern "C" {
* Class: io_ray_runtime_RayNativeRuntime
* Method: nativeInitialize
* Signature:
* (ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLio/ray/runtime/gcs/GcsClientOptions;Ljava/lang/String;ILjava/lang/String;Ljava/util/Map;[B)V
* (ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLio/ray/runtime/gcs/GcsClientOptions;ILjava/lang/String;Ljava/util/Map;)V
*/
JNIEXPORT void JNICALL Java_io_ray_runtime_RayNativeRuntime_nativeInitialize(
JNIEnv *, jclass, jint, jstring, jint, jstring, jstring, jstring, jbyteArray, jobject,
@@ -42,7 +42,7 @@ Java_io_ray_runtime_RayNativeRuntime_nativeRunTaskExecutor(JNIEnv *, jclass, job
/*
* Class: io_ray_runtime_RayNativeRuntime
* Method: nativeShutdown
* Signature: (Z)V
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_io_ray_runtime_RayNativeRuntime_nativeShutdown(JNIEnv *,
jclass);
@@ -16,10 +16,10 @@
#include <jni.h>
#include "jni_utils.h"
#include "ray/common/id.h"
#include "ray/core_worker/common.h"
#include "ray/core_worker/core_worker.h"
#include "jni_utils.h"
/// Store C++ instances of ray function in the cache to avoid unnessesary JNI operations.
thread_local std::unordered_map<jint, std::vector<std::pair<jobject, ray::RayFunction>>>
@@ -109,6 +109,7 @@ inline ray::ActorCreationOptions ToActorCreationOptions(JNIEnv *env,
std::unordered_map<std::string, double> resources;
std::vector<std::string> dynamic_worker_options;
uint64_t max_concurrency = 1;
auto placement_options = std::make_pair(ray::PlacementGroupID::Nil(), -1);
if (actorCreationOptions) {
global =
env->GetBooleanField(actorCreationOptions, java_actor_creation_options_global);
@@ -130,6 +131,19 @@ inline ray::ActorCreationOptions ToActorCreationOptions(JNIEnv *env,
}
max_concurrency = static_cast<uint64_t>(env->GetIntField(
actorCreationOptions, java_actor_creation_options_max_concurrency));
auto group =
env->GetObjectField(actorCreationOptions, java_actor_creation_options_group);
if (group) {
auto placement_group_id = env->GetObjectField(group, java_placement_group_id);
auto java_id_bytes = static_cast<jbyteArray>(
env->CallObjectMethod(placement_group_id, java_base_id_get_bytes));
RAY_CHECK_JAVA_EXCEPTION(env);
auto id = JavaByteArrayToId<ray::PlacementGroupID>(env, java_id_bytes);
auto index = env->GetIntField(actorCreationOptions,
java_actor_creation_options_bundle_index);
placement_options = std::make_pair(id, index);
}
}
auto full_name = GetActorFullName(global, name);
@@ -142,10 +156,34 @@ inline ray::ActorCreationOptions ToActorCreationOptions(JNIEnv *env,
dynamic_worker_options,
/*is_detached=*/false,
full_name,
/*is_asyncio=*/false};
/*is_asyncio=*/false,
placement_options};
return actor_creation_options;
}
inline ray::PlacementStrategy ConvertStrategy(jint java_strategy) {
return 0 == java_strategy ? ray::rpc::PACK : ray::rpc::SPREAD;
}
inline ray::PlacementGroupCreationOptions ToPlacementGroupCreationOptions(
JNIEnv *env, jobject java_bundles, jint java_strategy) {
std::vector<std::unordered_map<std::string, double>> bundles;
JavaListToNativeVector<std::unordered_map<std::string, double>>(
env, java_bundles, &bundles, [](JNIEnv *env, jobject java_bundle) {
return JavaMapToNativeMap<std::string, double>(
env, java_bundle,
[](JNIEnv *env, jobject java_key) {
return JavaStringToNativeString(env, (jstring)java_key);
},
[](JNIEnv *env, jobject java_value) {
double value = env->CallDoubleMethod(java_value, java_double_double_value);
RAY_CHECK_JAVA_EXCEPTION(env);
return value;
});
});
return ray::PlacementGroupCreationOptions("", ConvertStrategy(java_strategy), bundles);
}
#ifdef __cplusplus
extern "C" {
#endif
@@ -212,6 +250,19 @@ Java_io_ray_runtime_task_NativeTaskSubmitter_nativeSubmitActorTask(
return NativeIdVectorToJavaByteArrayList(env, return_ids);
}
JNIEXPORT jbyteArray JNICALL
Java_io_ray_runtime_task_NativeTaskSubmitter_nativeCreatePlacementGroup(JNIEnv *env,
jclass,
jobject bundles,
jint strategy) {
auto options = ToPlacementGroupCreationOptions(env, bundles, strategy);
ray::PlacementGroupID placement_group_id;
auto status = ray::CoreWorkerProcess::GetCoreWorker().CreatePlacementGroup(
options, &placement_group_id);
THROW_EXCEPTION_AND_RETURN_IF_NOT_OK(env, status, nullptr);
return IdToJavaByteArray<ray::PlacementGroupID>(env, placement_group_id);
}
#ifdef __cplusplus
}
#endif
@@ -52,6 +52,15 @@ Java_io_ray_runtime_task_NativeTaskSubmitter_nativeSubmitActorTask(JNIEnv *, jcl
jint, jobject, jint,
jobject);
/*
* Class: io_ray_runtime_task_NativeTaskSubmitter
* Method: nativeCreatePlacementGroup
* Signature: (Ljava/util/List;I)[B
*/
JNIEXPORT jbyteArray JNICALL
Java_io_ray_runtime_task_NativeTaskSubmitter_nativeCreatePlacementGroup(JNIEnv *, jclass,
jobject, jint);
#ifdef __cplusplus
}
#endif
+16
View File
@@ -74,6 +74,8 @@ jfieldID java_actor_creation_options_name;
jfieldID java_actor_creation_options_max_restarts;
jfieldID java_actor_creation_options_jvm_options;
jfieldID java_actor_creation_options_max_concurrency;
jfieldID java_actor_creation_options_group;
jfieldID java_actor_creation_options_bundle_index;
jclass java_gcs_client_options_class;
jfieldID java_gcs_client_options_ip;
@@ -89,6 +91,9 @@ jclass java_task_executor_class;
jmethodID java_task_executor_parse_function_arguments;
jmethodID java_task_executor_execute;
jclass java_placement_group_class;
jfieldID java_placement_group_id;
JavaVM *jvm;
inline jclass LoadClass(JNIEnv *env, const char *class_name) {
@@ -177,6 +182,12 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
java_base_task_options_resources =
env->GetFieldID(java_base_task_options_class, "resources", "Ljava/util/Map;");
java_placement_group_class =
LoadClass(env, "io/ray/runtime/placementgroup/PlacementGroupImpl");
java_placement_group_id =
env->GetFieldID(java_placement_group_class, "id",
"Lio/ray/runtime/placementgroup/PlacementGroupId;");
java_actor_creation_options_class =
LoadClass(env, "io/ray/api/options/ActorCreationOptions");
java_actor_creation_options_global =
@@ -189,6 +200,11 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
java_actor_creation_options_class, "jvmOptions", "Ljava/lang/String;");
java_actor_creation_options_max_concurrency =
env->GetFieldID(java_actor_creation_options_class, "maxConcurrency", "I");
java_actor_creation_options_group =
env->GetFieldID(java_actor_creation_options_class, "group",
"Lio/ray/api/placementgroup/PlacementGroup;");
java_actor_creation_options_bundle_index =
env->GetFieldID(java_actor_creation_options_class, "bundleIndex", "I");
java_gcs_client_options_class = LoadClass(env, "io/ray/runtime/gcs/GcsClientOptions");
java_gcs_client_options_ip =
env->GetFieldID(java_gcs_client_options_class, "ip", "Ljava/lang/String;");
+9
View File
@@ -127,6 +127,10 @@ extern jfieldID java_actor_creation_options_max_restarts;
extern jfieldID java_actor_creation_options_jvm_options;
/// maxConcurrency field of ActorCreationOptions class
extern jfieldID java_actor_creation_options_max_concurrency;
/// group field of ActorCreationOptions class
extern jfieldID java_actor_creation_options_group;
/// bundleIndex field of ActorCreationOptions class
extern jfieldID java_actor_creation_options_bundle_index;
/// GcsClientOptions class
extern jclass java_gcs_client_options_class;
@@ -153,6 +157,11 @@ extern jmethodID java_task_executor_parse_function_arguments;
/// execute method of TaskExecutor class
extern jmethodID java_task_executor_execute;
/// PlacementGroup class
extern jclass java_placement_group_class;
/// id field of PlacementGroup class
extern jfieldID java_placement_group_id;
#define CURRENT_JNI_VERSION JNI_VERSION_1_8
extern JavaVM *jvm;
@@ -41,8 +41,8 @@ ScheduleMap GcsPackStrategy::Schedule(
const GcsNodeManager &node_manager) {
ScheduleMap schedule_map;
auto &alive_nodes = node_manager.GetAllAliveNodes();
for (size_t pos = 0; pos < bundles.size(); pos++) {
schedule_map[bundles[pos]->BundleId()] =
for (auto &bundle : bundles) {
schedule_map[bundle->BundleId()] =
ClientID::FromBinary(alive_nodes.begin()->second->node_id());
}
return schedule_map;
@@ -80,13 +80,13 @@ void GcsPlacementGroupScheduler::Schedule(
auto strategy = placement_group->GetStrategy();
auto alive_nodes = gcs_node_manager_.GetAllAliveNodes();
/// If the placement group don't have bundle, the placement group creates success.
if (bundles.size() == 0) {
if (bundles.empty()) {
schedule_success_handler(placement_group);
return;
}
// If alive_node is empty, the the placement group creates fail.
if (alive_nodes.size() == 0) {
if (alive_nodes.empty()) {
schedule_failure_handler(placement_group);
return;
}
+5 -3
View File
@@ -155,9 +155,11 @@ bool SchedulingPolicy::ScheduleBundle(
ResourceSet available_node_resources =
ResourceSet(node_resources.GetAvailableResources());
available_node_resources.SubtractResources(node_resources.GetLoadResources());
RAY_LOG(DEBUG) << "client_id " << node_client_id
<< " avail: " << node_resources.GetAvailableResources().ToString()
<< " load: " << node_resources.GetLoadResources().ToString();
RAY_LOG(DEBUG) << "Scheduling bundle, client id = " << node_client_id
<< ", available resources = "
<< node_resources.GetAvailableResources().ToString()
<< ", resources load = " << node_resources.GetLoadResources().ToString()
<< ", the resource needed = " << resource_demand.ToString();
/// If the resource_demand is subset of the whole available_node_resources, this bundle
/// can be set in this node, return true.
return resource_demand.IsSubset(available_node_resources);
+4
View File
@@ -109,6 +109,10 @@ class GcsRpcClient {
new GrpcClient<ErrorInfoGcsService>(address, port, client_call_manager));
worker_info_grpc_client_ = std::unique_ptr<GrpcClient<WorkerInfoGcsService>>(
new GrpcClient<WorkerInfoGcsService>(address, port, client_call_manager));
placement_group_info_grpc_client_ =
std::unique_ptr<GrpcClient<PlacementGroupInfoGcsService>>(
new GrpcClient<PlacementGroupInfoGcsService>(address, port,
client_call_manager));
}
/// Add job info to gcs server.