Files
ray-project--ray/python/ray/tests/test_implicit_resource.py
T
2026-07-13 13:17:40 +08:00

79 lines
2.2 KiB
Python

import sys
import time
import pytest
import ray
from ray.util.state import list_actors
def test_implicit_resource(ray_start_regular):
@ray.remote(num_cpus=1, resources={ray._raylet.IMPLICIT_RESOURCE_PREFIX + "a": 1})
class Actor:
def ping(self):
return ray.get_runtime_context().get_node_id()
# The first actor is schedulable.
a1 = Actor.remote()
ray.get(a1.ping.remote())
# The second actor will be pending since
# only one such actor can run on a single node.
a2 = Actor.remote()
time.sleep(2)
actors = list_actors(filters=[("actor_id", "=", a2._actor_id.hex())])
assert actors[0]["state"] == "PENDING_CREATION"
@pytest.mark.parametrize("autoscaler_v2", [False, True], ids=["v1", "v2"])
def test_implicit_resource_autoscaling(autoscaler_v2, shutdown_only):
from ray.cluster_utils import AutoscalingCluster
cluster = AutoscalingCluster(
head_resources={"CPU": 0},
worker_node_types={
"cpu_node": {
"resources": {
"CPU": 8,
},
"node_config": {},
"min_workers": 1,
"max_workers": 100,
},
},
autoscaler_v2=autoscaler_v2,
)
cluster.start()
ray.init()
@ray.remote(num_cpus=1, resources={ray._raylet.IMPLICIT_RESOURCE_PREFIX + "a": 0.5})
class Actor:
def ping(self):
return ray.get_runtime_context().get_node_id()
actors = [Actor.remote() for _ in range(2)]
for actor in actors:
ray.get(actor.ping.remote())
# No new worker nodes should be started.
assert len(ray.nodes()) == 2
# 3 more worker nodes should be started.
actors.extend([Actor.remote() for _ in range(5)])
node_id_to_num_actors = {}
for actor in actors:
node_id = ray.get(actor.ping.remote())
node_id_to_num_actors[node_id] = node_id_to_num_actors.get(node_id, 0) + 1
assert len(ray.nodes()) == 5
assert len(node_id_to_num_actors) == 4
num_actors_per_node = list(node_id_to_num_actors.values())
num_actors_per_node.sort()
assert num_actors_per_node == [1, 2, 2, 2]
cluster.shutdown()
if __name__ == "__main__":
sys.exit(pytest.main(["-sv", __file__]))