"""Generate Step 5.2 shape-only low mapped cases.
Copy this file to an operator whitebox directory as S5_case_mapper.py.
Only implement the dynamic region at the end of this file.
"""
from __future__ import annotations
import copy
import json
import logging
from pathlib import Path
from typing import Any
_logger = logging.getLogger(__name__)
ROOT = Path(__file__).resolve().parent
def load_json(path: str) -> Any:
with (ROOT / path).open("r", encoding="utf-8") as f:
return json.load(f)
def dump_json(path: str, data: Any) -> None:
with (ROOT / path).open("w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
f.write("\n")
def input_tensor(
dtype: str,
shape: list[int] | None,
param_type: str = "REQUIRED",
data_range: str = "normal",
fmt: str = "ND",
**extra: Any,
) -> dict[str, Any]:
tensor = {
"kind": "tensor",
"dtype": dtype,
"format": fmt,
"shape": None if shape is None else list(shape),
"param_type": param_type,
"data_range": data_range,
}
tensor.update(extra)
return tensor
def dynamic_input_tensor(
dtype: str,
tensors: list[dict[str, Any]],
data_range: str = "normal",
fmt: str = "ND",
**extra: Any,
) -> dict[str, Any]:
tensor = {
"kind": "tensor_list",
"dtype": dtype,
"format": fmt,
"param_type": "DYNAMIC",
"tensor_count": len(tensors),
"data_range": data_range,
"tensors": tensors,
}
tensor.update(extra)
return tensor
def output_tensor(
dtype: str,
shape: list[int] | None,
param_type: str = "REQUIRED",
fmt: str = "ND",
**extra: Any,
) -> dict[str, Any]:
tensor = {
"kind": "tensor",
"dtype": dtype,
"format": fmt,
"shape": None if shape is None else list(shape),
"param_type": param_type,
}
tensor.update(extra)
return tensor
def output_tensor_list(
dtype: str,
tensors: list[dict[str, Any]],
fmt: str = "ND",
**extra: Any,
) -> dict[str, Any]:
tensor = {
"kind": "tensor_list",
"dtype": dtype,
"format": fmt,
"param_type": "DYNAMIC",
"tensor_count": len(tensors),
"tensors": tensors,
}
tensor.update(extra)
return tensor
def clone_case(case: dict[str, Any]) -> dict[str, Any]:
return copy.deepcopy(case)
def path_case_id(index: int, case: dict[str, Any]) -> str:
return str(case.get("id") or f"case{index:05d}")
def network_case_id(index: int, config: dict[str, Any]) -> str:
return str(config.get("id") or f"network{index:05d}")
def network_record(config: dict[str, Any], index: int) -> dict[str, Any]:
record = dict(config)
record.setdefault("id", network_case_id(index, config))
return record
def mapped_inputs(case: dict[str, Any]) -> dict[str, dict[str, Any]]:
inputs = case.get("inputs")
if not isinstance(inputs, dict):
raise ValueError(f"{case.get('id', '<unknown>')}: inputs must be an object")
return inputs
def _reset_tensor_range(tensor: dict[str, Any]) -> None:
tensor["data_range"] = "normal"
if tensor.get("kind") == "tensor_list":
for child in tensor.get("tensors", []):
if isinstance(child, dict) and "data_range" in child:
child["data_range"] = "normal"
def normalize_input_ranges(case: dict[str, Any]) -> dict[str, Any]:
normalized = clone_case(case)
for tensor in mapped_inputs(normalized).values():
_reset_tensor_range(tensor)
return normalized
def _require_exact_keys(obj: dict[str, Any], expected: set[str], label: str) -> None:
actual = set(obj.keys())
if actual != expected:
raise ValueError(f"{label}: expected keys {sorted(expected)}, got {sorted(actual)}")
def _validate_tensor_shape(shape: Any, label: str) -> None:
if shape is None:
return
if not isinstance(shape, list) or not all(isinstance(dim, int) for dim in shape):
raise ValueError(f"{label}: shape must be a list[int] or null")
def _validate_single_tensor(tensor: dict[str, Any], label: str, *, allow_data_range: bool) -> None:
expected = {"kind", "dtype", "format", "shape", "param_type"}
if allow_data_range:
expected.add("data_range")
_require_exact_keys(tensor, expected, label)
_validate_tensor_shape(tensor.get("shape"), label)
if not isinstance(tensor.get("param_type"), str) or not tensor["param_type"]:
raise ValueError(f"{label}: param_type must be a non-empty string")
if allow_data_range:
if not isinstance(tensor.get("data_range"), str) or not tensor["data_range"]:
raise ValueError(f"{label}: data_range must be a non-empty string")
elif "data_range" in tensor:
raise ValueError(f"{label}: data_range is not allowed")
def _validate_tensor_list_children(tensor: dict[str, Any], label: str, *, allow_data_range: bool) -> None:
child_expected = {"kind", "dtype", "format", "shape"}
if allow_data_range:
child_expected.add("data_range")
for child_index, child in enumerate(tensor["tensors"]):
if not isinstance(child, dict):
raise ValueError(f"{label}: child {child_index} must be an object")
_require_exact_keys(child, child_expected, f"{label}: child {child_index}")
_validate_tensor_shape(child.get("shape"), f"{label}: child {child_index}")
if child.get("kind") != "tensor":
raise ValueError(f"{label}: child {child_index} kind must be tensor")
if not isinstance(child.get("dtype"), str) or not child["dtype"]:
raise ValueError(f"{label}: child {child_index} dtype must be a non-empty string")
if not isinstance(child.get("format"), str) or not child["format"]:
raise ValueError(f"{label}: child {child_index} format must be a non-empty string")
if allow_data_range:
if not isinstance(child.get("data_range"), str) or not child["data_range"]:
raise ValueError(f"{label}: child {child_index} data_range must be a non-empty string")
elif "data_range" in child:
raise ValueError(f"{label}: child {child_index} data_range is not allowed")
def _validate_tensor_list_descriptor(tensor: dict[str, Any], label: str, *, allow_data_range: bool) -> None:
expected = {"kind", "dtype", "format", "param_type", "tensor_count", "tensors"}
if allow_data_range:
expected.add("data_range")
_require_exact_keys(tensor, expected, label)
if tensor.get("param_type") != "DYNAMIC":
raise ValueError(f"{label}: param_type must be DYNAMIC")
if not isinstance(tensor.get("tensor_count"), int) or tensor["tensor_count"] < 0:
raise ValueError(f"{label}: tensor_count must be a non-negative int")
if not isinstance(tensor.get("tensors"), list):
raise ValueError(f"{label}: tensors must be a list")
if tensor["tensor_count"] != len(tensor["tensors"]):
raise ValueError(f"{label}: tensor_count must equal len(tensors)")
if allow_data_range:
if not isinstance(tensor.get("data_range"), str) or not tensor["data_range"]:
raise ValueError(f"{label}: data_range must be a non-empty string")
elif "data_range" in tensor:
raise ValueError(f"{label}: data_range is not allowed")
_validate_tensor_list_children(tensor, label, allow_data_range=allow_data_range)
def _validate_tensor_descriptor(
tensor: dict[str, Any], label: str, *, allow_data_range: bool, kind: str
) -> None:
if tensor.get("kind") != kind:
raise ValueError(f"{label}: kind must be {kind}")
if not isinstance(tensor.get("dtype"), str) or not tensor["dtype"]:
raise ValueError(f"{label}: dtype must be a non-empty string")
if not isinstance(tensor.get("format"), str) or not tensor["format"]:
raise ValueError(f"{label}: format must be a non-empty string")
if kind == "tensor":
_validate_single_tensor(tensor, label, allow_data_range=allow_data_range)
else:
_validate_tensor_list_descriptor(tensor, label, allow_data_range=allow_data_range)
def _validate_mapped_case_fields(case: dict[str, Any], label: str) -> None:
if not isinstance(case, dict):
raise ValueError(f"{label}: case must be an object")
expected = {"id", "source", "attributes", "const_inputs", "inputs", "outputs", "meta"}
_require_exact_keys(case, expected, label)
if not isinstance(case["id"], str):
raise ValueError(f"{label}: id must be a string")
if not isinstance(case["source"], str):
raise ValueError(f"{label}: source must be a string")
if not isinstance(case["attributes"], dict) or not isinstance(case["const_inputs"], dict):
raise ValueError(f"{label}: attributes and const_inputs must be objects")
if not isinstance(case["inputs"], dict) or not isinstance(case["outputs"], dict):
raise ValueError(f"{label}: inputs and outputs must be objects")
if not isinstance(case["meta"], dict):
raise ValueError(f"{label}: meta must be an object")
if "supported_data_ranges" in case["meta"]:
raise ValueError(f"{label}: meta.supported_data_ranges is not allowed")
def _validate_mapped_input(name: str, tensor: dict[str, Any], label: str) -> None:
if not isinstance(tensor, dict):
raise ValueError(f"{label}: input {name} must be an object")
kind = tensor.get("kind")
if kind == "tensor_list" or tensor.get("param_type") == "DYNAMIC":
_validate_tensor_descriptor(tensor, f"{label}: input {name}", allow_data_range=True, kind="tensor_list")
else:
_validate_tensor_descriptor(tensor, f"{label}: input {name}", allow_data_range=True, kind="tensor")
def _validate_mapped_outputs(outputs: dict[str, Any], label: str) -> None:
for name, tensor in outputs.items():
if not isinstance(tensor, dict):
raise ValueError(f"{label}: output {name} must be an object")
kind = tensor.get("kind")
if kind == "tensor_list" or tensor.get("param_type") == "DYNAMIC":
_validate_tensor_descriptor(tensor, f"{label}: output {name}", allow_data_range=False, kind="tensor_list")
else:
_validate_tensor_descriptor(tensor, f"{label}: output {name}", allow_data_range=False, kind="tensor")
def validate_mapped_case(case: Any, label: str) -> dict[str, Any]:
_validate_mapped_case_fields(case, label)
for name, tensor in case["inputs"].items():
_validate_mapped_input(name, tensor, label)
_validate_mapped_outputs(case["outputs"], label)
return normalize_input_ranges(case)
def map_path_case(case: dict[str, Any], index: int) -> dict[str, Any]:
mapped = build_low_base_case(case, "path", index)
mapped.setdefault("id", path_case_id(index, case))
mapped.setdefault("source", "path")
mapped["id"] = str(mapped["id"])
mapped["source"] = "path"
return validate_mapped_case(mapped, mapped["id"])
def map_network_case(record: dict[str, Any], index: int) -> dict[str, Any]:
mapped = build_low_base_case(record, "network", index)
mapped.setdefault("id", network_case_id(index, record))
mapped.setdefault("source", "network")
mapped["id"] = str(mapped["id"])
mapped["source"] = "network"
return validate_mapped_case(mapped, mapped["id"])
def make_shape_variants(case: dict[str, Any]) -> list[dict[str, Any]]:
source = case.get("source")
if source == "path":
return [make_path_shape_case(case)]
if source == "network":
return [make_network_shape_case(case)]
raise ValueError(f"{case.get('id', '<unknown>')}: unsupported source {source!r}")
def assert_unique_ids(cases: list[dict[str, Any]], label: str) -> None:
seen: set[str] = set()
for case in cases:
case_id = case["id"]
if case_id in seen:
raise ValueError(f"duplicate id in {label}: {case_id}")
seen.add(case_id)
def build_low_shape_cases(
path_cases: list[dict[str, Any]], network_cases: list[dict[str, Any]],
) -> list[dict[str, Any]]:
base_cases = path_cases + network_cases
shape_cases: list[dict[str, Any]] = []
for case in base_cases:
shape_variants = make_shape_variants(case)
if not shape_variants:
raise ValueError(f"{case['id']}: make_shape_variants must return at least one shape low case")
for variant in shape_variants:
if not isinstance(variant, dict):
raise ValueError(f"{case['id']}: shape variant must be an object")
variant.setdefault("source", "shape")
variant.setdefault("meta", {})
if not isinstance(variant["meta"], dict):
raise ValueError(f"{case['id']}: shape variant meta must be an object")
variant["source"] = "shape"
variant["id"] = f"low_case_{len(shape_cases):02d}"
variant["meta"].setdefault("base_id", case["id"])
variant["meta"].setdefault("variant_kind", "shape")
shape_cases.append(validate_mapped_case(variant, variant["id"]))
assert_unique_ids(shape_cases, "S5_mapped_cases_low_shape.json")
return shape_cases
def main() -> None:
logging.basicConfig(level=logging.INFO, format="%(message)s")
path_cases = load_json("S2P2_cases.json")
network_configs = load_json("S2P1_low_configs.json")
mapped_path = [map_path_case(case, index) for index, case in enumerate(path_cases)]
mapped_network = [
map_network_case(network_record(config, index), index)
for index, config in enumerate(network_configs)
]
low_shape_cases = build_low_shape_cases(mapped_path, mapped_network)
dump_json("S5_mapped_cases_path.json", mapped_path)
dump_json("S5_mapped_cases_network.json", mapped_network)
dump_json("S5_mapped_cases_low_shape.json", low_shape_cases)
_logger.info(
f"wrote {len(mapped_path)} path cases, {len(mapped_network)} mapped network cases,"
f" {len(low_shape_cases)} low shape cases"
)
def build_low_base_case(record: dict[str, Any], source: str, index: int) -> dict[str, Any]:
"""TODO(operator-specific): construct one complete base mapped case."""
raise NotImplementedError
def make_path_shape_case(case: dict[str, Any]) -> dict[str, Any]:
"""TODO(operator-specific): map one path base case to one shape low case."""
raise NotImplementedError
def make_network_shape_case(case: dict[str, Any]) -> dict[str, Any]:
"""TODO(operator-specific): map one network base case to one shape low case."""
raise NotImplementedError
def derive_outputs(
inputs: dict[str, Any],
attributes: dict[str, Any],
const_inputs: dict[str, Any],
meta: dict[str, Any],
) -> dict[str, dict[str, Any]]:
"""TODO(operator-specific): derive complete V1 output descriptors."""
raise NotImplementedError
if __name__ == "__main__":
main()