Coverage for tests/simulator/test_greedy.py: 100%
111 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
1import sys
2import os
3import pytest
4from dataclasses import replace
6# Add current path
7sys.path.append(os.getcwd())
9from tests.test_utils import temp_sys_path
11with temp_sys_path("simulator", "streamwise"):
12 from constants import DEFAULT_WORKFLOW_CONFIG
13 from constants import SECONDS_IN_HOUR
15 from workflows import WORKFLOWS
17 from sim_types import GPUType
18 from sim_types import QualityLevel
19 from sim_types import WorkflowConfig
21 from data_loading import load_latency_data
22 from data_loading import load_power_data
24 from model_provisioner.greedy import GreedyAllocator
26 from model_provisioner.policies import STREAMWISE_POLICY
29def test_allocate_8A_8H() -> None:
30 """8 A100 + 8 H100."""
31 latency_data = load_latency_data("simulator/data/")
32 allocator = GreedyAllocator(
33 workflow=DEFAULT_WORKFLOW_CONFIG,
34 latency_data=latency_data,
35 )
36 result = allocator.allocate(
37 num_gpus={GPUType.A100: 8, GPUType.H100: 8},
38 )
39 assert result.gpus_used[GPUType.A100] == 8
40 assert result.gpus_used[GPUType.H100] == 8
41 assert 0 < result.ttff_s < result.total_time_s
42 # assert 4100 <= result.total_time_s <= 4400 # TODO old values
43 assert 50 * 60 <= result.total_time_s <= 60 * 60 # 50-60 minutes
44 # assert 3500 <= result.ttff_s <= 3800 # TODO old values
45 assert 45 * 60 <= result.ttff_s <= 55 * 60 # 45-55 minutes
46 assert 0.2 <= result.tbf_s <= 0.4
49def test_allocate_32A_32H() -> None:
50 """32 A100 + 32 H100"""
51 latency_data = load_latency_data("simulator/data/")
52 allocator = GreedyAllocator(
53 workflow=DEFAULT_WORKFLOW_CONFIG,
54 latency_data=latency_data,
55 )
56 result = allocator.allocate(
57 num_gpus={GPUType.A100: 32, GPUType.H100: 32},
58 verbose=True,
59 )
60 assert result.gpus_used[GPUType.A100] == 32
61 assert result.gpus_used[GPUType.H100] == 32
62 assert 0 < result.ttff_s < result.total_time_s
63 assert 0 < result.tbf_s < 1
66def test_allocate_16A() -> None:
67 """16 A100 + 0 H100."""
68 latency_data = load_latency_data("simulator/data/")
69 allocator = GreedyAllocator(
70 workflow=DEFAULT_WORKFLOW_CONFIG,
71 latency_data=latency_data,
72 )
73 result = allocator.allocate(
74 num_gpus={GPUType.A100: 16, GPUType.H100: 0},
75 verbose=True,
76 )
77 assert result.gpus_used[GPUType.A100] == 16
78 assert result.gpus_used.get(GPUType.H100, 0) == 0
79 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
80 assert 0 < result.tbf_s < 1
83def test_allocate_64A() -> None:
84 """64 A100 + 0 H100."""
85 latency_data = load_latency_data("simulator/data/")
86 allocator = GreedyAllocator(
87 workflow=DEFAULT_WORKFLOW_CONFIG,
88 latency_data=latency_data,
89 )
90 result = allocator.allocate(
91 num_gpus={GPUType.A100: 64, GPUType.H100: 0},
92 verbose=True,
93 )
94 assert result.gpus_used[GPUType.A100] == 64
95 assert result.gpus_used.get(GPUType.H100, 0) == 0
96 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
97 assert 0 < result.tbf_s < 1
100def test_allocate_64H() -> None:
101 """0 A100 + 64 H100."""
102 latency_data = load_latency_data("simulator/data/")
103 allocator = GreedyAllocator(
104 workflow=DEFAULT_WORKFLOW_CONFIG,
105 latency_data=latency_data,
106 )
107 result = allocator.allocate(
108 num_gpus={GPUType.A100: 0, GPUType.H100: 64},
109 )
110 assert result.gpus_used.get(GPUType.A100, 0) == 0
111 assert result.gpus_used[GPUType.H100] == 64
112 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
113 assert 0 < result.tbf_s < 1
116def test_allocate_64GB() -> None:
117 """64 GB200."""
118 latency_data = load_latency_data("simulator/data/")
119 allocator = GreedyAllocator(
120 workflow=DEFAULT_WORKFLOW_CONFIG,
121 latency_data=latency_data,
122 )
123 result = allocator.allocate(
124 num_gpus={GPUType.GB200: 64},
125 verbose=True,
126 )
127 assert result.gpus_used[GPUType.GB200] == 64
128 assert result.gpus_used.get(GPUType.A100, 0) == 0
129 assert result.gpus_used.get(GPUType.H100, 0) == 0
130 assert result.gpus_used.get(GPUType.H200, 0) == 0
131 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
132 assert 0 < result.tbf_s < 1
135def test_allocate_32A_8H() -> None:
136 """32 A100 + 8 H100."""
137 latency_data = load_latency_data("simulator/data/")
138 allocator = GreedyAllocator(
139 workflow=DEFAULT_WORKFLOW_CONFIG,
140 latency_data=latency_data,
141 )
142 result = allocator.allocate(
143 num_gpus={GPUType.A100: 32, GPUType.H100: 8},
144 verbose=True,
145 )
146 assert result.gpus_used[GPUType.A100] == 32
147 assert result.gpus_used[GPUType.H100] == 8
148 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
149 assert 0 < result.tbf_s < 1
152def test_allocate_16A_80H() -> None:
153 """16 A100 + 80 H100."""
154 latency_data = load_latency_data("simulator/data/")
155 allocator = GreedyAllocator(
156 workflow=DEFAULT_WORKFLOW_CONFIG,
157 latency_data=latency_data,
158 )
159 result = allocator.allocate(
160 num_gpus={GPUType.A100: 16, GPUType.H100: 80},
161 verbose=True,
162 )
163 assert result.gpus_used[GPUType.A100] == 16
164 assert result.gpus_used[GPUType.H100] == 80
165 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
166 assert 0 < result.tbf_s < 1
169def test_allocate_0H() -> None:
170 """No GPUs."""
171 latency_data = load_latency_data("simulator/data/")
172 allocator = GreedyAllocator(
173 workflow=DEFAULT_WORKFLOW_CONFIG,
174 latency_data=latency_data,
175 )
176 with pytest.raises(AssertionError, match="Total number of GPUs must be at least 8"):
177 allocator.allocate(
178 num_gpus={GPUType.A100: 0, GPUType.H100: 0},
179 verbose=True,
180 )
183def test_32A_32H_options() -> None:
184 """32 A100 + 32 H100 with all options enabled."""
185 latency_data = load_latency_data("simulator/data/")
186 allocator = GreedyAllocator(
187 workflow=DEFAULT_WORKFLOW_CONFIG,
188 latency_data=latency_data,
189 )
190 result = allocator.allocate(
191 num_gpus={
192 GPUType.A100: 32,
193 GPUType.H100: 32,
194 },
195 verbose=True,
196 allow_removal=True,
197 allow_merging=True,
198 look_ahead_replicas=4,
199 )
200 assert result.gpus_used[GPUType.A100] == 32
201 assert result.gpus_used[GPUType.H100] == 32
202 assert 0 < result.ttff_s < result.total_time_s < 10 * 60 * 60
203 assert 0 < result.tbf_s < 1
206@pytest.mark.parametrize("workflow", WORKFLOWS.values())
207def test_workflows(workflow: WorkflowConfig) -> None:
208 latency_data = load_latency_data("simulator/data/")
209 power_data = load_power_data("simulator/data/")
210 policy = STREAMWISE_POLICY
211 if workflow.target_resolution != QualityLevel.HIGH:
212 policy = replace(policy, use_upscaler=False)
213 allocator = GreedyAllocator(
214 workflow=workflow,
215 latency_data=latency_data,
216 power_data=power_data,
217 policy=policy,
218 )
219 result = allocator.allocate(
220 num_gpus={
221 GPUType.A100: 16,
222 GPUType.H100: 16
223 },
224 verbose=True,
225 )
226 assert result.gpus_used[GPUType.A100] == 16
227 assert result.gpus_used[GPUType.H100] == 16
228 assert 0 < result.ttff_s < result.total_time_s < 24 * SECONDS_IN_HOUR
229 assert 0 < result.tbf_s < 1