mirror of
https://github.com/wassname/ray.git
synced 2026-09-12 12:51:15 +08:00
add java tutorial (#2491)
This commit is contained in:
committed by
Robert Nishihara
parent
90a3ea9443
commit
0ea7a6abf0
+5
-315
@@ -2,7 +2,6 @@ This directory contains the java worker, with the following components.
|
|||||||
|
|
||||||
- java/api: Ray API definition
|
- java/api: Ray API definition
|
||||||
- java/common: utilities
|
- java/common: utilities
|
||||||
- java/hook: binary rewrite of the Java byte-code for remote execution
|
|
||||||
- java/runtime-common: common implementation of the runtime in worker
|
- java/runtime-common: common implementation of the runtime in worker
|
||||||
- java/runtime-dev: a pure-java mock implementation of the runtime for
|
- java/runtime-dev: a pure-java mock implementation of the runtime for
|
||||||
fast development
|
fast development
|
||||||
@@ -11,21 +10,6 @@ This directory contains the java worker, with the following components.
|
|||||||
- src/local\_scheduler/lib/java: JNI client library for local scheduler
|
- src/local\_scheduler/lib/java: JNI client library for local scheduler
|
||||||
- src/plasma/lib/java: JNI client library for plasma storage
|
- src/plasma/lib/java: JNI client library for plasma storage
|
||||||
|
|
||||||
Build and test
|
|
||||||
==============
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# build native components
|
|
||||||
../build.sh -l java
|
|
||||||
|
|
||||||
# build java worker
|
|
||||||
mvn clean install -Dmaven.test.skip
|
|
||||||
|
|
||||||
# test
|
|
||||||
export RAY_CONFIG=ray.config.ini
|
|
||||||
mvn test
|
|
||||||
|
|
||||||
Quick start
|
Quick start
|
||||||
===========
|
===========
|
||||||
|
|
||||||
@@ -92,304 +76,10 @@ correspondent calls executed on remote machines.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ray Java API
|
More information
|
||||||
============
|
================
|
||||||
|
|
||||||
Basic API
|
- `Installation <https://github.com/ray-project/ray/tree/master/java/doc/installation.rst>`_
|
||||||
---------
|
- `API document <https://github.com/ray-project/ray/tree/master/java/doc/api.rst>`_
|
||||||
|
- `Tutorial <https://github.com/ray-project/ray/tree/master/java/tutorial>`_
|
||||||
|
|
||||||
``Ray.init()``
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Ray.init should be invoked before any other Ray functions to initialize
|
|
||||||
the runtime.
|
|
||||||
|
|
||||||
``@RayRemote``
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The annotation of ``@RayRemote`` can be used to decorate static java
|
|
||||||
method or class. The former indicates that a target function is a remote
|
|
||||||
function, which is valid with the follow requirements. \* it must be a
|
|
||||||
public static method \* parameters and return value must not be the
|
|
||||||
primitive type of java such as int, double, but could use the wrapper
|
|
||||||
class like Integer,Double \* the return value of the method must always
|
|
||||||
be the same with the same input
|
|
||||||
|
|
||||||
When the annotation is used for classes, the classes are considered
|
|
||||||
actors(a mechanism to share state among many remote functions). The
|
|
||||||
member functions can be invoked using ``Ray.call``. The requirements for
|
|
||||||
an actor class are as follows. \* it must have an constructor without
|
|
||||||
any parameter \* if it is an inner class, it must be public static \* it
|
|
||||||
must not have a member field or method decorated using
|
|
||||||
``public static``, as the semantic is undefined with multiple instances
|
|
||||||
of this same class on different machines \* an actor method must be
|
|
||||||
decorated using ``public`` but no ``static``, and the other requirements
|
|
||||||
are the same as above.
|
|
||||||
|
|
||||||
``Ray.call``
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
RayObject<R> call(Func func, ...);
|
|
||||||
|
|
||||||
``func`` is the target method, continued with appropriate parameters.
|
|
||||||
There are some requirements here:
|
|
||||||
|
|
||||||
- the return type of ``func`` must be ``R``
|
|
||||||
- currently at most 6 parameters of ``func`` are allowed
|
|
||||||
- each parameter must be of type ``T`` of the correspondent ``func``'s
|
|
||||||
parameter, or be the lifted ``RayObject<T>`` to indicate a result
|
|
||||||
from another ray call
|
|
||||||
|
|
||||||
The returned object is labled as ``RayObject<R>`` and its value will be
|
|
||||||
put into memory of the machine where the function call is executed.
|
|
||||||
|
|
||||||
``Ray.put``
|
|
||||||
~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can also invoke ``Ray.put`` to explicitly place an object into local
|
|
||||||
memory.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public static <T> RayObject<T> put(T object);
|
|
||||||
public static <T, TM> RayObject<T> put(T obj, TM metadata);
|
|
||||||
|
|
||||||
``RayObject<T>.get/getMeta``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public class RayObject<T> {
|
|
||||||
public T get() throws TaskExecutionException;
|
|
||||||
public <M> M getMeta() throws TaskExecutionException;
|
|
||||||
}
|
|
||||||
|
|
||||||
This method blocks current thread until requested data gets ready and is
|
|
||||||
fetched (if needed) from remote memory to local.
|
|
||||||
|
|
||||||
``Ray.wait``
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Calling ``Ray.wait`` will block current thread and wait for specified
|
|
||||||
ray calls. It returns when at least ``numReturns`` calls are completed,
|
|
||||||
or the ``timeout`` expires. See multi-value support for ``RayList``.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public static WaitResult<T> wait(RayList<T> waitfor, int numReturns, int timeout);
|
|
||||||
public static WaitResult<T> wait(RayList<T> waitfor, int numReturns);
|
|
||||||
public static WaitResult<T> wait(RayList<T> waitfor);
|
|
||||||
|
|
||||||
Multi-value API
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Multi-value Types
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Java worker supports multiple ``RayObject``\ s in a single data
|
|
||||||
structure as a return value or a ray call parameter, through the
|
|
||||||
following container types.
|
|
||||||
|
|
||||||
``MultipleReturnsX<R0, R1, ...>``
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
There are multiple heterogeneous values, with their types as ``R0``,
|
|
||||||
``R1``,... respectively. Note currently this container type is only
|
|
||||||
supported as the return type of a ray call, therefore you can not use it
|
|
||||||
as the type of an input parameter.
|
|
||||||
|
|
||||||
``RayList<T>``
|
|
||||||
''''''''''''''
|
|
||||||
|
|
||||||
A list of ``RayObject<T>``, inherited from ``List<T>`` in Java. It can
|
|
||||||
be used as the type for both return value and parameters.
|
|
||||||
|
|
||||||
``RayMap<L, T>``
|
|
||||||
''''''''''''''''
|
|
||||||
|
|
||||||
A map of ``RayObject<T>`` with each indexed using a label with type
|
|
||||||
``L``, inherited from ``Map<L, T>``. It can be used as the type for both
|
|
||||||
return value and parameters.
|
|
||||||
|
|
||||||
Enable multiple heterogeneous return values
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Java worker support at most four multiple heterogeneous return values,
|
|
||||||
and in order to let the runtime know the number of return values we
|
|
||||||
supply the method of ``Ray.call_X`` as follows.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
RayObjects2<R0, R1> call_2(Func func, ...);
|
|
||||||
RayObjects3<R0, R1, R2> call_3(Func func, ...);
|
|
||||||
RayObjects4<R0, R1, R2, R3> call_4(Func func, ...);
|
|
||||||
|
|
||||||
Note ``func`` must match the following requirements.
|
|
||||||
|
|
||||||
- It must hava the return value of ``MultipleReturnsX``, and must be
|
|
||||||
invoked using correspondent ``Ray.call_X``
|
|
||||||
|
|
||||||
Here is an example.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public class MultiRExample {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Ray.init();
|
|
||||||
RayObjects2<Integer, String> refs = Ray.call_2(MultiRExample::sayMultiRet);
|
|
||||||
Integer obj1 = refs.r0().get();
|
|
||||||
String obj2 = refs.r1().get();
|
|
||||||
Assert.assertTrue(obj1.equals(123));
|
|
||||||
Assert.assertTrue(obj2.equals("123"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public static MultipleReturns2<Integer, String> sayMultiRet() {
|
|
||||||
return new MultipleReturns2<Integer, String>(123, "123");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Return with ``RayList``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
We use ``Ray.call_n`` to do so, which is similar to ``Ray.call`` except
|
|
||||||
an additional parameter ``returnCount`` which tells the number of return
|
|
||||||
``RayObject<R>`` in ``RayList<R>``. This is because Ray core engines
|
|
||||||
needs to know it before the method is really called.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
RayList<R> call_n(Func func, Integer returnCount, ...);
|
|
||||||
|
|
||||||
Here is an example.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public class ListRExample {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Ray.init();
|
|
||||||
RayList<Integer> ns = Ray.call_n(ListRExample::sayList, 10, 10);
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
RayObject<Integer> obj = ns.Get(i);
|
|
||||||
Assert.assertTrue(i == obj.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public static List<Integer> sayList(Integer count) {
|
|
||||||
ArrayList<Integer> rets = new ArrayList<>();
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
rets.add(i);
|
|
||||||
return rets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Return with ``RayMap``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This is similar to ``RayList`` case, except that now each return
|
|
||||||
``RayObject<R>`` in ``RayMap<L,R>`` has a given label when
|
|
||||||
``Ray.call_n`` is made.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
RayMap<L, R> call_n(Func func, Collection<L> returnLabels, ...);
|
|
||||||
|
|
||||||
Here is an example.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public class MapRExample {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Ray.init();
|
|
||||||
RayMap<Integer, String> ns = Ray.call_n(MapRExample::sayMap,
|
|
||||||
Arrays.asList(1, 2, 4, 3), "n_futures_");
|
|
||||||
for (Entry<Integer, RayObject<String>> ne : ns.EntrySet()) {
|
|
||||||
Integer key = ne.getKey();
|
|
||||||
RayObject<String> obj = ne.getValue();
|
|
||||||
Assert.assertTrue(obj.get().equals("n_futures_" + key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RayRemote(externalIO = true)
|
|
||||||
public static Map<Integer, String> sayMap(Collection<Integer> ids,
|
|
||||||
String prefix) {
|
|
||||||
Map<Integer, String> ret = new HashMap<>();
|
|
||||||
for (int id : ids) {
|
|
||||||
ret.put(id, prefix + id);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enable ``RayList`` and ``RayMap`` as parameters
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
public class ListTExample {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Ray.init();
|
|
||||||
RayList<Integer> ints = new RayList<>();
|
|
||||||
ints.add(Ray.put(new Integer(1)));
|
|
||||||
ints.add(Ray.put(new Integer(1)));
|
|
||||||
ints.add(Ray.put(new Integer(1)));
|
|
||||||
RayObject<Integer> obj = Ray.call(ListTExample::sayReadRayList,
|
|
||||||
(List<Integer>)ints);
|
|
||||||
Assert.assertTrue(obj.get().equals(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public static int sayReadRayList(List<Integer> ints) {
|
|
||||||
int sum = 0;
|
|
||||||
for (Integer i : ints) {
|
|
||||||
sum += i;
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Actor Support
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Create Actors
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A regular class annotated with ``@RayRemote`` is an actor class.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public class Adder {
|
|
||||||
public Adder() {
|
|
||||||
sum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer add(Integer n) {
|
|
||||||
return sum += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
Whenever you call ``Ray.create()`` method, an actor will be created, and
|
|
||||||
you get a local ``RayActor`` of that actor as the return value.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
RayActor<Adder> adder = Ray.create(Adder.class);
|
|
||||||
|
|
||||||
Call Actor Methods
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The same ``Ray.call`` or its extended versions (e.g., ``Ray.call_n``) is
|
|
||||||
applied, except that the first argument becomes ``RayActor``.
|
|
||||||
|
|
||||||
.. code:: java
|
|
||||||
|
|
||||||
RayObject<R> Ray.call(Func func, RayActor<Adder> actor, ...);
|
|
||||||
RayObject<Integer> result1 = Ray.call(Adder::add, adder, 1);
|
|
||||||
RayObject<Integer> result2 = Ray.call(Adder::add, adder, 10);
|
|
||||||
result2.get(); // 11
|
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
Ray Java API
|
||||||
|
============
|
||||||
|
|
||||||
|
Basic API
|
||||||
|
---------
|
||||||
|
|
||||||
|
``Ray.init()``
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Ray.init should be invoked before any other Ray functions to initialize
|
||||||
|
the runtime.
|
||||||
|
|
||||||
|
``@RayRemote``
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ``@RayRemote`` annotation can be used to decorate static java
|
||||||
|
methods and classes. The former indicates that a target function is a remote
|
||||||
|
function, which is valid with the follow requirements.
|
||||||
|
|
||||||
|
- It must be a public static method.
|
||||||
|
- Its parameters and return value cannot be primitive types like int or
|
||||||
|
double but can use wrapper classes like Integer or Double.
|
||||||
|
- The method must be deterministic for task reconstruction to behave correctly.
|
||||||
|
|
||||||
|
When the annotation is used for a class, the class becomes an actor class
|
||||||
|
(an encapsulation of state shared among many remote functions). The
|
||||||
|
member functions can be invoked using ``Ray.call``. The requirements for
|
||||||
|
an actor class are as follows.
|
||||||
|
|
||||||
|
- It must have a constructor without any parameters.
|
||||||
|
- Any inner class must be public static.
|
||||||
|
- It must not have a member field or method decorated using ``public static``,
|
||||||
|
as the semantic is undefined with multiple instances of this same class on
|
||||||
|
different machines
|
||||||
|
- An actor method must be decorated using ``public`` but not ``static``
|
||||||
|
- The other requirements are the same as for remote functions.
|
||||||
|
|
||||||
|
``Ray.call``
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Here is a simple example of invoking a remote function using ``Ray.call``.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
RayObject<R> call(Func func, ...);
|
||||||
|
|
||||||
|
Here, ``func`` is the target method and the ``...``'s should be filled in with
|
||||||
|
the arguments to ``func``. In addition, the following must hold.
|
||||||
|
|
||||||
|
- The return type of ``func`` must be ``R``.
|
||||||
|
- Currently at most 6 parameters of ``func`` are allowed.
|
||||||
|
- Each parameter must have the same type ``T`` as the corresponding parameter
|
||||||
|
to ``func``, or it must have the type ``RayObject<T>`` to indicate a result
|
||||||
|
from another ``Ray.call`` invocation.
|
||||||
|
|
||||||
|
The returned object is labeled as ``RayObject<R>`` and its value will be
|
||||||
|
put into the object store on the machine where the function call is executed.
|
||||||
|
|
||||||
|
``Ray.put``
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
You can also invoke ``Ray.put`` to explicitly place an object into the object
|
||||||
|
store.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public static <T> RayObject<T> put(T object);
|
||||||
|
public static <T, TM> RayObject<T> put(T obj, TM metadata);
|
||||||
|
|
||||||
|
``RayObject<T>.get/getMeta``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public class RayObject<T> {
|
||||||
|
public T get() throws TaskExecutionException;
|
||||||
|
public <M> M getMeta() throws TaskExecutionException;
|
||||||
|
}
|
||||||
|
|
||||||
|
This method blocks the current thread until the requested data is ready and has
|
||||||
|
been fetched (if necessary) from a remote machine.
|
||||||
|
|
||||||
|
``Ray.wait``
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Calling ``Ray.wait`` will block the current thread and wait for specified
|
||||||
|
ray calls. It returns when at least ``numReturns`` calls are completed,
|
||||||
|
or the ``timeout`` expires. See multi-value support for ``RayList``.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public static WaitResult<T> wait(RayList<T> waitfor, int numReturns, int timeout);
|
||||||
|
public static WaitResult<T> wait(RayList<T> waitfor, int numReturns);
|
||||||
|
public static WaitResult<T> wait(RayList<T> waitfor);
|
||||||
|
|
||||||
|
Multi-value API
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Multi-value Types
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Multiple ``RayObject``'s can be placed in a single data
|
||||||
|
structure as a return value or as a ``Ray.call`` parameter through the
|
||||||
|
following container types.
|
||||||
|
|
||||||
|
``MultipleReturnsX<R0, R1, ...>``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This consists of multiple heterogeneous values, with types ``R0``,
|
||||||
|
``R1``,... respectively. Currently this container type is only
|
||||||
|
supported as the return type of ``Ray.call``. Therefore you cannot use it
|
||||||
|
as the type of an input parameter.
|
||||||
|
|
||||||
|
``RayList<T>``
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This is a list of ``RayObject<T>``s, which inherits from ``List<T>`` in Java. It
|
||||||
|
can be used as the type for both a return value and a parameter value.
|
||||||
|
|
||||||
|
``RayMap<L, T>``
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A map of ``RayObject<T>``s with each indexed using a label with type
|
||||||
|
``L``, inherited from ``Map<L, T>``. It can be used as the type for both
|
||||||
|
a return value and a parameter value.
|
||||||
|
|
||||||
|
Enable multiple heterogeneous return values
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
At most four multiple heterogeneous return values are supported.
|
||||||
|
In order to let the runtime know the number of return values, we
|
||||||
|
supply the method of ``Ray.call_X`` as follows.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
RayObjects2<R0, R1> call_2(Func func, ...);
|
||||||
|
RayObjects3<R0, R1, R2> call_3(Func func, ...);
|
||||||
|
RayObjects4<R0, R1, R2, R3> call_4(Func func, ...);
|
||||||
|
|
||||||
|
Note ``func`` must match the following requirements.
|
||||||
|
|
||||||
|
- It must have a return value of type ``MultipleReturnsX``, and must be
|
||||||
|
invoked using the corresponding ``Ray.call_X``.
|
||||||
|
|
||||||
|
Here is an example.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public class MultiRExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Ray.init();
|
||||||
|
RayObjects2<Integer, String> refs = Ray.call_2(MultiRExample::sayMultiRet);
|
||||||
|
Integer obj1 = refs.r0().get();
|
||||||
|
String obj2 = refs.r1().get();
|
||||||
|
Assert.assertTrue(obj1.equals(123));
|
||||||
|
Assert.assertTrue(obj2.equals("123"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static MultipleReturns2<Integer, String> sayMultiRet() {
|
||||||
|
return new MultipleReturns2<Integer, String>(123, "123");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Return with ``RayList``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
We use ``Ray.call_n`` to do so, which is similar to ``Ray.call`` except it has
|
||||||
|
an additional parameter ``returnCount`` which specifies the number of return
|
||||||
|
``RayObject<R>``s in ``RayList<R>``. This is because Ray needs to know the
|
||||||
|
number of return values before the method is actually executed.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
RayList<R> call_n(Func func, Integer returnCount, ...);
|
||||||
|
|
||||||
|
Here is an example.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public class ListRExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Ray.init();
|
||||||
|
RayList<Integer> ns = Ray.call_n(ListRExample::sayList, 10, 10);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
RayObject<Integer> obj = ns.Get(i);
|
||||||
|
Assert.assertTrue(i == obj.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static List<Integer> sayList(Integer count) {
|
||||||
|
ArrayList<Integer> rets = new ArrayList<>();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
rets.add(i);
|
||||||
|
return rets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Return with ``RayMap``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This is similar to ``RayList`` case, except that now each return
|
||||||
|
``RayObject<R>`` in ``RayMap<L,R>`` has a given label when
|
||||||
|
``Ray.call_n`` is made.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
RayMap<L, R> call_n(Func func, Collection<L> returnLabels, ...);
|
||||||
|
|
||||||
|
Here is an example.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public class MapRExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Ray.init();
|
||||||
|
RayMap<Integer, String> ns = Ray.call_n(MapRExample::sayMap,
|
||||||
|
Arrays.asList(1, 2, 4, 3), "n_futures_");
|
||||||
|
for (Entry<Integer, RayObject<String>> ne : ns.EntrySet()) {
|
||||||
|
Integer key = ne.getKey();
|
||||||
|
RayObject<String> obj = ne.getValue();
|
||||||
|
Assert.assertTrue(obj.get().equals("n_futures_" + key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote(externalIO = true)
|
||||||
|
public static Map<Integer, String> sayMap(Collection<Integer> ids,
|
||||||
|
String prefix) {
|
||||||
|
Map<Integer, String> ret = new HashMap<>();
|
||||||
|
for (int id : ids) {
|
||||||
|
ret.put(id, prefix + id);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Enable ``RayList`` and ``RayMap`` as parameters
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
public class ListTExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Ray.init();
|
||||||
|
RayList<Integer> ints = new RayList<>();
|
||||||
|
ints.add(Ray.put(new Integer(1)));
|
||||||
|
ints.add(Ray.put(new Integer(1)));
|
||||||
|
ints.add(Ray.put(new Integer(1)));
|
||||||
|
RayObject<Integer> obj = Ray.call(ListTExample::sayReadRayList,
|
||||||
|
(List<Integer>)ints);
|
||||||
|
Assert.assertTrue(obj.get().equals(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static int sayReadRayList(List<Integer> ints) {
|
||||||
|
int sum = 0;
|
||||||
|
for (Integer i : ints) {
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor Support
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Create Actors
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A regular class annotated with ``@RayRemote`` is an actor class.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public class Adder {
|
||||||
|
public Adder() {
|
||||||
|
sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer add(Integer n) {
|
||||||
|
return sum += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
Whenever you call ``Ray.create()`` method, an actor will be created, and
|
||||||
|
you get a local ``RayActor`` of that actor as the return value.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
RayActor<Adder> adder = Ray.create(Adder.class);
|
||||||
|
|
||||||
|
Call Actor Methods
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The same ``Ray.call`` or its extended versions (e.g., ``Ray.call_n``) is
|
||||||
|
applied, except that the first argument becomes ``RayActor``.
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
RayObject<R> Ray.call(Func func, RayActor<Adder> actor, ...);
|
||||||
|
RayObject<Integer> result1 = Ray.call(Adder::add, adder, 1);
|
||||||
|
RayObject<Integer> result2 = Ray.call(Adder::add, adder, 10);
|
||||||
|
result2.get(); // 11
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
Install Ray for Java
|
||||||
|
====================
|
||||||
|
|
||||||
|
Ray works for Java 8 and above. Currently, we only support building Ray from source.
|
||||||
|
|
||||||
|
Build from source
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Install dependencies
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
First, make sure JDK 8 or above is installed on your machine. If not, you can download it from `here <http://www.oracle.com/technetwork/java/javase/downloads/index.html>`_.
|
||||||
|
|
||||||
|
Then install the following dependencies.
|
||||||
|
|
||||||
|
For Ubuntu users, run the following commands:
|
||||||
|
::
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y maven cmake pkg-config build-essential autoconf curl libtool unzip flex bison python # we install python here because python2 is required to build the webui
|
||||||
|
|
||||||
|
# If you are not using Anaconda, you need the following.
|
||||||
|
sudo apt-get install python-dev # For Python 2.
|
||||||
|
sudo apt-get install python3-dev # For Python 3.
|
||||||
|
|
||||||
|
# If you are on Ubuntu 14.04, you need the following.
|
||||||
|
pip install cmake
|
||||||
|
|
||||||
|
pip install cython
|
||||||
|
|
||||||
|
For macOS users, run the following commands:
|
||||||
|
::
|
||||||
|
|
||||||
|
brew update
|
||||||
|
brew install maven cmake pkg-config automake autoconf libtool openssl bison wget
|
||||||
|
|
||||||
|
pip install cython
|
||||||
|
|
||||||
|
Build Ray
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
Then we can start building Ray with the following commands:
|
||||||
|
::
|
||||||
|
|
||||||
|
git clone https://github.com/ray-project/ray.git
|
||||||
|
cd ray
|
||||||
|
|
||||||
|
# build native components
|
||||||
|
./build.sh -l java
|
||||||
|
|
||||||
|
# build java API
|
||||||
|
cd java
|
||||||
|
mvn clean install -Dmaven.test.skip
|
||||||
|
|
||||||
|
Run tests
|
||||||
|
^^^^^^^^^
|
||||||
|
::
|
||||||
|
|
||||||
|
# in `ray/java` directory
|
||||||
|
export RAY_CONFIG=ray.config.ini
|
||||||
|
mvn test
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
#first you should run the ../test.sh to build
|
|
||||||
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")"; pwd)
|
|
||||||
export RAY_CONFIG=$ROOT_DIR/../ray.config.ini
|
|
||||||
java -Djava.library.path=../../build/src/plasma:../../build/src/local_scheduler -cp .:target/ray-example-1.0.jar:lib/* org.ray.example.HelloWorld
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package org.ray.example;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import org.ray.api.Ray;
|
|
||||||
import org.ray.api.RayObject;
|
|
||||||
import org.ray.api.RayRemote;
|
|
||||||
import org.ray.core.RayRuntime;
|
|
||||||
import org.ray.util.logger.RayLog;
|
|
||||||
|
|
||||||
public class HelloWorld implements Serializable {
|
|
||||||
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public static String sayHello() {
|
|
||||||
String ret = "he";
|
|
||||||
ret += "llo";
|
|
||||||
RayLog.rapp.info("real say hello");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public static String sayWorld() {
|
|
||||||
String ret = "world";
|
|
||||||
ret += "!";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RayRemote
|
|
||||||
public static String merge(String hello, String world) {
|
|
||||||
return hello + "," + world;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
try {
|
|
||||||
Ray.init();
|
|
||||||
|
|
||||||
RayLog.rapp.info("HelloWorld.main() has " + args.length + " args");
|
|
||||||
for (String arg: args) {
|
|
||||||
RayLog.rapp.info("arg: " + arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
String helloWorld = HelloWorld.sayHelloWorld();
|
|
||||||
RayLog.rapp.info(helloWorld);
|
|
||||||
assert helloWorld.equals("hello,world!");
|
|
||||||
} catch (Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
RayRuntime.getInstance().cleanUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sayHelloWorld() {
|
|
||||||
RayObject<String> hello = Ray.call(HelloWorld::sayHello);
|
|
||||||
RayObject<String> world = Ray.call(HelloWorld::sayWorld);
|
|
||||||
return Ray.call(HelloWorld::merge, hello, world).get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
<module>runtime-dev</module>
|
<module>runtime-dev</module>
|
||||||
<module>cli</module>
|
<module>cli</module>
|
||||||
<module>test</module>
|
<module>test</module>
|
||||||
<module>example</module>
|
<module>tutorial</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
+2
-2
@@ -87,7 +87,7 @@ driver_args =
|
|||||||
%CONFIG_FILE_DIR%/runtime-native/target/classes =
|
%CONFIG_FILE_DIR%/runtime-native/target/classes =
|
||||||
%CONFIG_FILE_DIR%/runtime-native/target/test-classes =
|
%CONFIG_FILE_DIR%/runtime-native/target/test-classes =
|
||||||
|
|
||||||
%CONFIG_FILE_DIR%/example/target/classes =
|
%CONFIG_FILE_DIR%/tutorial/target/classes =
|
||||||
|
|
||||||
%CONFIG_FILE_DIR%/test/target/classes =
|
%CONFIG_FILE_DIR%/test/target/classes =
|
||||||
%CONFIG_FILE_DIR%/test/target/test-classes =
|
%CONFIG_FILE_DIR%/test/target/test-classes =
|
||||||
@@ -104,7 +104,7 @@ driver_args =
|
|||||||
%CONFIG_FILE_DIR%/test/target/test-classes =
|
%CONFIG_FILE_DIR%/test/target/test-classes =
|
||||||
%CONFIG_FILE_DIR%/test/lib/* =
|
%CONFIG_FILE_DIR%/test/lib/* =
|
||||||
|
|
||||||
%CONFIG_FILE_DIR%/example/target/ray-example-1.0.jar =
|
%CONFIG_FILE_DIR%/tutorial/target/ray-tutorial-1.0.jar =
|
||||||
|
|
||||||
[ray.java.path.classes.deploy]
|
[ray.java.path.classes.deploy]
|
||||||
%CONFIG_FILE_DIR%/java/lib/* =
|
%CONFIG_FILE_DIR%/java/lib/* =
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pushd example
|
|||||||
if [ ! -d "app1/" ];then
|
if [ ! -d "app1/" ];then
|
||||||
mkdir app1
|
mkdir app1
|
||||||
fi
|
fi
|
||||||
cp -rf target/ray-example-1.0.jar app1/
|
cp -rf target/ray-tutorial-1.0.jar app1/
|
||||||
zip -r app1.zip app1
|
zip -r app1.zip app1
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
Ray Java Tutorial
|
||||||
|
=================
|
||||||
|
|
||||||
|
- `Installation guide <https://github.com/ray-project/ray/tree/master/java/doc/installation.rst>`_
|
||||||
|
- `API document <https://github.com/ray-project/ray/tree/master/java/doc/api.rst>`_
|
||||||
|
|
||||||
|
Exercises
|
||||||
|
---------
|
||||||
|
|
||||||
|
Each file ``java/example/src/main/java/org/ray/exercise/Exercise*.java`` is a separate exercise.
|
||||||
|
To run a exercise case, set the ``RAY_CONFIG`` env variable and run the following command in ``ray/java/`` directory.
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
java -Djava.library.path=../build/src/plasma/:../build/src/local_scheduler/ -classpath "tutorial/target/ray-tutorial-1.0.jar:tutorial/lib/*" org.ray.exercise.Exercise01
|
||||||
|
|
||||||
|
`Exercise 1 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise01.java>`_: Define a remote function, and execute multiple remote functions in parallel.
|
||||||
|
|
||||||
|
`Exercise 2 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise02.java>`_: Execute remote functions in parallel with some dependencies.
|
||||||
|
|
||||||
|
`Exercise 3 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise03.java>`_: Call remote functions from within remote functions.
|
||||||
|
|
||||||
|
`Exercise 4 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise04.java>`_: Use ``Ray.wait`` to ignore stragglers.
|
||||||
|
|
||||||
|
`Exercise 5 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise05.java>`_: Use multiple heterogeneous return values.
|
||||||
|
|
||||||
|
`Exercise 6 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise06.java>`_: Usage of ``RayList<T>``.
|
||||||
|
|
||||||
|
`Exercise 7 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise07.java>`_: Usage of ``RayMap<L, T>``.
|
||||||
|
|
||||||
|
`Exercise 8 <https://github.com/ray-project/ray/tree/master/java/tutorial/src/main/java/org/ray/exercise/Exercise08.java>`_: Actor Support of create Actor and call Actor method.
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>org.ray</groupId>
|
<groupId>org.ray</groupId>
|
||||||
<artifactId>ray-example</artifactId>
|
<artifactId>ray-tutorial</artifactId>
|
||||||
|
|
||||||
<name>java example for ray</name>
|
<name>java tutorial</name>
|
||||||
<description>java example for ray</description>
|
<description>Tutorial of using Ray with Java</description>
|
||||||
<url></url>
|
<url></url>
|
||||||
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@@ -94,4 +94,4 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a remote function, and execute multiple remote functions in parallel.
|
||||||
|
*/
|
||||||
|
public class Exercise01 implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A plain remote function.
|
||||||
|
*/
|
||||||
|
// `@RayRemote` annotation converts a normal function to a remote function.
|
||||||
|
@RayRemote
|
||||||
|
public static String sayHello() {
|
||||||
|
String ret = "hello";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static String sayWorld() {
|
||||||
|
String ret = "world!";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try {
|
||||||
|
// Use `Ray.init` to initialize the Ray runtime.
|
||||||
|
Ray.init();
|
||||||
|
// Use `Ray.call` to call a remote function.
|
||||||
|
RayObject<String> hello = Ray.call(Exercise01::sayHello);
|
||||||
|
RayObject<String> world = Ray.call(Exercise01::sayWorld);
|
||||||
|
System.out.println("First remote call result:" + hello.get());
|
||||||
|
System.out.println("Second remote call result:" + world.get());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute remote functions in parallel with some dependencies.
|
||||||
|
*/
|
||||||
|
public class Exercise02 {
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static String sayHello() {
|
||||||
|
String ret = "hello";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static String sayWorld() {
|
||||||
|
String ret = "world!";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote function with dependency.
|
||||||
|
*/
|
||||||
|
@RayRemote
|
||||||
|
public static String merge(String hello, String world) {
|
||||||
|
return hello + "," + world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sayHelloWorld() {
|
||||||
|
RayObject<String> hello = Ray.call(Exercise02::sayHello);
|
||||||
|
RayObject<String> world = Ray.call(Exercise02::sayWorld);
|
||||||
|
// Pass unfinished results as the parameters to another remote function.
|
||||||
|
return Ray.call(Exercise02::merge, hello, world).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
String helloWorld = Exercise02.sayHelloWorld();
|
||||||
|
System.out.println(helloWorld);
|
||||||
|
assert helloWorld.equals("hello,world!");
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a remote function from within another remote function.
|
||||||
|
*/
|
||||||
|
public class Exercise03 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote function which will call another remote function.
|
||||||
|
*/
|
||||||
|
@RayRemote
|
||||||
|
public static String sayHelloWithWorld() {
|
||||||
|
String ret = "hello";
|
||||||
|
System.out.println(ret);
|
||||||
|
RayObject<String> world = Ray.call(Exercise03::sayWorld);
|
||||||
|
return ret + "," + world.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote function which will be called by another remote function.
|
||||||
|
*/
|
||||||
|
@RayRemote
|
||||||
|
public static String sayWorld() {
|
||||||
|
String ret = "world!";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
String helloWithWorld = Ray.call(Exercise03::sayHelloWithWorld).get();
|
||||||
|
System.out.println(helloWithWorld);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayList;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.api.WaitResult;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use Ray.wait to ignore stragglers
|
||||||
|
*/
|
||||||
|
public class Exercise04 {
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static String f1() {
|
||||||
|
String ret = "f1";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RayRemote
|
||||||
|
public static String f2() {
|
||||||
|
String ret = "f2";
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slow remote function.
|
||||||
|
*/
|
||||||
|
@RayRemote
|
||||||
|
public static String f3() {
|
||||||
|
String ret = "f3";
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000L);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
RayObject<String> o1 = Ray.call(Exercise04::f1);
|
||||||
|
RayObject<String> o2 = Ray.call(Exercise04::f2);
|
||||||
|
RayObject<String> o3 = Ray.call(Exercise04::f3);
|
||||||
|
RayList<String> rayList = new RayList<>();
|
||||||
|
rayList.add(o1);
|
||||||
|
rayList.add(o2);
|
||||||
|
rayList.add(o3);
|
||||||
|
// Ray.wait will block until specified number of results are ready
|
||||||
|
// or specified timeout have passed.
|
||||||
|
// In this case, the result of f3 will be ignored.
|
||||||
|
WaitResult<String> waitResult = Ray.wait(rayList, 2, 3000);
|
||||||
|
RayList<String> readyOnes = waitResult.getReadyOnes();
|
||||||
|
RayList<String> remainOnes = waitResult.getRemainOnes();
|
||||||
|
System.out.println("Number of readyOnes: " + readyOnes.size());
|
||||||
|
for (int i = 0; i < readyOnes.size(); i++) {
|
||||||
|
System.out.println("The value of readyOnes " + i + " is " + readyOnes.get(i));
|
||||||
|
}
|
||||||
|
System.out.println("Number of remainOnes: " + remainOnes.size());
|
||||||
|
for (int i = 0; i < remainOnes.size(); i++) {
|
||||||
|
System.out.println("The value of remainOnes " + i + " is " + remainOnes.get(i));
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.api.returns.MultipleReturns2;
|
||||||
|
import org.ray.api.returns.RayObjects2;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use multiple heterogeneous return values
|
||||||
|
* Java worker support at most four heterogeneous return values,
|
||||||
|
* To call such remote functions, use {@code Ray.call_X} as follows.
|
||||||
|
*/
|
||||||
|
public class Exercise05 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
RayObjects2<Integer, String> refs = Ray.call_2(Exercise05::sayMultiRet);
|
||||||
|
Integer obj1 = refs.r0().get();
|
||||||
|
String obj2 = refs.r1().get();
|
||||||
|
System.out.println(obj1);
|
||||||
|
System.out.println(obj2);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote function that returns multiple heterogeneous values.
|
||||||
|
*/
|
||||||
|
@RayRemote
|
||||||
|
public static MultipleReturns2<Integer, String> sayMultiRet() {
|
||||||
|
return new MultipleReturns2<Integer, String>(123, "123");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayList;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show usage of RayList.
|
||||||
|
* RayList is a list of {@code RayObject}s, inherited from {@code List}.
|
||||||
|
* It can be used as the type for both return values and parameters.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Exercise06 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
// The result is a `RayList`.
|
||||||
|
RayList<Integer> ns = Ray.call_n(Exercise06::sayList, 10, 10);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
RayObject<Integer> obj = ns.Get(i);
|
||||||
|
System.out.println(obj.get());
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote function that returns a list.
|
||||||
|
*/
|
||||||
|
@RayRemote
|
||||||
|
public static List<Integer> sayList(Integer count) {
|
||||||
|
ArrayList<Integer> rets = new ArrayList<>();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
rets.add(i);
|
||||||
|
}
|
||||||
|
return rets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayMap;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show usage of RayMap.
|
||||||
|
* {@code RayMap} is a map of {@code RayObject}s, inherited from {@code Map}.
|
||||||
|
* It can be used as the type for both return values and parameters.
|
||||||
|
*/
|
||||||
|
public class Exercise07 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
RayMap<Integer, String> ns = Ray.call_n(Exercise07::sayMap,
|
||||||
|
Arrays.asList(1, 2, 4, 3), "n_futures_");
|
||||||
|
for (Map.Entry<Integer, RayObject<String>> ne : ns.EntrySet()) {
|
||||||
|
Integer key = ne.getKey();
|
||||||
|
RayObject<String> obj = ne.getValue();
|
||||||
|
System.out.println(obj.get());
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote function that returns a map.
|
||||||
|
*/
|
||||||
|
@RayRemote()
|
||||||
|
public static Map<Integer, String> sayMap(Collection<Integer> ids, String prefix) {
|
||||||
|
Map<Integer, String> ret = new HashMap<>();
|
||||||
|
for (int id : ids) {
|
||||||
|
ret.put(id, prefix + id);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.ray.exercise;
|
||||||
|
|
||||||
|
import org.ray.api.Ray;
|
||||||
|
import org.ray.api.RayActor;
|
||||||
|
import org.ray.api.RayObject;
|
||||||
|
import org.ray.api.RayRemote;
|
||||||
|
import org.ray.core.RayRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show usage of actors.
|
||||||
|
*/
|
||||||
|
public class Exercise08 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
Ray.init();
|
||||||
|
// `Ray.create` creates an actor instance.
|
||||||
|
RayActor<Adder> adder = Ray.create(Adder.class);
|
||||||
|
// Use `Ray.call(actor, parameters)` to call an actor method.
|
||||||
|
RayObject<Integer> result1 = Ray.call(Adder::add, adder, 1);
|
||||||
|
RayObject<Integer> result2 = Ray.call(Adder::add, adder, 10);
|
||||||
|
System.out.println(result1.get());
|
||||||
|
System.out.println(result2.get());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
RayRuntime.getInstance().cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An example actor.
|
||||||
|
*/
|
||||||
|
// `@RayRemote` annotation also converts a normal class to an actor.
|
||||||
|
@RayRemote
|
||||||
|
public static class Adder {
|
||||||
|
|
||||||
|
public Adder() {
|
||||||
|
sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer add(Integer n) {
|
||||||
|
return sum += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user