File size: 6,544 Bytes
2e0a017 | 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 | import unittest
import numpy as np
from quread.def_translator import DEFGridConfig, build_def_blockages_from_severity_rows, to_def_blockages_fragment
from quread.eda_translator import build_eda_mapping_from_severity_rows, to_cadence_skill_reliability, to_synopsys_tcl
from quread.package_exporter import build_companion_lef, build_companion_lib
from quread.severity_mapper import SeverityConfig, SeverityThresholds, compute_severity_rows, severity_rows_to_csv
from quread.metrics import to_metrics_csv
from quread.validation_workbench import (
build_validation_report_html,
validate_design_exports,
validation_artifact_summary_rows,
validation_focus_rows,
)
def _sample_metrics():
return {
"activity_count": np.array([10.0, 2.0], dtype=float),
"activity_norm": np.array([1.0, 0.2], dtype=float),
"gate_error": np.array([0.12, 0.01], dtype=float),
"readout_error": np.array([0.08, 0.02], dtype=float),
"fidelity": np.array([0.82, 0.99], dtype=float),
"state_fidelity": np.array([0.80, 0.99], dtype=float),
"process_fidelity": np.array([0.78, 0.98], dtype=float),
"coherence_health": np.array([0.30, 0.90], dtype=float),
"decoherence_risk": np.array([0.70, 0.10], dtype=float),
"composite_risk": np.array([0.82, 0.22], dtype=float),
"hotspot_level": np.array([2.0, 0.0], dtype=float),
}
class ValidationWorkbenchTest(unittest.TestCase):
def _build_case(self):
metrics = _sample_metrics()
severity_cfg = SeverityConfig(
mode="linear",
source_metric="composite_risk",
thresholds=SeverityThresholds(warning=0.45, critical=0.70),
)
severity_rows = compute_severity_rows(metrics, cfg=severity_cfg, qubit_coords={0: (0, 0), 1: (0, 1)})
mapping_rows = build_eda_mapping_from_severity_rows(metrics, severity_rows)
grid_cfg = DEFGridConfig(
origin_x_dbu=0,
origin_y_dbu=0,
site_width_dbu=100,
row_height_dbu=100,
sites_per_cell_x=10,
rows_per_cell_y=10,
)
blockage_rows = build_def_blockages_from_severity_rows(severity_rows, grid_cfg=grid_cfg, partial_density=70.0)
return {
"metrics": metrics,
"severity_cfg": severity_cfg,
"severity_rows": severity_rows,
"mapping_rows": mapping_rows,
"grid_cfg": grid_cfg,
"blockage_rows": blockage_rows,
"metrics_csv_text": to_metrics_csv(metrics),
"severity_csv_text": severity_rows_to_csv(severity_rows),
"synopsys_tcl_text": to_synopsys_tcl(mapping_rows),
"cadence_skill_text": to_cadence_skill_reliability(mapping_rows),
"def_fragment_text": to_def_blockages_fragment(blockage_rows),
"companion_lef_text": build_companion_lef(
severity_rows,
dbu_per_micron=1000,
site_name="QUREAD_SITE",
site_width_dbu=100,
row_height_dbu=100,
sites_per_cell_x=10,
rows_per_cell_y=10,
),
"companion_lib_text": build_companion_lib(
severity_rows,
dbu_per_micron=1000,
site_width_dbu=100,
row_height_dbu=100,
sites_per_cell_x=10,
rows_per_cell_y=10,
),
"design_def_text": "UNITS DISTANCE MICRONS 1000 ;\nDIEAREA ( 0 0 ) ( 2000 2000 ) ;\n",
}
def test_validate_design_exports_passes_for_consistent_artifacts(self):
case = self._build_case()
report = validate_design_exports(
metrics_csv_text=case["metrics_csv_text"],
severity_csv_text=case["severity_csv_text"],
synopsys_tcl_text=case["synopsys_tcl_text"],
cadence_skill_text=case["cadence_skill_text"],
def_fragment_text=case["def_fragment_text"],
companion_lef_text=case["companion_lef_text"],
companion_lib_text=case["companion_lib_text"],
expected_metrics=case["metrics"],
expected_severity_rows=case["severity_rows"],
expected_mapping_rows=case["mapping_rows"],
expected_blockage_rows=case["blockage_rows"],
severity_cfg=case["severity_cfg"],
grid_cfg=case["grid_cfg"],
chip_rows=2,
chip_cols=2,
dbu_per_micron=1000,
site_name="QUREAD_SITE",
imported_design_def_text=case["design_def_text"],
)
self.assertEqual(report["summary"]["overall_status"], "PASS")
self.assertGreater(report["summary"]["pass_count"], 0)
def test_validate_design_exports_fails_for_misaligned_def(self):
case = self._build_case()
broken_def = case["def_fragment_text"].replace("RECT ( 0 0 ) ( 1000 1000 ) ;", "RECT ( 5 0 ) ( 1000 1000 ) ;")
report = validate_design_exports(
metrics_csv_text=case["metrics_csv_text"],
severity_csv_text=case["severity_csv_text"],
synopsys_tcl_text=case["synopsys_tcl_text"],
cadence_skill_text=case["cadence_skill_text"],
def_fragment_text=broken_def,
companion_lef_text=case["companion_lef_text"],
companion_lib_text=case["companion_lib_text"],
expected_metrics=case["metrics"],
expected_severity_rows=case["severity_rows"],
expected_mapping_rows=case["mapping_rows"],
expected_blockage_rows=case["blockage_rows"],
severity_cfg=case["severity_cfg"],
grid_cfg=case["grid_cfg"],
chip_rows=2,
chip_cols=2,
dbu_per_micron=1000,
site_name="QUREAD_SITE",
imported_design_def_text=case["design_def_text"],
)
self.assertEqual(report["summary"]["overall_status"], "FAIL")
self.assertTrue(any(check["code"] == "def_alignment" and check["status"] == "FAIL" for check in report["checks"]))
focus_rows = validation_focus_rows(report)
self.assertGreaterEqual(len(focus_rows), 1)
self.assertIn("q0", focus_rows[0][3])
artifact_rows = validation_artifact_summary_rows(report)
self.assertTrue(any(row[0] == "def" and row[4] == "FAIL" for row in artifact_rows))
html = build_validation_report_html(report)
self.assertIn("Artifact Summary", html)
self.assertIn("Mismatch Focus", html)
|