[Java] Support calling functions returning void (#5494)

This commit is contained in:
Hao Chen
2019-08-23 21:10:15 +08:00
committed by GitHub
parent 7812dd5636
commit 239c177fe8
27 changed files with 1603 additions and 112 deletions
@@ -10,6 +10,7 @@ import org.ray.api.Ray;
import org.ray.api.RayActor;
import org.ray.api.RayObject;
import org.ray.api.annotation.RayRemote;
import org.ray.api.function.RayFunc1;
import org.ray.api.test.BaseTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +65,7 @@ public abstract class RayBenchmarkTest<T> extends BaseTest implements Serializab
long endTime = remoteResult.getFinishTime();
long costTime = endTime - temp.getStartTime();
counterList.add(costTime / 1000);
LOGGER.warn("{}_cost_time:{}ns",logPrefix, costTime);
LOGGER.warn("{}_cost_time:{}ns", logPrefix, costTime);
Assert.assertTrue(rayBenchmarkTest.checkResult(remoteResult.getResult()));
}
return counterList;
@@ -130,7 +131,13 @@ public abstract class RayBenchmarkTest<T> extends BaseTest implements Serializab
RayObject<List<Long>>[] rayObjects = new RayObject[clientNum];
for (int i = 0; i < clientNum; i++) {
rayObjects[i] = Ray.call(RayBenchmarkTest::singleClient, pressureTestParameter);
// Java compiler can't automatically infer the type of
// `RayBenchmarkTest::singleClient`, because `RayBenchmarkTest` is a generic class.
// It will match both `RayFunc1` and `RayFuncVoid1`. This looks like a bug or
// defect of the Java compiler.
// TODO(hchen): Figure out how to avoid manually declaring `RayFunc` type in this case.
RayFunc1<PressureTestParameter, List<Long>> func = RayBenchmarkTest::singleClient;
rayObjects[i] = Ray.call(func, pressureTestParameter);
}
for (int i = 0; i < clientNum; i++) {
List<Long> subCounterList = rayObjects[i].get();
@@ -32,7 +32,11 @@ public class ActorTest extends BaseTest {
return value;
}
public int increase(int delta) {
public void increase(int delta) {
value += delta;
}
public int increaseAndGet(int delta) {
value += delta;
return value;
}
@@ -45,7 +49,8 @@ public class ActorTest extends BaseTest {
Assert.assertNotEquals(actor.getId(), UniqueId.NIL);
// Test calling an actor
Assert.assertEquals(Integer.valueOf(1), Ray.call(Counter::getValue, actor).get());
Assert.assertEquals(Integer.valueOf(11), Ray.call(Counter::increase, actor, 10).get());
Ray.call(Counter::increase, actor, 1);
Assert.assertEquals(Integer.valueOf(3), Ray.call(Counter::increaseAndGet, actor, 1).get());
}
@RayRemote
@@ -64,19 +69,19 @@ public class ActorTest extends BaseTest {
@RayRemote
public static int testActorAsFirstParameter(RayActor<Counter> actor, int delta) {
RayObject<Integer> res = Ray.call(Counter::increase, actor, delta);
RayObject<Integer> res = Ray.call(Counter::increaseAndGet, actor, delta);
return res.get();
}
@RayRemote
public static int testActorAsSecondParameter(int delta, RayActor<Counter> actor) {
RayObject<Integer> res = Ray.call(Counter::increase, actor, delta);
RayObject<Integer> res = Ray.call(Counter::increaseAndGet, actor, delta);
return res.get();
}
@RayRemote
public static int testActorAsFieldOfParameter(List<RayActor<Counter>> actor, int delta) {
RayObject<Integer> res = Ray.call(Counter::increase, actor.get(0), delta);
RayObject<Integer> res = Ray.call(Counter::increaseAndGet, actor.get(0), delta);
return res.get();
}
@@ -96,9 +101,9 @@ public class ActorTest extends BaseTest {
public void testForkingActorHandle() {
TestUtils.skipTestUnderSingleProcess();
RayActor<Counter> counter = Ray.createActor(Counter::new, 100);
Assert.assertEquals(Integer.valueOf(101), Ray.call(Counter::increase, counter, 1).get());
Assert.assertEquals(Integer.valueOf(101), Ray.call(Counter::increaseAndGet, counter, 1).get());
RayActor<Counter> counter2 = ((NativeRayActor) counter).fork();
Assert.assertEquals(Integer.valueOf(103), Ray.call(Counter::increase, counter2, 2).get());
Assert.assertEquals(Integer.valueOf(103), Ray.call(Counter::increaseAndGet, counter2, 2).get());
}
@Test
@@ -18,14 +18,10 @@ public class PlasmaStoreTest extends BaseTest {
ObjectId objectId = ObjectId.fromRandom();
AbstractRayRuntime runtime = (AbstractRayRuntime) Ray.internal();
ObjectStore objectStore = runtime.getObjectStore();
objectStore.putRaw(new NativeRayObject(new byte[]{1}, null), objectId);
Assert.assertEquals(
objectStore.getRaw(Collections.singletonList(objectId), -1).get(0).data[0],
(byte) 1);
objectStore.putRaw(new NativeRayObject(new byte[]{2}, null), objectId);
// Putting 2 objects with duplicate ID should fail but ignored.
Assert.assertEquals(
objectStore.getRaw(Collections.singletonList(objectId), -1).get(0).data[0],
(byte) 1);
objectStore.put("1", objectId);
Assert.assertEquals(Ray.get(objectId), "1");
objectStore.put("2", objectId);
// Putting the second object with duplicate ID should fail but ignored.
Assert.assertEquals(Ray.get(objectId), "1");
}
}
@@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map;
import org.ray.api.Ray;
import org.ray.api.annotation.RayRemote;
import org.ray.api.id.ObjectId;
import org.ray.runtime.AbstractRayRuntime;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -66,6 +68,7 @@ public class RayCallTest extends BaseTest {
}
public static class LargeObject implements Serializable {
private byte[] data = new byte[1024 * 1024];
}
@@ -74,6 +77,12 @@ public class RayCallTest extends BaseTest {
return largeObject;
}
@RayRemote
private static void testNoReturn(ObjectId objectId) {
// Put an object in object store to inform driver that this function is executing.
((AbstractRayRuntime) Ray.internal()).getObjectStore().put(1, objectId);
}
/**
* Test calling and returning different types.
*/
@@ -93,6 +102,10 @@ public class RayCallTest extends BaseTest {
Assert.assertEquals(map, Ray.call(RayCallTest::testMap, map).get());
LargeObject largeObject = new LargeObject();
Assert.assertNotNull(Ray.call(RayCallTest::testLargeObject, largeObject).get());
ObjectId randomObjectId = ObjectId.fromRandom();
Ray.call(RayCallTest::testNoReturn, randomObjectId);
Assert.assertEquals(((int) Ray.get(randomObjectId)), 1);
}
@RayRemote