Skip to content

Commit a5aea0d

Browse files
committed
initial commit for diff only
1 parent d126dca commit a5aea0d

6 files changed

Lines changed: 262 additions & 129 deletions

File tree

perf-changelog.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
changelog:
2+
- config-key: dsr1-fp8-h200-trt
3+
description: Test change

utils/matrix_logic/generate_sweep_configs.py

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import json
2-
import yaml
32
import argparse
43

5-
from validation import validate_master_config, validate_matrix_entry, validate_runner_config, Fields
4+
from validation import (
5+
validate_matrix_entry,
6+
load_config_files,
7+
load_runner_file,
8+
Fields
9+
)
610

711
seq_len_stoi = {
812
"1k1k": (1024, 1024),
@@ -366,44 +370,6 @@ def get_lowest_conc(search_space_entry):
366370
return matrix_values
367371

368372

369-
def load_config_files(config_files):
370-
"""Load and merge configuration files."""
371-
all_config_data = {}
372-
for config_file in config_files:
373-
try:
374-
with open(config_file, 'r') as f:
375-
config_data = yaml.safe_load(f)
376-
assert isinstance(
377-
config_data, dict), f"Config file '{config_file}' must contain a dictionary"
378-
379-
# Check for duplicate keys, this is only in place to prevent against the very unlikely
380-
# case where an entry in one config accidentally/purposefully tries to override an entry in another config
381-
duplicate_keys = set(all_config_data.keys()) & set(
382-
config_data.keys())
383-
if duplicate_keys:
384-
raise ValueError(
385-
f"Duplicate configuration keys found in '{config_file}': {', '.join(sorted(duplicate_keys))}"
386-
)
387-
388-
all_config_data.update(config_data)
389-
except FileNotFoundError:
390-
raise ValueError(f"Input file '{config_file}' does not exist.")
391-
392-
return all_config_data
393-
394-
395-
def load_runner_file(runner_file):
396-
"""Load runner configuration file."""
397-
try:
398-
with open(runner_file, 'r') as f:
399-
runner_config = yaml.safe_load(f)
400-
except FileNotFoundError as e:
401-
raise ValueError(
402-
f"Runner config file '{runner_file}' does not exist.")
403-
404-
return runner_config
405-
406-
407373
def main():
408374
# Create parent parser with common arguments
409375
parent_parser = argparse.ArgumentParser(add_help=False)
@@ -547,11 +513,9 @@ def main():
547513

548514
args = parser.parse_args()
549515

550-
# Load and validate configuration files
516+
# Load and validate configuration files (validation happens by default in load functions)
551517
all_config_data = load_config_files(args.config_files)
552518
runner_data = load_runner_file(args.runner_config)
553-
validate_master_config(all_config_data)
554-
validate_runner_config(runner_data)
555519

556520
# Route to appropriate function based on subcommand
557521
if args.command == 'full-sweep':

utils/matrix_logic/test_generate_sweep_configs.py

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
seq_len_to_str,
88
generate_full_sweep,
99
generate_runner_model_sweep_config,
10-
load_config_files,
11-
load_runner_file,
1210
)
1311

1412

@@ -583,90 +581,6 @@ def test_uses_lowest_conc(self, sample_single_node_config, sample_runner_config,
583581
assert all(entry["conc"] == 4 for entry in result)
584582

585583

586-
# =============================================================================
587-
# Test load_config_files
588-
# =============================================================================
589-
590-
class TestLoadConfigFiles:
591-
"""Tests for load_config_files function."""
592-
593-
def test_load_single_file(self, tmp_path):
594-
"""Should load a single config file."""
595-
config_file = tmp_path / "config.yaml"
596-
config_file.write_text("""
597-
test-config:
598-
image: test-image
599-
model: test-model
600-
""")
601-
result = load_config_files([str(config_file)])
602-
assert "test-config" in result
603-
assert result["test-config"]["image"] == "test-image"
604-
605-
def test_load_multiple_files(self, tmp_path):
606-
"""Should merge multiple config files."""
607-
config1 = tmp_path / "config1.yaml"
608-
config1.write_text("""
609-
config-one:
610-
value: 1
611-
""")
612-
config2 = tmp_path / "config2.yaml"
613-
config2.write_text("""
614-
config-two:
615-
value: 2
616-
""")
617-
result = load_config_files([str(config1), str(config2)])
618-
assert "config-one" in result
619-
assert "config-two" in result
620-
621-
def test_duplicate_keys_raise_error(self, tmp_path):
622-
"""Duplicate keys across files should raise error."""
623-
config1 = tmp_path / "config1.yaml"
624-
config1.write_text("""
625-
duplicate-key:
626-
value: 1
627-
""")
628-
config2 = tmp_path / "config2.yaml"
629-
config2.write_text("""
630-
duplicate-key:
631-
value: 2
632-
""")
633-
with pytest.raises(ValueError) as exc_info:
634-
load_config_files([str(config1), str(config2)])
635-
assert "Duplicate configuration keys" in str(exc_info.value)
636-
637-
def test_nonexistent_file_raises_error(self):
638-
"""Nonexistent file should raise error."""
639-
with pytest.raises(ValueError) as exc_info:
640-
load_config_files(["nonexistent.yaml"])
641-
assert "does not exist" in str(exc_info.value)
642-
643-
644-
# =============================================================================
645-
# Test load_runner_file
646-
# =============================================================================
647-
648-
class TestLoadRunnerFile:
649-
"""Tests for load_runner_file function."""
650-
651-
def test_load_runner_file(self, tmp_path):
652-
"""Should load runner config file."""
653-
runner_file = tmp_path / "runners.yaml"
654-
runner_file.write_text("""
655-
h100:
656-
- h100-node-0
657-
- h100-node-1
658-
""")
659-
result = load_runner_file(str(runner_file))
660-
assert "h100" in result
661-
assert len(result["h100"]) == 2
662-
663-
def test_nonexistent_runner_file(self):
664-
"""Nonexistent runner file should raise error."""
665-
with pytest.raises(ValueError) as exc_info:
666-
load_runner_file("nonexistent.yaml")
667-
assert "does not exist" in str(exc_info.value)
668-
669-
670584
# =============================================================================
671585
# Test edge cases and special configurations
672586
# =============================================================================

utils/matrix_logic/test_validation.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
validate_matrix_entry,
1515
validate_master_config,
1616
validate_runner_config,
17+
load_config_files,
18+
load_runner_file,
1719
)
1820

1921

@@ -738,3 +740,130 @@ def test_multiple_runner_types(self, valid_runner_config):
738740
assert "h200" in result
739741
assert "mi300x" in result
740742
assert "gb200" in result
743+
744+
745+
# =============================================================================
746+
# Test load_config_files
747+
# =============================================================================
748+
749+
class TestLoadConfigFiles:
750+
"""Tests for load_config_files function."""
751+
752+
def test_load_single_file_with_validation(self, tmp_path, valid_single_node_master_config):
753+
"""Should load and validate a single config file."""
754+
config_file = tmp_path / "config.yaml"
755+
import yaml
756+
config_file.write_text(yaml.dump({"test-config": valid_single_node_master_config}))
757+
result = load_config_files([str(config_file)])
758+
assert "test-config" in result
759+
assert result["test-config"]["image"] == valid_single_node_master_config["image"]
760+
761+
def test_load_single_file_without_validation(self, tmp_path):
762+
"""Should load a single config file without validation when validate=False."""
763+
config_file = tmp_path / "config.yaml"
764+
config_file.write_text("""
765+
test-config:
766+
image: test-image
767+
model: test-model
768+
""")
769+
result = load_config_files([str(config_file)], validate=False)
770+
assert "test-config" in result
771+
assert result["test-config"]["image"] == "test-image"
772+
773+
def test_load_multiple_files(self, tmp_path):
774+
"""Should merge multiple config files."""
775+
config1 = tmp_path / "config1.yaml"
776+
config1.write_text("""
777+
config-one:
778+
value: 1
779+
""")
780+
config2 = tmp_path / "config2.yaml"
781+
config2.write_text("""
782+
config-two:
783+
value: 2
784+
""")
785+
result = load_config_files([str(config1), str(config2)], validate=False)
786+
assert "config-one" in result
787+
assert "config-two" in result
788+
789+
def test_duplicate_keys_raise_error(self, tmp_path):
790+
"""Duplicate keys across files should raise error."""
791+
config1 = tmp_path / "config1.yaml"
792+
config1.write_text("""
793+
duplicate-key:
794+
value: 1
795+
""")
796+
config2 = tmp_path / "config2.yaml"
797+
config2.write_text("""
798+
duplicate-key:
799+
value: 2
800+
""")
801+
with pytest.raises(ValueError) as exc_info:
802+
load_config_files([str(config1), str(config2)], validate=False)
803+
assert "Duplicate configuration keys" in str(exc_info.value)
804+
805+
def test_nonexistent_file_raises_error(self):
806+
"""Nonexistent file should raise error."""
807+
with pytest.raises(ValueError) as exc_info:
808+
load_config_files(["nonexistent.yaml"])
809+
assert "does not exist" in str(exc_info.value)
810+
811+
def test_validation_runs_by_default(self, tmp_path):
812+
"""Validation should run by default and catch invalid configs."""
813+
config_file = tmp_path / "config.yaml"
814+
config_file.write_text("""
815+
invalid-config:
816+
image: test-image
817+
# Missing required fields like model, model-prefix, precision, etc.
818+
""")
819+
with pytest.raises(ValueError) as exc_info:
820+
load_config_files([str(config_file)])
821+
assert "failed validation" in str(exc_info.value)
822+
823+
824+
# =============================================================================
825+
# Test load_runner_file
826+
# =============================================================================
827+
828+
class TestLoadRunnerFile:
829+
"""Tests for load_runner_file function."""
830+
831+
def test_load_runner_file_with_validation(self, tmp_path):
832+
"""Should load and validate runner config file."""
833+
runner_file = tmp_path / "runners.yaml"
834+
runner_file.write_text("""
835+
h100:
836+
- h100-node-0
837+
- h100-node-1
838+
""")
839+
result = load_runner_file(str(runner_file))
840+
assert "h100" in result
841+
assert len(result["h100"]) == 2
842+
843+
def test_load_runner_file_without_validation(self, tmp_path):
844+
"""Should load runner config file without validation when validate=False."""
845+
runner_file = tmp_path / "runners.yaml"
846+
runner_file.write_text("""
847+
h100:
848+
- h100-node-0
849+
- h100-node-1
850+
""")
851+
result = load_runner_file(str(runner_file), validate=False)
852+
assert "h100" in result
853+
assert len(result["h100"]) == 2
854+
855+
def test_nonexistent_runner_file(self):
856+
"""Nonexistent runner file should raise error."""
857+
with pytest.raises(ValueError) as exc_info:
858+
load_runner_file("nonexistent.yaml")
859+
assert "does not exist" in str(exc_info.value)
860+
861+
def test_validation_runs_by_default(self, tmp_path):
862+
"""Validation should run by default and catch invalid configs."""
863+
runner_file = tmp_path / "runners.yaml"
864+
runner_file.write_text("""
865+
h100: not-a-list
866+
""")
867+
with pytest.raises(ValueError) as exc_info:
868+
load_runner_file(str(runner_file))
869+
assert "must be a list" in str(exc_info.value)

utils/matrix_logic/validation.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from enum import Enum
44

55
import pprint
6+
import yaml
67

78
"""
89
The below class defines the field names expected to be present in the JSON entries
@@ -315,3 +316,73 @@ def validate_runner_config(runner_configs: dict) -> List[dict]:
315316
f"Runner config entry '{key}' cannot be an empty list")
316317

317318
return runner_configs
319+
320+
321+
# =============================================================================
322+
# File Loading Functions
323+
# =============================================================================
324+
325+
326+
def load_config_files(config_files: List[str], validate: bool = True) -> dict:
327+
"""Load and merge configuration files.
328+
329+
Args:
330+
config_files: List of paths to YAML configuration files.
331+
validate: If True, run validate_master_config on loaded data. Defaults to True.
332+
333+
Returns:
334+
Merged configuration dictionary.
335+
336+
Raises:
337+
ValueError: If file doesn't exist, isn't a dict, or has duplicate keys.
338+
"""
339+
all_config_data = {}
340+
for config_file in config_files:
341+
try:
342+
with open(config_file, 'r') as f:
343+
config_data = yaml.safe_load(f)
344+
assert isinstance(
345+
config_data, dict), f"Config file '{config_file}' must contain a dictionary"
346+
347+
# Check for duplicate keys
348+
duplicate_keys = set(all_config_data.keys()) & set(
349+
config_data.keys())
350+
if duplicate_keys:
351+
raise ValueError(
352+
f"Duplicate configuration keys found in '{config_file}': {', '.join(sorted(duplicate_keys))}"
353+
)
354+
355+
all_config_data.update(config_data)
356+
except FileNotFoundError:
357+
raise ValueError(f"Input file '{config_file}' does not exist.")
358+
359+
if validate:
360+
validate_master_config(all_config_data)
361+
362+
return all_config_data
363+
364+
365+
def load_runner_file(runner_file: str, validate: bool = True) -> dict:
366+
"""Load runner configuration file.
367+
368+
Args:
369+
runner_file: Path to the runner YAML configuration file.
370+
validate: If True, run validate_runner_config on loaded data. Defaults to True.
371+
372+
Returns:
373+
Runner configuration dictionary.
374+
375+
Raises:
376+
ValueError: If file doesn't exist or fails validation.
377+
"""
378+
try:
379+
with open(runner_file, 'r') as f:
380+
runner_config = yaml.safe_load(f)
381+
except FileNotFoundError:
382+
raise ValueError(
383+
f"Runner config file '{runner_file}' does not exist.")
384+
385+
if validate:
386+
validate_runner_config(runner_config)
387+
388+
return runner_config

0 commit comments

Comments
 (0)