From f9098fe6319ff748593cf121fcc0665c90f649b4 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Tue, 8 Sep 2020 22:00:46 +0800 Subject: [PATCH] [Java doc] index and introduction page (#10646) --- doc/source/index.rst | 115 +++++++++++++++++++++------ doc/source/ray-overview/index.rst | 127 +++++++++++++++++++++++++----- 2 files changed, 199 insertions(+), 43 deletions(-) diff --git a/doc/source/index.rst b/doc/source/index.rst index 20fdb8c85..18bbe1607 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -9,37 +9,108 @@ 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 uses Tasks (functions) and Actors (Classes) to allow you to parallelize your Python code: +Ray provides Python and Java API. And Ray uses Tasks (functions) and Actors (Classes) to allow you to parallelize your code. -.. code-block:: python +.. tabs:: + .. group-tab:: Python - # First, run `pip install ray`. + .. code-block:: python - import ray - ray.init() + # First, run `pip install ray`. - @ray.remote - def f(x): - return x * x + import ray + ray.init() - futures = [f.remote(i) for i in range(4)] - print(ray.get(futures)) # [0, 1, 4, 9] + @ray.remote + def f(x): + return x * x - @ray.remote - class Counter(object): - def __init__(self): - self.n = 0 + futures = [f.remote(i) for i in range(4)] + print(ray.get(futures)) # [0, 1, 4, 9] - def increment(self): - self.n += 1 + @ray.remote + class Counter(object): + def __init__(self): + self.n = 0 - def read(self): - return self.n + def increment(self): + self.n += 1 - counters = [Counter.remote() for i in range(4)] - [c.increment.remote() for c in counters] - futures = [c.read.remote() for c in counters] - print(ray.get(futures)) # [1, 1, 1, 1] + def read(self): + return self.n + + counters = [Counter.remote() for i in range(4)] + [c.increment.remote() for c in counters] + futures = [c.read.remote() for c in counters] + print(ray.get(futures)) # [1, 1, 1, 1] + + .. group-tab:: Java + + First, add the `ray-api `__ and `ray-runtime `__ dependencies in your project. + + .. code-block:: java + + import io.ray.api.ActorHandle; + import io.ray.api.ObjectRef; + import io.ray.api.Ray; + import java.util.ArrayList; + import java.util.List; + import java.util.stream.Collectors; + + public class RayDemo { + + public static int f(int x) { + return x * x; + } + + public static class Counter { + + private int n = 0; + + public void increment() { + this.n += 1; + } + + public int read() { + return this.n; + } + } + + public static void main(String[] args) { + // Intialize Ray runtime. + Ray.init(); + { + List> objectRefList = new ArrayList<>(); + // Invoke the `f` method 4 times remotely as Ray tasks. + // The tasks will run in parallel in the background. + for (int i = 0; i < 4; i++) { + objectRefList.add(Ray.task(RayDemo::f, i).remote()); + } + // Get the actual results of the tasks with `get`. + System.out.println(Ray.get(objectRefList)); // [0, 1, 4, 9] + } + + { + List> counters = new ArrayList<>(); + // Create 4 actors from the `Counter` class. + // They will run in remote worker processes. + for (int i = 0; i < 4; i++) { + counters.add(Ray.actor(Counter::new).remote()); + } + + // Invoke the `increment` method on each actor. + // This will send an actor task to each remote actor. + for (ActorHandle counter : counters) { + counter.task(Counter::increment).remote(); + } + // Invoke the `read` method on each actor, and print the results. + List> objectRefList = counters.stream() + .map(counter -> counter.task(Counter::read).remote()) + .collect(Collectors.toList()); + System.out.println(Ray.get(objectRefList)); // [1, 1, 1, 1] + } + } + } You can also get started by visiting our `Tutorials `_. For the latest wheels (nightlies), see the `installation page `__. diff --git a/doc/source/ray-overview/index.rst b/doc/source/ray-overview/index.rst index 67d96f422..c565ccb2b 100644 --- a/doc/source/ray-overview/index.rst +++ b/doc/source/ray-overview/index.rst @@ -8,40 +8,79 @@ A Gentle Introduction to Ray This tutorial will provide a tour of the core features of Ray. -First, install Ray with: ``pip install ray``, and now we can execute some Python in parallel. +Ray provides Python and Java API. +To use Ray in Python, first install Ray with: ``pip install ray``. +To use Ray in Java, first add the `ray-api `__ and `ray-runtime `__ dependencies in your project. +Then we can use Ray to parallelize your program. -Parallelizing Python Functions with Ray Tasks -============================================= +Parallelizing Python/Java Functions with Ray Tasks +================================================== -First, import ray and ``init`` the Ray service. -Then decorate your function with ``@ray.remote`` to declare that you want to run this function -remotely. Lastly, call that function with ``.remote()`` instead of calling it normally. This remote call yields a future, or ``ObjectRef`` that you can then -fetch with ``ray.get``. +.. tabs:: + .. group-tab:: Python -.. code-block:: python + First, import ray and ``init`` the Ray service. + Then decorate your function with ``@ray.remote`` to declare that you want to run this function + remotely. Lastly, call that function with ``.remote()`` instead of calling it normally. This remote call yields a future, or ``ObjectRef`` that you can then + fetch with ``ray.get``. - import ray - ray.init() + .. code-block:: python - @ray.remote - def f(x): - return x * x + import ray + ray.init() - futures = [f.remote(i) for i in range(4)] - print(ray.get(futures)) # [0, 1, 4, 9] + @ray.remote + def f(x): + return x * x -In the above code block we defined some Ray Tasks. While these are great for stateless operations, sometimes you -must maintain the state of your application. You can do that with Ray Actors. + futures = [f.remote(i) for i in range(4)] + print(ray.get(futures)) # [0, 1, 4, 9] -Parallelizing Python Classes with Ray Actors -============================================== + .. group-tab:: Java -Ray provides actors to allow you to parallelize an instance of a class in Python. + First, use ``Ray.init`` to initialize Ray runtime. + Then you can use ``Ray.task(...).remote()`` to convert any Java static method into a Ray task. The task will run asynchronously in a remote worker process. The ``remote`` method will return an ``ObjectRef``, and you can then fetch the actual result with ``get``. + + .. code-block:: java + + import io.ray.api.ObjectRef; + import io.ray.api.Ray; + import java.util.ArrayList; + import java.util.List; + + public class RayDemo { + + public static int f(int x) { + return x * x; + } + + public static void main(String[] args) { + // Intialize Ray runtime. + Ray.init(); + List> objectRefList = new ArrayList<>(); + // Invoke the `f` method 4 times remotely as Ray tasks. + // The tasks will run in parallel in the background. + for (int i = 0; i < 4; i++) { + objectRefList.add(Ray.task(RayDemo::f, i).remote()); + } + // Get the actual results of the tasks. + System.out.println(Ray.get(objectRefList)); // [0, 1, 4, 9] + } + } + + In the above code block we defined some Ray Tasks. While these are great for stateless operations, sometimes you + must maintain the state of your application. You can do that with Ray Actors. + +Parallelizing Python/Java Classes with Ray Actors +================================================= + +Ray provides actors to allow you to parallelize an instance of a class in Python/Java. When you instantiate a class that is a Ray actor, Ray will start a remote instance of that class in the cluster. This actor can then execute remote method calls and maintain its own internal state. -.. code-block:: python +.. tabs:: + .. code-tab:: python import ray ray.init() # Only call this once. @@ -62,6 +101,52 @@ maintain its own internal state. futures = [c.read.remote() for c in counters] print(ray.get(futures)) # [1, 1, 1, 1] + .. code-tab:: java + + import io.ray.api.ActorHandle; + import io.ray.api.ObjectRef; + import io.ray.api.Ray; + import java.util.ArrayList; + import java.util.List; + import java.util.stream.Collectors; + + public class RayDemo { + + public static class Counter { + + private int n = 0; + + public void increment() { + this.n += 1; + } + + public int read() { + return this.n; + } + } + + public static void main(String[] args) { + // Intialize Ray runtime. + Ray.init(); + List> counters = new ArrayList<>(); + // Create 4 actors from the `Counter` class. + // They will run in remote worker processes. + for (int i = 0; i < 4; i++) { + counters.add(Ray.actor(Counter::new).remote()); + } + + // Invoke the `increment` method on each actor. + // This will send an actor task to each remote actor. + for (ActorHandle counter : counters) { + counter.task(Counter::increment).remote(); + } + // Invoke the `read` method on each actor, and print the results. + List> objectRefList = counters.stream() + .map(counter -> counter.task(Counter::read).remote()) + .collect(Collectors.toList()); + System.out.println(Ray.get(objectRefList)); // [1, 1, 1, 1] + } + } An Overview of the Ray Libraries ================================