def test_delete_refs_on_disconnect(ray_start_regular): with ray_start_client_server() as ray: @ray.remote def f(x): return x + 2 thing1 = f.remote(6) # noqa thing2 = ray.put("Hello World") # noqa # One put, one function -- the function result thing1 is # in a different category, according to the raylet. assert len(real_ray.objects()) == 2 # But we're maintaining the reference assert server_object_ref_count(3)() # And can get the data assert ray.get(thing1) == 8 # Close the client ray.close() wait_for_condition(server_object_ref_count(0), timeout=5) def test_cond(): return len(real_ray.objects()) == 0 wait_for_condition(test_cond, timeout=5)
def test_wait(ray_start_regular_shared): with ray_start_client_server() as ray: objectref = ray.put("hello world") ready, remaining = ray.wait([objectref]) assert remaining == [] retval = ray.get(ready[0]) assert retval == "hello world" objectref2 = ray.put(5) ready, remaining = ray.wait([objectref, objectref2]) assert (ready, remaining) == ([objectref], [objectref2]) or \ (ready, remaining) == ([objectref2], [objectref]) ready_retval = ray.get(ready[0]) remaining_retval = ray.get(remaining[0]) assert (ready_retval, remaining_retval) == ("hello world", 5) \ or (ready_retval, remaining_retval) == (5, "hello world") with pytest.raises(Exception): # Reference not in the object store. ray.wait([ClientObjectRef("blabla")]) with pytest.raises(TypeError): ray.wait("blabla") with pytest.raises(TypeError): ray.wait(ClientObjectRef("blabla")) with pytest.raises(TypeError): ray.wait(["blabla"])
def test_delete_actor_on_disconnect(ray_start_regular): with ray_start_client_server() as ray: @ray.remote class Accumulator: def __init__(self): self.acc = 0 def inc(self): self.acc += 1 def get(self): return self.acc actor = Accumulator.remote() actor.inc.remote() assert server_actor_ref_count(1)() assert ray.get(actor.get.remote()) == 1 ray.close() wait_for_condition(server_actor_ref_count(0), timeout=5) def test_cond(): alive_actors = [ v for v in real_ray.actors().values() if v["State"] != ActorTableData.DEAD ] return len(alive_actors) == 0 wait_for_condition(test_cond, timeout=10)
def test_put_get(ray_start_regular_shared): with ray_start_client_server() as ray: objectref = ray.put("hello world") print(objectref) retval = ray.get(objectref) assert retval == "hello world"
def test_basic_named_actor(ray_start_regular_shared): """Test that ray.get_actor() can create and return a detached actor. """ with ray_start_client_server() as ray: @ray.remote class Accumulator: def __init__(self): self.x = 0 def inc(self): self.x += 1 def get(self): return self.x # Create the actor actor = Accumulator.options(name="test_acc").remote() actor.inc.remote() actor.inc.remote() del actor new_actor = ray.get_actor("test_acc") new_actor.inc.remote() assert ray.get(new_actor.get.remote()) == 3
def main(): system_config = {"put_small_object_in_memory_store": True} with ray_setup_and_teardown( logging_level=logging.WARNING, _system_config=system_config): for name, obj in inspect.getmembers(sys.modules[__name__]): if not name.startswith("benchmark_"): continue with ray_start_client_server() as ray: obj(ray)
def test_delete_ref_on_object_deletion(ray_start_regular): with ray_start_client_server() as ray: vals = { "ref": ray.put("Hello World"), "ref2": ray.put("This value stays"), } del vals["ref"] wait_for_condition(server_object_ref_count(1), timeout=5)
def test_nested_function(ray_start_regular_shared): with ray_start_client_server() as ray: @ray.remote def g(): @ray.remote def f(): return "OK" return ray.get(f.remote()) assert ray.get(g.remote()) == "OK"
def test_kill_actor_immediately_after_creation(ray_start_regular): with ray_start_client_server() as ray: @ray.remote class A: pass a = A.remote() b = A.remote() ray.kill(a) ray.kill(b) wait_for_condition(_all_actors_dead(ray), timeout=10)
def test_function_calling_function(ray_start_regular_shared): with ray_start_client_server() as ray: @ray.remote def g(): return "OK" @ray.remote def f(): print(f, g) return ray.get(g.remote()) print(f, type(f)) assert ray.get(f.remote()) == "OK"
def test_real_ray_fallback(ray_start_regular_shared): with ray_start_client_server() as ray: @ray.remote def get_nodes_real(): import ray as real_ray return real_ray.nodes() nodes = ray.get(get_nodes_real.remote()) assert len(nodes) == 1, nodes @ray.remote def get_nodes(): # Can access the full Ray API in remote methods. return ray.nodes() nodes = ray.get(get_nodes.remote()) assert len(nodes) == 1, nodes
def test_basic_log_stream(ray_start_regular_shared): with ray_start_client_server() as ray: log_msgs = [] def test_log(level, msg): log_msgs.append(msg) ray.worker.log_client.log = test_log ray.worker.log_client.set_logstream_level(logging.DEBUG) # Allow some time to propogate time.sleep(1) x = ray.put("Foo") assert ray.get(x) == "Foo" time.sleep(1) logs_with_id = [msg for msg in log_msgs if msg.find(x.id.hex()) >= 0] assert len(logs_with_id) >= 2 assert any((msg.find("get") >= 0 for msg in logs_with_id)) assert any((msg.find("put") >= 0 for msg in logs_with_id))
def test_basic_actor(ray_start_regular_shared): with ray_start_client_server() as ray: @ray.remote class HelloActor: def __init__(self): self.count = 0 def say_hello(self, whom): self.count += 1 return ("Hello " + whom, self.count) actor = HelloActor.remote() s, count = ray.get(actor.say_hello.remote("you")) assert s == "Hello you" assert count == 1 s, count = ray.get(actor.say_hello.remote("world")) assert s == "Hello world" assert count == 2
def test_stdout_log_stream(ray_start_regular_shared): with ray_start_client_server() as ray: log_msgs = [] def test_log(level, msg): log_msgs.append(msg) ray.worker.log_client.stdstream = test_log @ray.remote def print_on_stderr_and_stdout(s): print(s) print(s, file=sys.stderr) time.sleep(1) print_on_stderr_and_stdout.remote("Hello world") time.sleep(1) assert len(log_msgs) == 2 assert all((msg.find("Hello world") for msg in log_msgs))
def test_simple_multiple_references(ray_start_regular): with ray_start_client_server() as ray: @ray.remote class A: def __init__(self): self.x = ray.put("hi") def get(self): return [self.x] a = A.remote() ref1 = ray.get(a.get.remote())[0] ref2 = ray.get(a.get.remote())[0] del a assert ray.get(ref1) == "hi" del ref1 assert ray.get(ref2) == "hi" del ref2
def test_remote_functions(ray_start_regular_shared): with ray_start_client_server() as ray: @ray.remote def plus2(x): return x + 2 @ray.remote def fact(x): print(x, type(fact)) if x <= 0: return 1 # This hits the "nested tasks" issue # https://github.com/ray-project/ray/issues/3644 # So we're on the right track! return ray.get(fact.remote(x - 1)) * x ref2 = plus2.remote(234) # `236` assert ray.get(ref2) == 236 ref3 = fact.remote(20) # `2432902008176640000` assert ray.get(ref3) == 2_432_902_008_176_640_000 # Reuse the cached ClientRemoteFunc object ref4 = fact.remote(5) assert ray.get(ref4) == 120 # Test ray.wait() ref5 = fact.remote(10) # should return ref2, ref3, ref4 res = ray.wait([ref5, ref2, ref3, ref4], num_returns=3) assert [ref2, ref3, ref4] == res[0] assert [ref5] == res[1] assert ray.get(res[0]) == [236, 2_432_902_008_176_640_000, 120] # should return ref2, ref3, ref4, ref5 res = ray.wait([ref2, ref3, ref4, ref5], num_returns=4) assert [ref2, ref3, ref4, ref5] == res[0] assert [] == res[1] all_vals = ray.get(res[0]) assert all_vals == [236, 2_432_902_008_176_640_000, 120, 3628800]
def test_get_ray_metadata(ray_start_regular_shared): """Test the ClusterInfo client data pathway and API surface """ with ray_start_client_server() as ray: ip_address = ray_start_regular_shared["node_ip_address"] initialized = ray.is_initialized() assert initialized nodes = ray.nodes() assert len(nodes) == 1, nodes assert nodes[0]["NodeManagerAddress"] == ip_address current_node_id = "node:" + ip_address cluster_resources = ray.cluster_resources() available_resources = ray.available_resources() assert cluster_resources["CPU"] == 1.0 assert current_node_id in cluster_resources assert current_node_id in available_resources
def test_delete_actor(ray_start_regular): with ray_start_client_server() as ray: @ray.remote class Accumulator: def __init__(self): self.acc = 0 def inc(self): self.acc += 1 actor = Accumulator.remote() actor.inc.remote() actor2 = Accumulator.remote() actor2.inc.remote() assert server_actor_ref_count(2)() del actor wait_for_condition(server_actor_ref_count(1), timeout=5)
def test_cancel_chain(ray_start_regular, use_force): with ray_start_client_server() as ray: SignalActor = create_remote_signal_actor(ray) signaler = SignalActor.remote() @ray.remote def wait_for(t): return ray.get(t[0]) obj1 = wait_for.remote([signaler.wait.remote()]) obj2 = wait_for.remote([obj1]) obj3 = wait_for.remote([obj2]) obj4 = wait_for.remote([obj3]) assert len(ray.wait([obj1], timeout=.1)[0]) == 0 ray.cancel(obj1, force=use_force) for ob in [obj1, obj2, obj3, obj4]: with pytest.raises(valid_exceptions(use_force)): ray.get(ob) signaler2 = SignalActor.remote() obj1 = wait_for.remote([signaler2.wait.remote()]) obj2 = wait_for.remote([obj1]) obj3 = wait_for.remote([obj2]) obj4 = wait_for.remote([obj3]) assert len(ray.wait([obj3], timeout=.1)[0]) == 0 ray.cancel(obj3, force=use_force) for ob in [obj3, obj4]: with pytest.raises(valid_exceptions(use_force)): ray.get(ob) with pytest.raises(GetTimeoutError): ray.get(obj1, timeout=.1) with pytest.raises(GetTimeoutError): ray.get(obj2, timeout=.1) signaler2.send.remote() ray.get(obj1)
def test_create_remote_before_start(ray_start_regular_shared): """Creates remote objects (as though in a library) before starting the client. """ from ray.experimental.client import ray @ray.remote class Returner: def doit(self): return "foo" @ray.remote def f(x): return x + 20 # Prints in verbose tests print("Created remote functions") with ray_start_client_server() as ray: assert ray.get(f.remote(3)) == 23 a = Returner.remote() assert ray.get(a.doit.remote()) == "foo"
def test_pass_handles(ray_start_regular_shared): """Test that passing client handles to actors and functions to remote actors in functions (on the server or raylet side) works transparently to the caller. """ with ray_start_client_server() as ray: @ray.remote class ExecActor: def exec(self, f, x): return ray.get(f.remote(x)) def exec_exec(self, actor, f, x): return ray.get(actor.exec.remote(f, x)) @ray.remote def fact(x): out = 1 while x > 0: out = out * x x -= 1 return out @ray.remote def func_exec(f, x): return ray.get(f.remote(x)) @ray.remote def func_actor_exec(actor, f, x): return ray.get(actor.exec.remote(f, x)) @ray.remote def sneaky_func_exec(obj, x): return ray.get(obj["f"].remote(x)) @ray.remote def sneaky_actor_exec(obj, x): return ray.get(obj["actor"].exec.remote(obj["f"], x)) def local_fact(x): if x <= 0: return 1 return x * local_fact(x - 1) assert ray.get(fact.remote(7)) == local_fact(7) assert ray.get(func_exec.remote(fact, 8)) == local_fact(8) test_obj = {} test_obj["f"] = fact assert ray.get(sneaky_func_exec.remote(test_obj, 5)) == local_fact(5) actor_handle = ExecActor.remote() assert ray.get(actor_handle.exec.remote(fact, 7)) == local_fact(7) assert ray.get(func_actor_exec.remote(actor_handle, fact, 10)) == local_fact(10) second_actor = ExecActor.remote() assert ray.get(actor_handle.exec_exec.remote(second_actor, fact, 9)) == local_fact(9) test_actor_obj = {} test_actor_obj["actor"] = second_actor test_actor_obj["f"] = fact assert ray.get(sneaky_actor_exec.remote(test_actor_obj, 4)) == local_fact(4)