chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
import os
|
||||
import sys
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
import ray
|
||||
from ray._private.accelerators import HPUAcceleratorManager, hpu
|
||||
from ray.util.placement_group import placement_group
|
||||
from ray.util.scheduling_strategies import PlacementGroupSchedulingStrategy
|
||||
|
||||
|
||||
def test_user_configured_more_than_visible(monkeypatch, call_ray_stop_only):
|
||||
# Test more hpus are configured than visible.
|
||||
monkeypatch.setenv("HABANA_VISIBLE_MODULES", "0,1,2")
|
||||
with pytest.raises(ValueError):
|
||||
ray.init(resources={"HPU": 4})
|
||||
|
||||
|
||||
@patch(
|
||||
"ray._private.accelerators.HPUAcceleratorManager.get_current_node_num_accelerators", # noqa: E501
|
||||
return_value=4,
|
||||
)
|
||||
def test_auto_detected_more_than_visible(
|
||||
mock_get_num_accelerators, monkeypatch, shutdown_only
|
||||
):
|
||||
# Test more hpus are detected than visible.
|
||||
monkeypatch.setenv("HABANA_VISIBLE_MODULES", "0,1,2")
|
||||
ray.init()
|
||||
_ = mock_get_num_accelerators.called
|
||||
assert ray.available_resources()["HPU"] == 3
|
||||
|
||||
|
||||
@patch(
|
||||
"ray._private.accelerators.HPUAcceleratorManager.get_current_node_num_accelerators", # noqa: E501
|
||||
return_value=2,
|
||||
)
|
||||
def test_auto_detect_resources(mock_get_num_accelerators, shutdown_only):
|
||||
# Test that ray node resources are filled with auto detected count.
|
||||
ray.init()
|
||||
_ = mock_get_num_accelerators.called
|
||||
assert ray.available_resources()["HPU"] == 2
|
||||
|
||||
|
||||
def test_get_current_process_visible_accelerator_ids():
|
||||
os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR] = "0,1,2"
|
||||
assert HPUAcceleratorManager.get_current_process_visible_accelerator_ids() == [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
] # noqa: E501
|
||||
|
||||
del os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR]
|
||||
assert HPUAcceleratorManager.get_current_process_visible_accelerator_ids() is None
|
||||
|
||||
os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR] = ""
|
||||
assert HPUAcceleratorManager.get_current_process_visible_accelerator_ids() == []
|
||||
|
||||
del os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR]
|
||||
|
||||
|
||||
def test_set_current_process_visible_accelerator_ids():
|
||||
HPUAcceleratorManager.set_current_process_visible_accelerator_ids(["0"])
|
||||
assert os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR] == "0"
|
||||
|
||||
HPUAcceleratorManager.set_current_process_visible_accelerator_ids(["0", "1"])
|
||||
assert os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR] == "0,1"
|
||||
|
||||
HPUAcceleratorManager.set_current_process_visible_accelerator_ids(["0", "1", "2"])
|
||||
assert os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR] == "0,1,2"
|
||||
|
||||
del os.environ[hpu.HABANA_VISIBLE_DEVICES_ENV_VAR]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_config",
|
||||
[
|
||||
(1, False),
|
||||
(0.5, True),
|
||||
(3, False),
|
||||
],
|
||||
)
|
||||
def test_validate_resource_request_quantity(test_config):
|
||||
num_hpus, expect_error = test_config
|
||||
|
||||
if expect_error:
|
||||
assert (
|
||||
HPUAcceleratorManager.validate_resource_request_quantity(num_hpus)[0]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
HPUAcceleratorManager.validate_resource_request_quantity(num_hpus)[1]
|
||||
is not None
|
||||
)
|
||||
else:
|
||||
assert (
|
||||
HPUAcceleratorManager.validate_resource_request_quantity(num_hpus)[0]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
HPUAcceleratorManager.validate_resource_request_quantity(num_hpus)[1]
|
||||
is None
|
||||
)
|
||||
|
||||
|
||||
def test_check_accelerator_info():
|
||||
|
||||
if HPUAcceleratorManager.is_initialized():
|
||||
assert (
|
||||
"Intel-GAUDI" in HPUAcceleratorManager.get_current_node_accelerator_type()
|
||||
)
|
||||
else:
|
||||
assert HPUAcceleratorManager.get_current_node_accelerator_type() is None
|
||||
|
||||
assert HPUAcceleratorManager.get_resource_name() == "HPU"
|
||||
|
||||
|
||||
def test_decorator_args():
|
||||
|
||||
# This is a valid way of using the decorator.
|
||||
@ray.remote(resources={"HPU": 1}) # noqa: F811
|
||||
class Actor: # noqa: F811
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
# This is a valid way of using the decorator.
|
||||
@ray.remote(num_cpus=1, resources={"HPU": 1}) # noqa: F811
|
||||
class Actor: # noqa: F811
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
def test_actor_deletion_with_hpus(shutdown_only):
|
||||
ray.init(num_cpus=1, resources={"HPU": 1})
|
||||
|
||||
# When an actor that uses an HPU exits, make sure that the HPU resources
|
||||
# are released.
|
||||
|
||||
@ray.remote(resources={"HPU": 1})
|
||||
class Actor:
|
||||
def getpid(self):
|
||||
return os.getpid()
|
||||
|
||||
for _ in range(5):
|
||||
# If we can successfully create an actor, that means that enough
|
||||
# HPU resources are available.
|
||||
a = Actor.remote()
|
||||
ray.get(a.getpid.remote())
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform == "win32", reason="Failing on Windows.")
|
||||
def test_actor_hpus(ray_start_cluster):
|
||||
cluster = ray_start_cluster
|
||||
num_nodes = 2
|
||||
num_hpus_per_raylet = 2
|
||||
for i in range(num_nodes):
|
||||
cluster.add_node(num_cpus=10 * 2, resources={"HPU": num_hpus_per_raylet})
|
||||
ray.init(address=cluster.address)
|
||||
|
||||
@ray.remote(resources={"HPU": 1})
|
||||
class Actor1:
|
||||
def __init__(self):
|
||||
resource_ids = ray.get_runtime_context().get_accelerator_ids()
|
||||
self.hpu_ids = resource_ids.get("HPU")
|
||||
|
||||
def get_location_and_ids(self):
|
||||
return (
|
||||
ray.get_runtime_context().get_node_id(),
|
||||
tuple(self.hpu_ids),
|
||||
)
|
||||
|
||||
# Create one actor per HPU.
|
||||
actors = [Actor1.remote() for _ in range(num_nodes * num_hpus_per_raylet)]
|
||||
# Make sure that no two actors are assigned to the same HPU.
|
||||
locations_and_ids = ray.get(
|
||||
[actor.get_location_and_ids.remote() for actor in actors]
|
||||
)
|
||||
node_names = {location for location, hpu_id in locations_and_ids}
|
||||
assert len(node_names) == num_nodes
|
||||
location_actor_combinations = []
|
||||
for node_name in node_names:
|
||||
for hpu_id in range(num_hpus_per_raylet):
|
||||
location_actor_combinations.append((node_name, (f"{hpu_id}",)))
|
||||
|
||||
assert set(locations_and_ids) == set(location_actor_combinations)
|
||||
|
||||
# Creating a new actor should fail because all of the HPUs are being
|
||||
# used.
|
||||
a = Actor1.remote()
|
||||
ready_ids, _ = ray.wait([a.get_location_and_ids.remote()], timeout=0.01)
|
||||
assert ready_ids == []
|
||||
|
||||
|
||||
def test_actor_habana_visible_devices(shutdown_only):
|
||||
"""Test user can overwrite HABANA_VISIBLE_MODULES
|
||||
after the actor is created."""
|
||||
ray.init(resources={"HPU": 1})
|
||||
|
||||
@ray.remote(resources={"HPU": 1})
|
||||
class Actor:
|
||||
def set_habana_visible_devices(self, habana_visible_devices):
|
||||
os.environ["HABANA_VISIBLE_MODULES"] = habana_visible_devices
|
||||
|
||||
def get_habana_visible_devices(self):
|
||||
return os.environ["HABANA_VISIBLE_MODULES"]
|
||||
|
||||
actor = Actor.remote()
|
||||
assert ray.get(actor.get_habana_visible_devices.remote()) == "0"
|
||||
ray.get(actor.set_habana_visible_devices.remote("0,1"))
|
||||
assert ray.get(actor.get_habana_visible_devices.remote()) == "0,1"
|
||||
|
||||
|
||||
def test_hpu_ids(shutdown_only):
|
||||
num_hpus = 3
|
||||
ray.init(num_cpus=num_hpus, resources={"HPU": num_hpus})
|
||||
|
||||
def get_hpu_ids(hpus_per_worker):
|
||||
hpu_ids = ray.get_runtime_context().get_accelerator_ids()["HPU"]
|
||||
assert len(hpu_ids) == hpus_per_worker
|
||||
modules = os.environ.get("HABANA_VISIBLE_MODULES")
|
||||
if modules is not None:
|
||||
assert modules == ",".join([str(i) for i in hpu_ids]) # noqa
|
||||
for hpu_id in hpu_ids:
|
||||
assert hpu_id in [str(i) for i in range(num_hpus)]
|
||||
return hpu_ids
|
||||
|
||||
f0 = ray.remote(resources={"HPU": 0})(lambda: get_hpu_ids(0))
|
||||
f1 = ray.remote(resources={"HPU": 1})(lambda: get_hpu_ids(1))
|
||||
|
||||
list_of_ids = ray.get([f0.remote() for _ in range(10)])
|
||||
assert list_of_ids == 10 * [[]]
|
||||
ray.get([f1.remote() for _ in range(10)])
|
||||
|
||||
# Test that actors have HABANA_VISIBLE_MODULES set properly.
|
||||
|
||||
def _check_hpu_env(expected_num_hpus):
|
||||
hpu_ids = ray.get_runtime_context().get_accelerator_ids()["HPU"]
|
||||
assert len(hpu_ids) == expected_num_hpus
|
||||
if expected_num_hpus > 0:
|
||||
assert os.environ["HABANA_VISIBLE_MODULES"] == ",".join(
|
||||
[str(i) for i in hpu_ids] # noqa
|
||||
)
|
||||
else:
|
||||
assert os.environ.get("HABANA_VISIBLE_MODULES") is None
|
||||
|
||||
@ray.remote
|
||||
class Actor:
|
||||
def __init__(self, num_hpus):
|
||||
self.num_hpus = num_hpus
|
||||
_check_hpu_env(num_hpus)
|
||||
self.x = num_hpus
|
||||
|
||||
def test(self):
|
||||
_check_hpu_env(self.num_hpus)
|
||||
return self.x
|
||||
|
||||
a0 = Actor.remote(0)
|
||||
assert ray.get(a0.test.remote()) == 0
|
||||
|
||||
a1 = Actor.options(resources={"HPU": 1}).remote(1)
|
||||
assert ray.get(a1.test.remote()) == 1
|
||||
|
||||
|
||||
def test_hpu_with_placement_group(shutdown_only):
|
||||
num_hpus = 2
|
||||
ray.init(num_cpus=1, resources={"HPU": num_hpus})
|
||||
|
||||
@ray.remote(resources={"HPU": num_hpus})
|
||||
class HPUActor:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def ready(self):
|
||||
hpu_ids = ray.get_runtime_context().get_accelerator_ids()["HPU"]
|
||||
assert len(hpu_ids) == num_hpus
|
||||
assert os.environ["HABANA_VISIBLE_MODULES"] == ",".join(
|
||||
[str(i) for i in hpu_ids] # noqa
|
||||
)
|
||||
|
||||
# Reserve a placement group of 1 bundle that reserves 1 CPU and 2 HPU.
|
||||
pg = placement_group([{"CPU": 1, "HPU": num_hpus}])
|
||||
|
||||
# Wait until placement group is created.
|
||||
ray.get(pg.ready(), timeout=10)
|
||||
|
||||
actor = HPUActor.options(
|
||||
scheduling_strategy=PlacementGroupSchedulingStrategy(
|
||||
placement_group=pg,
|
||||
)
|
||||
).remote()
|
||||
|
||||
ray.get(actor.ready.remote(), timeout=10)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main(["-sv", __file__]))
|
||||
Reference in New Issue
Block a user