129 lines
3.3 KiB
Python
129 lines
3.3 KiB
Python
"""Tests for GPU selection utilities."""
|
|||
|
|
|
||
|
|
import os
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from mjlab.utils.gpu import select_gpus
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture(autouse=True)
|
||
|
|
def clean_cuda_env():
|
||
|
|
"""Clean CUDA_VISIBLE_DEVICES before each test."""
|
||
|
|
original = os.environ.get("CUDA_VISIBLE_DEVICES")
|
||
|
|
yield
|
||
|
|
# Restore original value after test.
|
||
|
|
if original is None:
|
||
|
|
os.environ.pop("CUDA_VISIBLE_DEVICES", None)
|
||
|
|
else:
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = original
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_with_visible_devices_set():
|
||
|
|
"""Respects CUDA_VISIBLE_DEVICES when selecting GPUs."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2,3"
|
||
|
|
|
||
|
|
# Select first two GPUs (indices 0, 1 -> physical GPUs 0, 1).
|
||
|
|
selected, num = select_gpus([0, 1])
|
||
|
|
assert selected == [0, 1]
|
||
|
|
assert num == 2
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_with_non_contiguous_devices():
|
||
|
|
"""Handles non-contiguous CUDA_VISIBLE_DEVICES correctly."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "1,3,5"
|
||
|
|
|
||
|
|
# Index 0 -> physical GPU 1.
|
||
|
|
selected, num = select_gpus([0])
|
||
|
|
assert selected == [1]
|
||
|
|
assert num == 1
|
||
|
|
|
||
|
|
# Index 1 -> physical GPU 3.
|
||
|
|
selected, num = select_gpus([1])
|
||
|
|
assert selected == [3]
|
||
|
|
assert num == 1
|
||
|
|
|
||
|
|
# Indices 0, 2 -> physical GPUs 1, 5.
|
||
|
|
selected, num = select_gpus([0, 2])
|
||
|
|
assert selected == [1, 5]
|
||
|
|
assert num == 2
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_all_option():
|
||
|
|
"""Selects all GPUs when 'all' is specified."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "2,4,6"
|
||
|
|
|
||
|
|
selected, num = select_gpus("all")
|
||
|
|
assert selected == [2, 4, 6]
|
||
|
|
assert num == 3
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_single_gpu():
|
||
|
|
"""Correctly selects a single GPU."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"
|
||
|
|
|
||
|
|
selected, num = select_gpus([0])
|
||
|
|
assert selected == [0]
|
||
|
|
assert num == 1
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_with_spaces():
|
||
|
|
"""Handles CUDA_VISIBLE_DEVICES with spaces correctly."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = " 0 , 1 , 2 "
|
||
|
|
|
||
|
|
selected, num = select_gpus([1, 2])
|
||
|
|
assert selected == [1, 2]
|
||
|
|
assert num == 2
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_empty_segments():
|
||
|
|
"""Handles empty segments in CUDA_VISIBLE_DEVICES."""
|
||
|
|
# This can happen with malformed environment variables.
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "0,,2"
|
||
|
|
|
||
|
|
selected, num = select_gpus([0, 1])
|
||
|
|
assert selected == [0, 2]
|
||
|
|
assert num == 2
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_respects_user_order():
|
||
|
|
"""Preserves the order specified by the user."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2,3"
|
||
|
|
|
||
|
|
# User requests in reverse order.
|
||
|
|
selected, num = select_gpus([3, 2, 1, 0])
|
||
|
|
assert selected == [3, 2, 1, 0]
|
||
|
|
assert num == 4
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_cpu_mode_explicit():
|
||
|
|
"""Selects CPU mode when None is specified."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"
|
||
|
|
|
||
|
|
selected, num = select_gpus(None)
|
||
|
|
assert selected is None
|
||
|
|
assert num == 0
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_cpu_mode_empty_cuda_visible_devices():
|
||
|
|
"""Selects CPU mode when CUDA_VISIBLE_DEVICES is empty."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = ""
|
||
|
|
|
||
|
|
# Should return CPU mode (None, 0) since no GPUs are visible.
|
||
|
|
selected, num = select_gpus([0])
|
||
|
|
assert selected is None
|
||
|
|
assert num == 0
|
||
|
|
|
||
|
|
|
||
|
|
def test_select_gpus_mig_uuids():
|
||
|
|
"""Handles MIG GPU UUIDs in CUDA_VISIBLE_DEVICES."""
|
||
|
|
os.environ["CUDA_VISIBLE_DEVICES"] = "MIG-GPU-abc-123,MIG-GPU-def-456"
|
||
|
|
|
||
|
|
selected, num = select_gpus("all")
|
||
|
|
assert selected == ["MIG-GPU-abc-123", "MIG-GPU-def-456"]
|
||
|
|
assert num == 2
|
||
|
|
|
||
|
|
selected, num = select_gpus([0])
|
||
|
|
assert selected == ["MIG-GPU-abc-123"]
|
||
|
|
assert num == 1
|