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)