Skip to content

Commit

Permalink
[Core] Fix in-container memory limit fetching for cgroups v2 (ray-pro…
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkzinzow authored Apr 15, 2022
1 parent 92781c6 commit 166cd53
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
18 changes: 12 additions & 6 deletions python/ray/_private/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,12 @@ def open_log(path, unbuffered=False, **kwargs):
return stream


def get_system_memory():
def get_system_memory(
# For cgroups v1:
memory_limit_filename="/sys/fs/cgroup/memory/memory.limit_in_bytes",
# For cgroups v2:
memory_limit_filename_v2="/sys/fs/cgroup/memory.max",
):
"""Return the total amount of system memory in bytes.
Returns:
Expand All @@ -380,16 +385,17 @@ def get_system_memory():
# container. Note that this file is not specific to Docker and its value is
# often much larger than the actual amount of memory.
docker_limit = None
# For cgroups v1:
memory_limit_filename = "/sys/fs/cgroup/memory/memory.limit_in_bytes"
# For cgroups v2:
memory_limit_filename_v2 = "/sys/fs/cgroup/memory.max"
if os.path.exists(memory_limit_filename):
with open(memory_limit_filename, "r") as f:
docker_limit = int(f.read())
elif os.path.exists(memory_limit_filename_v2):
with open(memory_limit_filename_v2, "r") as f:
docker_limit = int(f.read())
max_file = f.read()
if max_file.isnumeric():
docker_limit = int(max_file)
else:
# max_file is "max", i.e. is unset.
docker_limit = None

# Use psutil if it is available.
psutil_memory_in_bytes = psutil.virtual_memory().total
Expand Down
52 changes: 52 additions & 0 deletions python/ray/tests/test_advanced_8.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import numpy as np
import pytest
import psutil

import ray
from ray.dashboard import k8s_utils
Expand Down Expand Up @@ -273,6 +274,57 @@ def initialized(self):
wait_for_condition(lambda: ray.available_resources()[resource_name] < quantity)


def test_get_system_memory():
# cgroups v1, set
with tempfile.NamedTemporaryFile("w") as memory_limit_file:
memory_limit_file.write("100")
memory_limit_file.flush()
assert (
ray._private.utils.get_system_memory(
memory_limit_filename=memory_limit_file.name,
memory_limit_filename_v2="__does_not_exist__",
)
== 100
)

# cgroups v1, high
with tempfile.NamedTemporaryFile("w") as memory_limit_file:
memory_limit_file.write(str(2 ** 64))
memory_limit_file.flush()
psutil_memory_in_bytes = psutil.virtual_memory().total
assert (
ray._private.utils.get_system_memory(
memory_limit_filename=memory_limit_file.name,
memory_limit_filename_v2="__does_not_exist__",
)
== psutil_memory_in_bytes
)
# cgroups v2, set
with tempfile.NamedTemporaryFile("w") as memory_max_file:
memory_max_file.write("100")
memory_max_file.flush()
assert (
ray._private.utils.get_system_memory(
memory_limit_filename="__does_not_exist__",
memory_limit_filename_v2=memory_max_file.name,
)
== 100
)

# cgroups v2, not set
with tempfile.NamedTemporaryFile("w") as memory_max_file:
memory_max_file.write("max")
memory_max_file.flush()
psutil_memory_in_bytes = psutil.virtual_memory().total
assert (
ray._private.utils.get_system_memory(
memory_limit_filename="__does_not_exist__",
memory_limit_filename_v2=memory_max_file.name,
)
== psutil_memory_in_bytes
)


@pytest.mark.skipif(sys.platform == "win32", reason="not relevant for windows")
def test_detect_docker_cpus():
# No limits set
Expand Down

0 comments on commit 166cd53

Please sign in to comment.