File size: 3,875 Bytes
784f572
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import json
import subprocess
import sys
from pathlib import Path

import pytest

from dlb.gpu_matrix import active_gpus
from dlb.matrix import MatrixTask, write_matrix


ROOT = Path(__file__).parents[1]


def _task(index: int) -> MatrixTask:
    steps = 2**index
    return MatrixTask(
        task_id=f"flm-lm1b-steps-{steps}",
        category="many",
        model="flm",
        dataset="lm1b",
        steps=steps,
        sample_count=1024,
        seed=42,
        environment="dlb-flm",
        adapter="flm",
        source="flm",
        provenance="official",
        sample_dir=f"/tmp/dlb/samples/lm1b/flm/steps_{steps}",
        metrics_path=f"/tmp/dlb/metrics/lm1b/flm/steps_{steps}/metrics.json",
        timing_path=f"/tmp/dlb/timing/lm1b/flm/steps_{steps}/timing.json",
    )


def test_gpu_matrix_dry_run_binds_tasks_to_requested_gpus(tmp_path):
    matrix = write_matrix(tmp_path / "generation.tsv", [_task(0), _task(1), _task(2)])

    completed = subprocess.run(
        [
            sys.executable,
            "-m",
            "dlb.gpu_matrix",
            "--root",
            str(ROOT),
            "--stage",
            "generate",
            "--matrix",
            str(matrix),
            "--gpus",
            "0,1",
            "--max-jobs",
            "2",
            "--dry-run",
        ],
        cwd=ROOT,
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=False,
    )

    assert completed.returncode == 0, completed.stderr
    records = [json.loads(line) for line in completed.stdout.splitlines()]
    assert [record["gpu"] for record in records] == ["0", "1", "0"]
    assert all(record["cuda_visible_devices"] == record["gpu"] for record in records)
    assert all(record["stage"] == "generate" for record in records)
    assert records[0]["command"][:2] == ["bash", str(ROOT / "scripts/run_one.sh")]
    assert "--num-samples" in records[0]["command"]


def test_gpu_matrix_rejects_empty_gpu_list(tmp_path):
    matrix = write_matrix(tmp_path / "generation.tsv", [_task(0)])

    completed = subprocess.run(
        [
            sys.executable,
            "-m",
            "dlb.gpu_matrix",
            "--root",
            str(ROOT),
            "--stage",
            "benchmark",
            "--matrix",
            str(matrix),
            "--gpus",
            "",
            "--dry-run",
        ],
        cwd=ROOT,
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=False,
    )

    assert completed.returncode == 2
    assert "at least one GPU" in completed.stderr


def test_gpu_matrix_can_oversubscribe_gpus_when_max_jobs_exceeds_gpu_count():
    assert active_gpus(("0", "1"), 5) == ("0", "1", "0", "1", "0")


@pytest.mark.parametrize(
    "script",
    [
        "scripts/smoke_4gpu.sh",
        "scripts/run_4gpu.sh",
        "scripts/evaluate_4gpu.sh",
        "scripts/benchmark_4gpu.sh",
    ],
)
def test_4gpu_wrappers_do_not_regenerate_explicit_custom_matrix(
    tmp_path: Path, script: str
):
    custom = write_matrix(tmp_path / "custom.tsv", [_task(0)])
    before = custom.read_text(encoding="utf-8")

    completed = subprocess.run(
        [
            "bash",
            str(ROOT / script),
            "--root",
            str(ROOT),
            "--matrix",
            str(custom),
            "--gpus",
            "0,1",
            "--max-jobs",
            "1",
            "--dry-run",
        ],
        cwd=ROOT,
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=False,
    )

    assert completed.returncode == 0, completed.stderr
    assert custom.read_text(encoding="utf-8") == before
    records = [json.loads(line) for line in completed.stdout.splitlines()]
    assert [record["task_id"] for record in records] == ["flm-lm1b-steps-1"]