Add nightly test support to unified run_suite.py (#13941)
This commit is contained in:
@@ -8,6 +8,7 @@ on:
|
|||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- "python/sglang/version.py"
|
- "python/sglang/version.py"
|
||||||
|
- "test/run_suite.py"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
@@ -40,7 +41,7 @@ jobs:
|
|||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
run: |
|
run: |
|
||||||
cd test
|
cd test
|
||||||
python3 run_suite_nightly.py --suite nightly-1-gpu --continue-on-error
|
python3 run_suite.py --hw cuda --suite nightly-1-gpu --nightly --continue-on-error
|
||||||
|
|
||||||
# General tests - 4 GPU H100
|
# General tests - 4 GPU H100
|
||||||
nightly-test-general-4-gpu-h100:
|
nightly-test-general-4-gpu-h100:
|
||||||
@@ -60,7 +61,7 @@ jobs:
|
|||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
run: |
|
run: |
|
||||||
cd test
|
cd test
|
||||||
python3 run_suite_nightly.py --suite nightly-4-gpu --continue-on-error
|
python3 run_suite.py --hw cuda --suite nightly-4-gpu --nightly --continue-on-error
|
||||||
|
|
||||||
# General tests - 8 GPU H200
|
# General tests - 8 GPU H200
|
||||||
nightly-test-general-8-gpu-h200:
|
nightly-test-general-8-gpu-h200:
|
||||||
@@ -84,7 +85,7 @@ jobs:
|
|||||||
GPU_CONFIG: "8-gpu-h200"
|
GPU_CONFIG: "8-gpu-h200"
|
||||||
run: |
|
run: |
|
||||||
cd test
|
cd test
|
||||||
python3 run_suite_nightly.py --suite nightly-8-gpu-h200 --continue-on-error
|
python3 run_suite.py --hw cuda --suite nightly-8-gpu-h200 --nightly --continue-on-error
|
||||||
|
|
||||||
- name: Run Qwen3-235B nightly performance test
|
- name: Run Qwen3-235B nightly performance test
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
@@ -184,7 +185,7 @@ jobs:
|
|||||||
GPU_CONFIG: "8-gpu-h20"
|
GPU_CONFIG: "8-gpu-h20"
|
||||||
run: |
|
run: |
|
||||||
cd test
|
cd test
|
||||||
python3 run_suite_nightly.py --suite nightly-8-gpu-h20 --continue-on-error
|
python3 run_suite.py --hw cuda --suite nightly-8-gpu-h20 --nightly --continue-on-error
|
||||||
|
|
||||||
# Text model accuracy tests
|
# Text model accuracy tests
|
||||||
nightly-test-text-accuracy-2-gpu-runner:
|
nightly-test-text-accuracy-2-gpu-runner:
|
||||||
@@ -376,7 +377,7 @@ jobs:
|
|||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
run: |
|
run: |
|
||||||
cd test
|
cd test
|
||||||
python3 run_suite_nightly.py --suite nightly-4-gpu-b200 --continue-on-error
|
python3 run_suite.py --hw cuda --suite nightly-4-gpu-b200 --nightly --continue-on-error
|
||||||
|
|
||||||
# B200 Performance tests - 8 GPU
|
# B200 Performance tests - 8 GPU
|
||||||
nightly-test-perf-8-gpu-b200:
|
nightly-test-perf-8-gpu-b200:
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import unittest
|
|||||||
import torch
|
import torch
|
||||||
|
|
||||||
from sglang.srt.batch_invariant_ops import batch_invariant_ops
|
from sglang.srt.batch_invariant_ops import batch_invariant_ops
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=10, suite="nightly-1-gpu", nightly=True)
|
||||||
from sglang.srt.batch_invariant_ops.batch_invariant_ops import set_batch_invariant_mode
|
from sglang.srt.batch_invariant_ops.batch_invariant_ops import set_batch_invariant_mode
|
||||||
from sglang.test.test_utils import CustomTestCase
|
from sglang.test.test_utils import CustomTestCase
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from types import SimpleNamespace
|
|||||||
|
|
||||||
from sglang.srt.environ import envs
|
from sglang.srt.environ import envs
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.run_eval import run_eval
|
from sglang.test.run_eval import run_eval
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_MODEL_NAME_FOR_TEST,
|
DEFAULT_MODEL_NAME_FOR_TEST,
|
||||||
@@ -12,6 +13,8 @@ from sglang.test.test_utils import (
|
|||||||
popen_launch_server,
|
popen_launch_server,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=60, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
|
|
||||||
class TestCppRadixCache(CustomTestCase):
|
class TestCppRadixCache(CustomTestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import unittest
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
|
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||||
@@ -12,6 +13,8 @@ from sglang.test.test_utils import (
|
|||||||
try_cached_model,
|
try_cached_model,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=3600, suite="nightly-8-gpu-b200", nightly=True)
|
||||||
|
|
||||||
FULL_DEEPSEEK_V3_MODEL_PATH = "deepseek-ai/DeepSeek-V3-0324"
|
FULL_DEEPSEEK_V3_MODEL_PATH = "deepseek-ai/DeepSeek-V3-0324"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import unittest
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
|
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||||
@@ -13,6 +14,8 @@ from sglang.test.test_utils import (
|
|||||||
write_github_step_summary,
|
write_github_step_summary,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=600, suite="nightly-8-gpu-h200", nightly=True)
|
||||||
|
|
||||||
DEEPSEEK_V32_MODEL_PATH = "deepseek-ai/DeepSeek-V3.2-Exp"
|
DEEPSEEK_V32_MODEL_PATH = "deepseek-ai/DeepSeek-V3.2-Exp"
|
||||||
|
|
||||||
# Global list to collect results
|
# Global list to collect results
|
||||||
|
|||||||
@@ -6,11 +6,14 @@ python3 -m unittest test_deepseek_v3_deterministic.TestFa3Deterministic
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.test_deterministic_utils import (
|
from sglang.test.test_deterministic_utils import (
|
||||||
COMMON_SERVER_ARGS,
|
COMMON_SERVER_ARGS,
|
||||||
TestDeterministicBase,
|
TestDeterministicBase,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=240, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
DEEPSEEK_MODEL = "lmsys/sglang-ci-dsv3-test"
|
DEEPSEEK_MODEL = "lmsys/sglang-ci-dsv3-test"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import unittest
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
|
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_URL_FOR_TEST,
|
DEFAULT_URL_FOR_TEST,
|
||||||
@@ -11,6 +12,8 @@ from sglang.test.test_utils import (
|
|||||||
write_github_step_summary,
|
write_github_step_summary,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=900, suite="nightly-4-gpu-b200", nightly=True)
|
||||||
|
|
||||||
FULL_DEEPSEEK_V3_FP4_MODEL_PATH = "nvidia/DeepSeek-V3-0324-FP4"
|
FULL_DEEPSEEK_V3_FP4_MODEL_PATH = "nvidia/DeepSeek-V3-0324-FP4"
|
||||||
SERVER_LAUNCH_TIMEOUT = 1000
|
SERVER_LAUNCH_TIMEOUT = 1000
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import unittest
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||||
DEFAULT_URL_FOR_TEST,
|
DEFAULT_URL_FOR_TEST,
|
||||||
@@ -17,6 +18,8 @@ from sglang.test.test_utils import (
|
|||||||
popen_launch_server,
|
popen_launch_server,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=500, suite="nightly-4-gpu", nightly=True)
|
||||||
|
|
||||||
MODELS = [
|
MODELS = [
|
||||||
SimpleNamespace(model="Qwen/Qwen2.5-VL-72B-Instruct", mmmu_accuracy=0.55),
|
SimpleNamespace(model="Qwen/Qwen2.5-VL-72B-Instruct", mmmu_accuracy=0.55),
|
||||||
SimpleNamespace(model="OpenGVLab/InternVL2_5-8B", mmmu_accuracy=0.52),
|
SimpleNamespace(model="OpenGVLab/InternVL2_5-8B", mmmu_accuracy=0.52),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import unittest
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.few_shot_gsm8k import run_eval
|
from sglang.test.few_shot_gsm8k import run_eval
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||||
@@ -11,6 +12,8 @@ from sglang.test.test_utils import (
|
|||||||
popen_launch_server,
|
popen_launch_server,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=300, suite="nightly-4-gpu-b200", nightly=True)
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenAttnBackend(CustomTestCase):
|
class TestFlashinferTrtllmGenAttnBackend(CustomTestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import unittest
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.few_shot_gsm8k import run_eval
|
from sglang.test.few_shot_gsm8k import run_eval
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||||
@@ -11,6 +12,8 @@ from sglang.test.test_utils import (
|
|||||||
popen_launch_server,
|
popen_launch_server,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=300, suite="nightly-4-gpu-b200", nightly=True)
|
||||||
|
|
||||||
|
|
||||||
class TestFlashinferTrtllmGenMoeBackend(CustomTestCase):
|
class TestFlashinferTrtllmGenMoeBackend(CustomTestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ from typing import Callable
|
|||||||
import pytest
|
import pytest
|
||||||
import torch
|
import torch
|
||||||
from flashinfer import fp4_quantize, scaled_fp4_grouped_quantize
|
from flashinfer import fp4_quantize, scaled_fp4_grouped_quantize
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=300, suite="nightly-4-gpu-b200", nightly=True)
|
||||||
from flashinfer.fused_moe import cutlass_fused_moe as flashinfer_cutlass_fused_moe
|
from flashinfer.fused_moe import cutlass_fused_moe as flashinfer_cutlass_fused_moe
|
||||||
from sgl_kernel import scaled_fp4_quant, silu_and_mul
|
from sgl_kernel import scaled_fp4_quant, silu_and_mul
|
||||||
from torch.nn import functional as F
|
from torch.nn import functional as F
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ import unittest
|
|||||||
|
|
||||||
from nightly_utils import NightlyBenchmarkRunner
|
from nightly_utils import NightlyBenchmarkRunner
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.test_utils import DEFAULT_URL_FOR_TEST
|
from sglang.test.test_utils import DEFAULT_URL_FOR_TEST
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=600, suite="nightly-4-gpu-b200", nightly=True)
|
||||||
|
|
||||||
PROFILE_DIR = "performance_profiles_gpt_oss_4gpu"
|
PROFILE_DIR = "performance_profiles_gpt_oss_4gpu"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ Tests LRU and FIFO eviction behavior.
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from sglang.srt.lora.eviction_policy import get_eviction_policy
|
from sglang.srt.lora.eviction_policy import get_eviction_policy
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=200, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
|
|
||||||
class TestLoRAEvictionPolicy(unittest.TestCase):
|
class TestLoRAEvictionPolicy(unittest.TestCase):
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import unittest
|
|||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from sglang.srt.entrypoints.openai.serving_base import OpenAIServingBase
|
from sglang.srt.entrypoints.openai.serving_base import OpenAIServingBase
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=30, suite="nightly-1-gpu", nightly=True)
|
||||||
from sglang.srt.server_args import ServerArgs
|
from sglang.srt.server_args import ServerArgs
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ import unittest
|
|||||||
|
|
||||||
import openai
|
import openai
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=150, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
from sglang.srt.utils import kill_process_tree
|
from sglang.srt.utils import kill_process_tree
|
||||||
from sglang.test.test_utils import (
|
from sglang.test.test_utils import (
|
||||||
DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
|
DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ import unittest
|
|||||||
|
|
||||||
from utils import LoRAAdaptor, LoRAModelCase, run_lora_multiple_batch_on_model_cases
|
from utils import LoRAAdaptor, LoRAModelCase, run_lora_multiple_batch_on_model_cases
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=97, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
from sglang.test.test_utils import CustomTestCase
|
from sglang.test.test_utils import CustomTestCase
|
||||||
|
|
||||||
LORA_MODELS_QWEN3 = [
|
LORA_MODELS_QWEN3 = [
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ import unittest
|
|||||||
import torch
|
import torch
|
||||||
from utils import CI_MULTI_LORA_MODELS, run_lora_test_one_by_one
|
from utils import CI_MULTI_LORA_MODELS, run_lora_test_one_by_one
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=200, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
from sglang.test.test_utils import CustomTestCase
|
from sglang.test.test_utils import CustomTestCase
|
||||||
|
|
||||||
PROMPTS = [
|
PROMPTS = [
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ from unittest.mock import MagicMock, patch
|
|||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=2, suite="nightly-1-gpu", nightly=True)
|
||||||
|
|
||||||
from sglang.srt.layers import dp_attention as _dp_attn
|
from sglang.srt.layers import dp_attention as _dp_attn
|
||||||
|
|
||||||
# Patch DP-attention globals before importing backends
|
# Patch DP-attention globals before importing backends
|
||||||
|
|||||||
@@ -6,11 +6,14 @@ python3 -m unittest test_qwen3_next_deterministic.TestFlashInferDeterministic
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_cuda_ci
|
||||||
from sglang.test.test_deterministic_utils import (
|
from sglang.test.test_deterministic_utils import (
|
||||||
COMMON_SERVER_ARGS,
|
COMMON_SERVER_ARGS,
|
||||||
TestDeterministicBase,
|
TestDeterministicBase,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_cuda_ci(est_time=200, suite="nightly-4-gpu", nightly=True)
|
||||||
|
|
||||||
QWEN3_NEXT = "Qwen/Qwen3-Next-80B-A3B-Instruct"
|
QWEN3_NEXT = "Qwen/Qwen3-Next-80B-A3B-Instruct"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+125
-17
@@ -1,5 +1,6 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import glob
|
import glob
|
||||||
|
import sys
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from sglang.test.ci.ci_register import CIRegistry, HWBackend, collect_tests
|
from sglang.test.ci.ci_register import CIRegistry, HWBackend, collect_tests
|
||||||
@@ -11,12 +12,29 @@ HW_MAPPING = {
|
|||||||
"amd": HWBackend.AMD,
|
"amd": HWBackend.AMD,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Per-commit test suites (run on every PR)
|
||||||
PER_COMMIT_SUITES = {
|
PER_COMMIT_SUITES = {
|
||||||
HWBackend.CPU: ["default"],
|
HWBackend.CPU: ["default"],
|
||||||
HWBackend.AMD: ["stage-a-test-1"],
|
HWBackend.AMD: ["stage-a-test-1"],
|
||||||
HWBackend.CUDA: ["stage-a-test-1"],
|
HWBackend.CUDA: ["stage-a-test-1"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Nightly test suites (run nightly, organized by GPU configuration)
|
||||||
|
NIGHTLY_SUITES = {
|
||||||
|
HWBackend.CUDA: [
|
||||||
|
"nightly-1-gpu",
|
||||||
|
"nightly-2-gpu",
|
||||||
|
"nightly-4-gpu",
|
||||||
|
"nightly-4-gpu-b200",
|
||||||
|
"nightly-8-gpu",
|
||||||
|
"nightly-8-gpu-h200",
|
||||||
|
"nightly-8-gpu-h20",
|
||||||
|
"nightly-8-gpu-b200",
|
||||||
|
],
|
||||||
|
HWBackend.AMD: ["nightly-amd"],
|
||||||
|
HWBackend.CPU: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def filter_tests(
|
def filter_tests(
|
||||||
ci_tests: List[CIRegistry], hw: HWBackend, suite: str, nightly: bool = False
|
ci_tests: List[CIRegistry], hw: HWBackend, suite: str, nightly: bool = False
|
||||||
@@ -28,14 +46,16 @@ def filter_tests(
|
|||||||
]
|
]
|
||||||
|
|
||||||
ret = []
|
ret = []
|
||||||
for t in ci_tests:
|
valid_suites = (
|
||||||
if not nightly:
|
NIGHTLY_SUITES.get(hw, []) if nightly else PER_COMMIT_SUITES.get(hw, [])
|
||||||
assert (
|
)
|
||||||
t.suite in PER_COMMIT_SUITES[hw]
|
|
||||||
), f"Unknown stage {t.suite} for backend {hw}"
|
|
||||||
else:
|
|
||||||
raise NotImplementedError("Nightly tests are not implemented yet.")
|
|
||||||
|
|
||||||
|
if suite not in valid_suites:
|
||||||
|
print(
|
||||||
|
f"Warning: Unknown suite {suite} for backend {hw.name}, nightly={nightly}"
|
||||||
|
)
|
||||||
|
|
||||||
|
for t in ci_tests:
|
||||||
if t.disabled is None:
|
if t.disabled is None:
|
||||||
ret.append(t)
|
ret.append(t)
|
||||||
print(f"Including test {t.filename}")
|
print(f"Including test {t.filename}")
|
||||||
@@ -45,20 +65,67 @@ def filter_tests(
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def run_a_suite(hw: HWBackend, suite: str, nightly: bool = False):
|
def auto_partition(files, rank, size):
|
||||||
files = glob.glob("registered/**/*.py", recursive=True)
|
"""
|
||||||
ci_tests = filter_tests(collect_tests(files), hw, suite, nightly)
|
Partition files into size sublists with approximately equal sums of estimated times
|
||||||
|
using a greedy algorithm (LPT heuristic), and return the partition for the specified rank.
|
||||||
|
"""
|
||||||
|
if not files or size <= 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Sort files by estimated_time in descending order (LPT heuristic)
|
||||||
|
sorted_files = sorted(files, key=lambda f: f.estimated_time, reverse=True)
|
||||||
|
|
||||||
|
partitions = [[] for _ in range(size)]
|
||||||
|
partition_sums = [0.0] * size
|
||||||
|
|
||||||
|
# Greedily assign each file to the partition with the smallest current total time
|
||||||
|
for file in sorted_files:
|
||||||
|
min_sum_idx = min(range(size), key=partition_sums.__getitem__)
|
||||||
|
partitions[min_sum_idx].append(file)
|
||||||
|
partition_sums[min_sum_idx] += file.estimated_time
|
||||||
|
|
||||||
|
if rank < size:
|
||||||
|
return partitions[rank]
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def run_a_suite(args):
|
||||||
|
hw = HW_MAPPING[args.hw]
|
||||||
|
suite = args.suite
|
||||||
|
nightly = args.nightly
|
||||||
|
auto_partition_id = args.auto_partition_id
|
||||||
|
auto_partition_size = args.auto_partition_size
|
||||||
|
|
||||||
|
files = glob.glob("**/*.py", recursive=True)
|
||||||
|
ci_tests = filter_tests(
|
||||||
|
collect_tests(files, sanity_check=False), hw, suite, nightly
|
||||||
|
)
|
||||||
test_files = [TestFile(t.filename, t.est_time) for t in ci_tests]
|
test_files = [TestFile(t.filename, t.est_time) for t in ci_tests]
|
||||||
|
|
||||||
run_unittest_files(
|
if not test_files:
|
||||||
|
print(f"No tests found for hw={hw.name}, suite={suite}, nightly={nightly}")
|
||||||
|
print("This is expected during incremental migration. Skipping.")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if auto_partition_size:
|
||||||
|
test_files = auto_partition(test_files, auto_partition_id, auto_partition_size)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"Running {len(test_files)} test(s) for hw={hw.name}, suite={suite}, nightly={nightly}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return run_unittest_files(
|
||||||
test_files,
|
test_files,
|
||||||
timeout_per_file=1200,
|
timeout_per_file=args.timeout_per_file,
|
||||||
continue_on_error=False,
|
continue_on_error=args.continue_on_error,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Run CI test suites from test/registered/"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--hw",
|
"--hw",
|
||||||
type=str,
|
type=str,
|
||||||
@@ -67,10 +134,51 @@ def main():
|
|||||||
help="Hardware backend to run tests on.",
|
help="Hardware backend to run tests on.",
|
||||||
)
|
)
|
||||||
parser.add_argument("--suite", type=str, required=True, help="Test suite to run.")
|
parser.add_argument("--suite", type=str, required=True, help="Test suite to run.")
|
||||||
parser.add_argument("--nightly", action="store_true")
|
parser.add_argument(
|
||||||
|
"--nightly",
|
||||||
|
action="store_true",
|
||||||
|
help="Run nightly tests instead of per-commit tests.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--timeout-per-file",
|
||||||
|
type=int,
|
||||||
|
default=1200,
|
||||||
|
help="The time limit for running one file in seconds (default: 1200).",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--continue-on-error",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="Continue running remaining tests even if one fails (default: False, useful for nightly tests).",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--auto-partition-id",
|
||||||
|
type=int,
|
||||||
|
help="Use auto load balancing. The part id.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--auto-partition-size",
|
||||||
|
type=int,
|
||||||
|
help="Use auto load balancing. The number of parts.",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
hw = HW_MAPPING[args.hw]
|
|
||||||
run_a_suite(hw, args.suite, args.nightly)
|
# Validate auto-partition arguments
|
||||||
|
if (args.auto_partition_id is not None) != (args.auto_partition_size is not None):
|
||||||
|
parser.error(
|
||||||
|
"--auto-partition-id and --auto-partition-size must be specified together."
|
||||||
|
)
|
||||||
|
if args.auto_partition_size is not None:
|
||||||
|
if args.auto_partition_size <= 0:
|
||||||
|
parser.error("--auto-partition-size must be positive.")
|
||||||
|
if not 0 <= args.auto_partition_id < args.auto_partition_size:
|
||||||
|
parser.error(
|
||||||
|
f"--auto-partition-id must be in range [0, {args.auto_partition_size}), "
|
||||||
|
f"but got {args.auto_partition_id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
exit_code = run_a_suite(args)
|
||||||
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user