hchevva commited on
Commit
2e0a017
·
verified ·
1 Parent(s): 5517ddc

Upload 2 files

Browse files
tests/test_app_flows.py CHANGED
@@ -683,6 +683,8 @@ ROW ROW1 CORE 0 400 FS DO 16 BY 1 STEP 200 0 ;
683
  with zipfile.ZipFile(path, "r") as zf:
684
  names = set(zf.namelist())
685
  self.assertIn("quread_design_report.html", names)
 
 
686
  self.assertIn("quread_heatmap_abstract.lef", names)
687
  self.assertIn("quread_heatmap_annotations.lib", names)
688
  self.assertIn("quread_risk_blockages.def", names)
@@ -690,6 +692,8 @@ ROW ROW1 CORE 0 400 FS DO 16 BY 1 STEP 200 0 ;
690
  self.assertIn("qubit_severity.csv", names)
691
  report = zf.read("quread_design_report.html").decode("utf-8")
692
  self.assertIn("Quread Combined Design Package", report)
 
 
693
  companion_lef = zf.read("quread_heatmap_abstract.lef").decode("utf-8")
694
  self.assertIn("MACRO QUREAD_Q0_", companion_lef)
695
  companion_lib = zf.read("quread_heatmap_annotations.lib").decode("utf-8")
@@ -784,6 +788,59 @@ ROW ROW1 CORE 0 400 FS DO 16 BY 1 STEP 200 0 ;
784
  except FileNotFoundError:
785
  pass
786
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
  def test_render_eda_view_supports_current_mapping_def_preview(self):
788
  qc = QuantumStateVector(2)
789
  qc.apply_single("H", target=0)
 
683
  with zipfile.ZipFile(path, "r") as zf:
684
  names = set(zf.namelist())
685
  self.assertIn("quread_design_report.html", names)
686
+ self.assertIn("validation_report.html", names)
687
+ self.assertIn("validation_report.json", names)
688
  self.assertIn("quread_heatmap_abstract.lef", names)
689
  self.assertIn("quread_heatmap_annotations.lib", names)
690
  self.assertIn("quread_risk_blockages.def", names)
 
692
  self.assertIn("qubit_severity.csv", names)
693
  report = zf.read("quread_design_report.html").decode("utf-8")
694
  self.assertIn("Quread Combined Design Package", report)
695
+ validation_html = zf.read("validation_report.html").decode("utf-8")
696
+ self.assertIn("Quread Validation Report", validation_html)
697
  companion_lef = zf.read("quread_heatmap_abstract.lef").decode("utf-8")
698
  self.assertIn("MACRO QUREAD_Q0_", companion_lef)
699
  companion_lib = zf.read("quread_heatmap_annotations.lib").decode("utf-8")
 
788
  except FileNotFoundError:
789
  pass
790
 
791
+ def test_render_validation_report_returns_summary_and_downloads(self):
792
+ qc = QuantumStateVector(2)
793
+ state, status, summary_md, focus_md, fig, artifact_rows, focus_rows, rows = app._render_validation_report(
794
+ qc,
795
+ 2,
796
+ 2,
797
+ 2,
798
+ DEFAULT_HEAT_METRIC,
799
+ None,
800
+ "",
801
+ 0.25,
802
+ 0.20,
803
+ 0.15,
804
+ 0.25,
805
+ 0.15,
806
+ 0.45,
807
+ 0.70,
808
+ *DEFAULT_SEVERITY_ARGS,
809
+ 0.0,
810
+ 8,
811
+ "0",
812
+ "0",
813
+ "100",
814
+ "100",
815
+ "10",
816
+ "10",
817
+ None,
818
+ None,
819
+ )
820
+ self.assertIn("Validation complete", status)
821
+ self.assertIn("Validation Summary", summary_md)
822
+ self.assertIn("Mismatch Focus", focus_md)
823
+ self.assertTrue(hasattr(fig, "axes"))
824
+ self.assertGreaterEqual(len(artifact_rows), 1)
825
+ self.assertIsInstance(focus_rows, list)
826
+ self.assertGreaterEqual(len(rows), 1)
827
+ self.assertIn("json", state)
828
+ self.assertIn("html", state)
829
+
830
+ json_path = app._dl_validation_json(state)
831
+ html_path = app._dl_validation_html(state)
832
+ try:
833
+ self.assertTrue(pathlib.Path(json_path).exists())
834
+ self.assertTrue(pathlib.Path(html_path).exists())
835
+ self.assertIn('"summary"', pathlib.Path(json_path).read_text(encoding="utf-8"))
836
+ self.assertIn("Quread Validation Report", pathlib.Path(html_path).read_text(encoding="utf-8"))
837
+ finally:
838
+ for candidate in (json_path, html_path):
839
+ try:
840
+ os.remove(candidate)
841
+ except FileNotFoundError:
842
+ pass
843
+
844
  def test_render_eda_view_supports_current_mapping_def_preview(self):
845
  qc = QuantumStateVector(2)
846
  qc.apply_single("H", target=0)
tests/test_validation_workbench.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import unittest
2
+
3
+ import numpy as np
4
+
5
+ from quread.def_translator import DEFGridConfig, build_def_blockages_from_severity_rows, to_def_blockages_fragment
6
+ from quread.eda_translator import build_eda_mapping_from_severity_rows, to_cadence_skill_reliability, to_synopsys_tcl
7
+ from quread.package_exporter import build_companion_lef, build_companion_lib
8
+ from quread.severity_mapper import SeverityConfig, SeverityThresholds, compute_severity_rows, severity_rows_to_csv
9
+ from quread.metrics import to_metrics_csv
10
+ from quread.validation_workbench import (
11
+ build_validation_report_html,
12
+ validate_design_exports,
13
+ validation_artifact_summary_rows,
14
+ validation_focus_rows,
15
+ )
16
+
17
+
18
+ def _sample_metrics():
19
+ return {
20
+ "activity_count": np.array([10.0, 2.0], dtype=float),
21
+ "activity_norm": np.array([1.0, 0.2], dtype=float),
22
+ "gate_error": np.array([0.12, 0.01], dtype=float),
23
+ "readout_error": np.array([0.08, 0.02], dtype=float),
24
+ "fidelity": np.array([0.82, 0.99], dtype=float),
25
+ "state_fidelity": np.array([0.80, 0.99], dtype=float),
26
+ "process_fidelity": np.array([0.78, 0.98], dtype=float),
27
+ "coherence_health": np.array([0.30, 0.90], dtype=float),
28
+ "decoherence_risk": np.array([0.70, 0.10], dtype=float),
29
+ "composite_risk": np.array([0.82, 0.22], dtype=float),
30
+ "hotspot_level": np.array([2.0, 0.0], dtype=float),
31
+ }
32
+
33
+
34
+ class ValidationWorkbenchTest(unittest.TestCase):
35
+ def _build_case(self):
36
+ metrics = _sample_metrics()
37
+ severity_cfg = SeverityConfig(
38
+ mode="linear",
39
+ source_metric="composite_risk",
40
+ thresholds=SeverityThresholds(warning=0.45, critical=0.70),
41
+ )
42
+ severity_rows = compute_severity_rows(metrics, cfg=severity_cfg, qubit_coords={0: (0, 0), 1: (0, 1)})
43
+ mapping_rows = build_eda_mapping_from_severity_rows(metrics, severity_rows)
44
+ grid_cfg = DEFGridConfig(
45
+ origin_x_dbu=0,
46
+ origin_y_dbu=0,
47
+ site_width_dbu=100,
48
+ row_height_dbu=100,
49
+ sites_per_cell_x=10,
50
+ rows_per_cell_y=10,
51
+ )
52
+ blockage_rows = build_def_blockages_from_severity_rows(severity_rows, grid_cfg=grid_cfg, partial_density=70.0)
53
+ return {
54
+ "metrics": metrics,
55
+ "severity_cfg": severity_cfg,
56
+ "severity_rows": severity_rows,
57
+ "mapping_rows": mapping_rows,
58
+ "grid_cfg": grid_cfg,
59
+ "blockage_rows": blockage_rows,
60
+ "metrics_csv_text": to_metrics_csv(metrics),
61
+ "severity_csv_text": severity_rows_to_csv(severity_rows),
62
+ "synopsys_tcl_text": to_synopsys_tcl(mapping_rows),
63
+ "cadence_skill_text": to_cadence_skill_reliability(mapping_rows),
64
+ "def_fragment_text": to_def_blockages_fragment(blockage_rows),
65
+ "companion_lef_text": build_companion_lef(
66
+ severity_rows,
67
+ dbu_per_micron=1000,
68
+ site_name="QUREAD_SITE",
69
+ site_width_dbu=100,
70
+ row_height_dbu=100,
71
+ sites_per_cell_x=10,
72
+ rows_per_cell_y=10,
73
+ ),
74
+ "companion_lib_text": build_companion_lib(
75
+ severity_rows,
76
+ dbu_per_micron=1000,
77
+ site_width_dbu=100,
78
+ row_height_dbu=100,
79
+ sites_per_cell_x=10,
80
+ rows_per_cell_y=10,
81
+ ),
82
+ "design_def_text": "UNITS DISTANCE MICRONS 1000 ;\nDIEAREA ( 0 0 ) ( 2000 2000 ) ;\n",
83
+ }
84
+
85
+ def test_validate_design_exports_passes_for_consistent_artifacts(self):
86
+ case = self._build_case()
87
+ report = validate_design_exports(
88
+ metrics_csv_text=case["metrics_csv_text"],
89
+ severity_csv_text=case["severity_csv_text"],
90
+ synopsys_tcl_text=case["synopsys_tcl_text"],
91
+ cadence_skill_text=case["cadence_skill_text"],
92
+ def_fragment_text=case["def_fragment_text"],
93
+ companion_lef_text=case["companion_lef_text"],
94
+ companion_lib_text=case["companion_lib_text"],
95
+ expected_metrics=case["metrics"],
96
+ expected_severity_rows=case["severity_rows"],
97
+ expected_mapping_rows=case["mapping_rows"],
98
+ expected_blockage_rows=case["blockage_rows"],
99
+ severity_cfg=case["severity_cfg"],
100
+ grid_cfg=case["grid_cfg"],
101
+ chip_rows=2,
102
+ chip_cols=2,
103
+ dbu_per_micron=1000,
104
+ site_name="QUREAD_SITE",
105
+ imported_design_def_text=case["design_def_text"],
106
+ )
107
+ self.assertEqual(report["summary"]["overall_status"], "PASS")
108
+ self.assertGreater(report["summary"]["pass_count"], 0)
109
+
110
+ def test_validate_design_exports_fails_for_misaligned_def(self):
111
+ case = self._build_case()
112
+ broken_def = case["def_fragment_text"].replace("RECT ( 0 0 ) ( 1000 1000 ) ;", "RECT ( 5 0 ) ( 1000 1000 ) ;")
113
+ report = validate_design_exports(
114
+ metrics_csv_text=case["metrics_csv_text"],
115
+ severity_csv_text=case["severity_csv_text"],
116
+ synopsys_tcl_text=case["synopsys_tcl_text"],
117
+ cadence_skill_text=case["cadence_skill_text"],
118
+ def_fragment_text=broken_def,
119
+ companion_lef_text=case["companion_lef_text"],
120
+ companion_lib_text=case["companion_lib_text"],
121
+ expected_metrics=case["metrics"],
122
+ expected_severity_rows=case["severity_rows"],
123
+ expected_mapping_rows=case["mapping_rows"],
124
+ expected_blockage_rows=case["blockage_rows"],
125
+ severity_cfg=case["severity_cfg"],
126
+ grid_cfg=case["grid_cfg"],
127
+ chip_rows=2,
128
+ chip_cols=2,
129
+ dbu_per_micron=1000,
130
+ site_name="QUREAD_SITE",
131
+ imported_design_def_text=case["design_def_text"],
132
+ )
133
+ self.assertEqual(report["summary"]["overall_status"], "FAIL")
134
+ self.assertTrue(any(check["code"] == "def_alignment" and check["status"] == "FAIL" for check in report["checks"]))
135
+ focus_rows = validation_focus_rows(report)
136
+ self.assertGreaterEqual(len(focus_rows), 1)
137
+ self.assertIn("q0", focus_rows[0][3])
138
+ artifact_rows = validation_artifact_summary_rows(report)
139
+ self.assertTrue(any(row[0] == "def" and row[4] == "FAIL" for row in artifact_rows))
140
+ html = build_validation_report_html(report)
141
+ self.assertIn("Artifact Summary", html)
142
+ self.assertIn("Mismatch Focus", html)