forked from ray-project/ray
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[tune] Use generic _ObjectCache for actor reuse (ray-project#33045)
Actor reuse is currently implemented within the RayTrialExecutor and tightly coupled to its concepts. To simplify the code, this PR introduces a new internal _ObjectCache class that generically caches objects (e.g. Actors+PGs) given a grouping key (e.g. resource requests). By moving the caching logic into a separate component, we can write better unit tests to ensure actor reuse works correctly and as expected. Signed-off-by: Kai Fricke <[email protected]> Signed-off-by: Kai Fricke <[email protected]>
- Loading branch information
Showing
6 changed files
with
332 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import pytest | ||
|
||
from ray.tune.utils.object_cache import _ObjectCache | ||
|
||
|
||
@pytest.mark.parametrize("eager", [False, True]) | ||
def test_no_may_keep_one(eager): | ||
"""Test object caching. | ||
- After init, no objects are cached (as max cached is 0), except when eager caching | ||
- After increasing max to 2, up to 2 objects are cached | ||
- Decreasing max objects will evict them on flush | ||
""" | ||
cache = _ObjectCache(may_keep_one=eager) | ||
|
||
# max(A) = 0, so we we only cache when eager caching | ||
assert cache.cache_object("A", 1) == eager | ||
assert cache.num_cached_objects == int(eager) | ||
|
||
# Set max(A) = 2 | ||
cache.increase_max("A", 2) | ||
|
||
# max(A) = 2, so we cache up to two objects | ||
if not eager: | ||
assert cache.cache_object("A", 1) | ||
|
||
assert cache.cache_object("A", 2) | ||
assert not cache.cache_object("A", 3) | ||
|
||
assert cache.num_cached_objects == 2 | ||
|
||
# Nothing has to be evicted | ||
assert not list(cache.flush_cached_objects()) | ||
|
||
# Set max(A) = 1, so we have one object too much | ||
cache.decrease_max("A", 1) | ||
|
||
# First cached object is evicted | ||
assert list(cache.flush_cached_objects()) == [1] | ||
assert cache.num_cached_objects == 1 | ||
|
||
# Set max(A) = 0 | ||
cache.decrease_max("A", 1) | ||
|
||
# Second cached object is evicted if not eager caching | ||
assert list(cache.flush_cached_objects()) == ([2] if not eager else []) | ||
assert cache.num_cached_objects == (0 if not eager else 1) | ||
|
||
|
||
@pytest.mark.parametrize("eager", [False, True]) | ||
def test_multi(eager): | ||
"""Test caching with multiple objects""" | ||
cache = _ObjectCache(may_keep_one=eager) | ||
|
||
# max(A) = 0, so we we only cache when eager caching | ||
assert cache.cache_object("A", 1) == eager | ||
assert cache.num_cached_objects == int(eager) | ||
|
||
# max(B) = 0, so no caching | ||
assert not cache.cache_object("B", 5) | ||
assert cache.num_cached_objects == int(eager) | ||
|
||
# Increase maximums levels | ||
cache.increase_max("A", 1) | ||
cache.increase_max("B", 1) | ||
|
||
# Cache objects (A is already cached if eager) | ||
assert cache.cache_object("A", 1) != eager | ||
assert cache.cache_object("B", 5) | ||
|
||
# No further objects can be cached | ||
assert not cache.cache_object("A", 2) | ||
assert not cache.cache_object("B", 6) | ||
|
||
assert cache.num_cached_objects == 2 | ||
|
||
# Decrease | ||
cache.decrease_max("A", 1) | ||
|
||
# Evict A object | ||
assert list(cache.flush_cached_objects()) == [1] | ||
|
||
cache.decrease_max("B", 1) | ||
|
||
# If eager, keep B object, otherwise, evict B | ||
assert list(cache.flush_cached_objects()) == ([5] if not eager else []) | ||
assert cache.num_cached_objects == (0 if not eager else 1) | ||
|
||
|
||
def test_multi_eager_other(): | ||
"""On eager caching, only cache an object if no other object is expected. | ||
- Expect up to one cached A object | ||
- Try to cache object B --> doesn't get cached | ||
- Remove expectation for A object | ||
- Try to cache object B --> get's cached | ||
""" | ||
cache = _ObjectCache(may_keep_one=True) | ||
|
||
cache.increase_max("A", 1) | ||
assert not cache.cache_object("B", 2) | ||
|
||
cache.decrease_max("A", 1) | ||
assert cache.cache_object("B", 3) | ||
|
||
|
||
@pytest.mark.parametrize("eager", [False, True]) | ||
def test_force_all(eager): | ||
"""Assert that force_all=True will always evict all object.""" | ||
cache = _ObjectCache(may_keep_one=eager) | ||
|
||
cache.increase_max("A", 2) | ||
|
||
assert cache.cache_object("A", 1) | ||
assert cache.cache_object("A", 2) | ||
|
||
assert list(cache.flush_cached_objects(force_all=True)) == [1, 2] | ||
assert cache.num_cached_objects == 0 | ||
|
||
|
||
if __name__ == "__main__": | ||
import sys | ||
|
||
sys.exit(pytest.main(["-v", __file__])) |
Oops, something went wrong.