mirror of
https://github.com/vale981/ray
synced 2025-03-05 18:11:42 -05:00
[docs] Documentation + example for the C++ language API (#13138)
This commit is contained in:
parent
9eba1871bb
commit
710615c228
3 changed files with 223 additions and 1 deletions
74
cpp/dev_BUILD.bazel
Normal file
74
cpp/dev_BUILD.bazel
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Bazel development build for C++ API.
|
||||
# C/C++ documentation: https://docs.bazel.build/versions/master/be/c-cpp.html
|
||||
|
||||
load("//bazel:ray.bzl", "COPTS")
|
||||
|
||||
cc_library(
|
||||
name = "ray_api",
|
||||
srcs = glob([
|
||||
"src/ray/api.cc",
|
||||
"src/ray/api/*.cc",
|
||||
"src/ray/api/*.h",
|
||||
"src/ray/app/*.cc",
|
||||
"src/ray/app/*.h",
|
||||
"src/ray/runtime/*.cc",
|
||||
"src/ray/runtime/*.h",
|
||||
"src/ray/runtime/**/*.cc",
|
||||
"src/ray/runtime/**/*.h",
|
||||
"src/ray/runtime/task/*.cc",
|
||||
"src/ray/runtime/task/*.h",
|
||||
"src/ray/util/*.cc",
|
||||
"src/ray/util/*.h",
|
||||
"src/ray/*.cc",
|
||||
"src/ray/*.h",
|
||||
"src/ray/worker/default_worker.cc",
|
||||
]),
|
||||
hdrs = glob([
|
||||
"include/ray/*.h",
|
||||
"include/ray/**/*.h",
|
||||
"include/ray/**/**/*.h",
|
||||
]),
|
||||
copts = COPTS,
|
||||
linkopts = ["-ldl"],
|
||||
linkstatic = True,
|
||||
strip_include_prefix = "include",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//:core_worker_lib",
|
||||
"//:ray_common",
|
||||
"//:ray_util",
|
||||
"@boost//:asio",
|
||||
"@boost//:thread",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@msgpack",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "example",
|
||||
srcs = glob([
|
||||
"src/ray/example/*.cc",
|
||||
]),
|
||||
copts = COPTS,
|
||||
linkstatic = True,
|
||||
deps = [
|
||||
"ray_api",
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "ray_cpp_pkg",
|
||||
srcs = [
|
||||
"example",
|
||||
"ray_api",
|
||||
],
|
||||
outs = ["ray_cpp_pkg.out"],
|
||||
cmd = """
|
||||
WORK_DIR="$$(pwd)" &&
|
||||
mkdir -p "$$WORK_DIR/python/ray/core/src/ray/cpp/" &&
|
||||
cp -f $(location example) "$$WORK_DIR/python/ray/core/src/ray/cpp/default_worker" &&
|
||||
cp -f $(locations ray_api) "$$WORK_DIR/python/ray/core/src/ray/cpp/" &&
|
||||
echo "$$WORK_DIR" > $@
|
||||
""",
|
||||
local = 1,
|
||||
)
|
134
cpp/src/ray/example/example.cc
Normal file
134
cpp/src/ray/example/example.cc
Normal file
|
@ -0,0 +1,134 @@
|
|||
|
||||
#include <ray/api.h>
|
||||
#include <ray/api/ray_config.h>
|
||||
#include <ray/experimental/default_worker.h>
|
||||
|
||||
using namespace ::ray::api;
|
||||
|
||||
/// general function of user code
|
||||
int Return1() { return 1; }
|
||||
int Plus1(int x) { return x + 1; }
|
||||
int Plus(int x, int y) { return x + y; }
|
||||
|
||||
/// a class of user code
|
||||
class Counter {
|
||||
public:
|
||||
int count;
|
||||
|
||||
Counter(int init) { count = init; }
|
||||
static Counter *FactoryCreate() { return new Counter(0); }
|
||||
static Counter *FactoryCreate(int init) { return new Counter(init); }
|
||||
static Counter *FactoryCreate(int init1, int init2) {
|
||||
return new Counter(init1 + init2);
|
||||
}
|
||||
/// non static function
|
||||
int Plus1() {
|
||||
count += 1;
|
||||
return count;
|
||||
}
|
||||
int Add(int x) {
|
||||
count += x;
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/// Currently, we compile `default_worker` and `example` in one single binary,
|
||||
/// to work around a symbol conflicting issue.
|
||||
/// This is the main function of the binary, and we use the `is_default_worker` arg to
|
||||
/// tell if this binary is used as `default_worker` or `example`.
|
||||
const char *default_worker_magic = "is_default_worker";
|
||||
/// `is_default_worker` is the last arg of `argv`
|
||||
if (argc > 1 &&
|
||||
memcmp(argv[argc - 1], default_worker_magic, strlen(default_worker_magic)) == 0) {
|
||||
default_worker_main(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
/// initialization to cluster mode
|
||||
ray::api::RayConfig::GetInstance()->run_mode = RunMode::CLUSTER;
|
||||
/// Dynamic library loading is not supported yet.
|
||||
ray::api::RayConfig::GetInstance()->lib_name = "";
|
||||
Ray::Init();
|
||||
|
||||
/// put and get object
|
||||
auto obj = Ray::Put(12345);
|
||||
auto get_put_result = *(Ray::Get(obj));
|
||||
std::cout << "get_put_result = " << get_put_result << std::endl;
|
||||
|
||||
/// common task without args
|
||||
auto task_obj = Ray::Task(Return1).Remote();
|
||||
int task_result1 = *(Ray::Get(task_obj));
|
||||
std::cout << "task_result1 = " << task_result1 << std::endl;
|
||||
|
||||
/// common task with args
|
||||
task_obj = Ray::Task(Plus1, 5).Remote();
|
||||
int task_result2 = *(Ray::Get(task_obj));
|
||||
std::cout << "task_result2 = " << task_result2 << std::endl;
|
||||
|
||||
/// actor task without args
|
||||
ActorHandle<Counter> actor1 = Ray::Actor(Counter::FactoryCreate).Remote();
|
||||
auto actor_object1 = actor1.Task(&Counter::Plus1).Remote();
|
||||
int actor_result1 = *(Ray::Get(actor_object1));
|
||||
std::cout << "actor_result1 = " << actor_result1 << std::endl;
|
||||
|
||||
/// actor task with args
|
||||
ActorHandle<Counter> actor2 = Ray::Actor(Counter::FactoryCreate, 1).Remote();
|
||||
auto actor_object2 = actor2.Task(&Counter::Add, 5).Remote();
|
||||
int actor_result2 = *(Ray::Get(actor_object2));
|
||||
std::cout << "actor_result2 = " << actor_result2 << std::endl;
|
||||
|
||||
/// actor task with args which pass by reference
|
||||
ActorHandle<Counter> actor3 = Ray::Actor(Counter::FactoryCreate, 6, 0).Remote();
|
||||
auto actor_object3 = actor3.Task(&Counter::Add, actor_object2).Remote();
|
||||
int actor_result3 = *(Ray::Get(actor_object3));
|
||||
std::cout << "actor_result3 = " << actor_result3 << std::endl;
|
||||
|
||||
/// general function remote call(args passed by value)
|
||||
auto r0 = Ray::Task(Return1).Remote();
|
||||
auto r2 = Ray::Task(Plus, 3, 22).Remote();
|
||||
|
||||
int task_result3 = *(Ray::Get(r2));
|
||||
std::cout << "task_result3 = " << task_result3 << std::endl;
|
||||
|
||||
/// general function remote call(args passed by reference)
|
||||
auto r3 = Ray::Task(Return1).Remote();
|
||||
auto r4 = Ray::Task(Plus1, r3).Remote();
|
||||
auto r5 = Ray::Task(Plus, r4, r3).Remote();
|
||||
auto r6 = Ray::Task(Plus, r4, 10).Remote();
|
||||
|
||||
int task_result4 = *(Ray::Get(r6));
|
||||
int task_result5 = *(Ray::Get(r5));
|
||||
std::cout << "task_result4 = " << task_result4 << ", task_result5 = " << task_result5
|
||||
<< std::endl;
|
||||
|
||||
/// create actor and actor function remote call with args passed by value
|
||||
ActorHandle<Counter> actor4 = Ray::Actor(Counter::FactoryCreate, 10).Remote();
|
||||
auto r10 = actor4.Task(&Counter::Add, 8).Remote();
|
||||
|
||||
int actor_result4 = *(Ray::Get(r10));
|
||||
std::cout << "actor_result4 = " << actor_result4 << std::endl;
|
||||
|
||||
/// create actor and task function remote call with args passed by reference
|
||||
ActorHandle<Counter> actor5 = Ray::Actor(Counter::FactoryCreate, r10, 0).Remote();
|
||||
|
||||
auto r11 = actor5.Task(&Counter::Add, r0).Remote();
|
||||
auto r12 = actor5.Task(&Counter::Add, r11).Remote();
|
||||
auto r13 = actor5.Task(&Counter::Add, r10).Remote();
|
||||
auto r14 = actor5.Task(&Counter::Add, r13).Remote();
|
||||
auto r15 = Ray::Task(Plus, r0, r11).Remote();
|
||||
auto r16 = Ray::Task(Plus1, r15).Remote();
|
||||
|
||||
int result12 = *(Ray::Get(r12));
|
||||
int result14 = *(Ray::Get(r14));
|
||||
int result11 = *(Ray::Get(r11));
|
||||
int result13 = *(Ray::Get(r13));
|
||||
int result16 = *(Ray::Get(r16));
|
||||
int result15 = *(Ray::Get(r15));
|
||||
|
||||
std::cout << "Final result:" << std::endl;
|
||||
std::cout << "result11 = " << result11 << ", result12 = " << result12
|
||||
<< ", result13 = " << result13 << ", result14 = " << result14
|
||||
<< ", result15 = " << result15 << ", result16 = " << result16 << std::endl;
|
||||
Ray::Shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -9,7 +9,7 @@ Getting Started with Ray
|
|||
Check out :ref:`gentle-intro` to learn more about Ray and its ecosystem of libraries that enable things like distributed hyperparameter tuning,
|
||||
reinforcement learning, and distributed training.
|
||||
|
||||
Ray provides Python and Java API. And Ray uses Tasks (functions) and Actors (Classes) to allow you to parallelize your code.
|
||||
Ray provides Python, Java, and *EXPERIMENTAL* C++ API. And Ray uses Tasks (functions) and Actors (Classes) to allow you to parallelize your code.
|
||||
|
||||
.. tabs::
|
||||
.. group-tab:: Python
|
||||
|
@ -112,6 +112,20 @@ Ray provides Python and Java API. And Ray uses Tasks (functions) and Actors (Cla
|
|||
}
|
||||
}
|
||||
|
||||
.. group-tab:: C++ (EXPERIMENTAL)
|
||||
|
||||
The C++ Ray API is currently experimental with limited support. You can track its development `here <https://github.com/ray-project/ray/milestone/17>`__ and report issues on GitHub.
|
||||
Run the following commands to get started:
|
||||
- Build ray from source with *bazel* as shown `here <https://docs.ray.io/en/master/development.html#building-ray-full>`__.
|
||||
- Run `cd ray/cpp`.
|
||||
- Run `cp dev_BUILD.bazel BUILD.bazel`.
|
||||
- Modify `src/ray/example.cc`.
|
||||
- Run `ray stop`.
|
||||
- Run `bazel build //cpp:example`.
|
||||
- Run `bazel run //cpp:example`.
|
||||
|
||||
.. literalinclude:: ../../cpp/src/ray/example/example.cc
|
||||
:language: cpp
|
||||
|
||||
You can also get started by visiting our `Tutorials <https://github.com/ray-project/tutorial>`_. For the latest wheels (nightlies), see the `installation page <installation.html>`__.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue