| import unittest |
|
|
| import numpy as np |
|
|
| from quread.def_translator import DEFGridConfig, build_def_blockages, to_def_blockages_fragment |
| from quread.eda_view import detect_eda_format, parse_eda_text |
|
|
|
|
| class EDAViewParserTest(unittest.TestCase): |
| def test_parse_synopsys_tcl_rows(self): |
| text = "\n".join( |
| [ |
| "# q1: tier=CRITICAL risk=0.8200 route=HIGH row=0 col=1", |
| "set quread_q1_risk 0.82", |
| "set quread_q1_tier CRITICAL", |
| "set quread_q1_timing_derate 1.12", |
| "set quread_q1_guardband_mv 41.0", |
| "set quread_q1_severity_score 0.82", |
| "set quread_q1_severity_percentile 100.0", |
| "set quread_q1_pnr_cost 82.0", |
| "set quread_q1_density_cap 50.8", |
| "set quread_q1_source_metric composite_risk", |
| "set quread_q1_severity_mode linear", |
| "set quread_q1_row 0", |
| "set quread_q1_col 1", |
| "", |
| "# q0: tier=WARNING risk=0.4500 route=MEDIUM row=0 col=0", |
| "set quread_q0_risk 0.45", |
| "set quread_q0_tier WARNING", |
| "set quread_q0_timing_derate 1.07", |
| "set quread_q0_guardband_mv 23.0", |
| "set quread_q0_row 0", |
| "set quread_q0_col 0", |
| ] |
| ) |
| rows, meta = parse_eda_text(text, "synopsys_tcl") |
| self.assertEqual(meta["format"], "synopsys_tcl") |
| self.assertEqual(len(rows), 2) |
| self.assertEqual(rows[0]["qubit"], 1) |
| self.assertEqual(rows[0]["tier"], "CRITICAL") |
| self.assertEqual(rows[0]["layout_row"], 0) |
| self.assertEqual(rows[0]["layout_col"], 1) |
| self.assertAlmostEqual(rows[0]["severity_score"], 0.82, places=6) |
| self.assertAlmostEqual(rows[0]["pnr_cost"], 82.0, places=6) |
|
|
| def test_parse_cadence_skill_rows(self): |
| text = "\n".join( |
| [ |
| 'qureadRiskRows = cons(list("q0" 0.200000 "OK" 1.030000 14.000 1 2 "LOW" 0.200000 0.000000 20.000000 88.000000 "composite_risk" "linear") qureadRiskRows)', |
| 'qureadRiskRows = cons(list("q2" 0.910000 "CRITICAL" 1.140000 55.000 2 1 "HIGH" 0.950000 100.000000 95.000000 43.000000 "weighted_blend" "pnr_cost") qureadRiskRows)', |
| ] |
| ) |
| rows, meta = parse_eda_text(text, "cadence_skill") |
| self.assertEqual(meta["format"], "cadence_skill") |
| self.assertEqual(len(rows), 2) |
| self.assertEqual(rows[0]["qubit"], 2) |
| self.assertEqual(rows[0]["route_priority"], "HIGH") |
| self.assertEqual(rows[0]["layout_row"], 2) |
| self.assertEqual(rows[0]["layout_col"], 1) |
| self.assertAlmostEqual(rows[0]["pnr_cost"], 95.0, places=6) |
| self.assertEqual(rows[0]["severity_mode"], "pnr_cost") |
|
|
| def test_auto_detect_prefers_recognized_format(self): |
| syn_text = "set quread_q0_risk 0.5" |
| self.assertEqual(detect_eda_format(syn_text), "synopsys_tcl") |
| rows, _meta = parse_eda_text(syn_text, "auto") |
| self.assertEqual(rows[0]["qubit"], 0) |
|
|
| def test_parse_def_blockages_round_trip(self): |
| metrics = { |
| "composite_risk": np.array([0.55, 0.88], dtype=float), |
| "activity_norm": np.array([0.55, 0.88], dtype=float), |
| } |
| rows = build_def_blockages( |
| metrics, |
| qubit_coords={0: (0, 0), 1: (1, 0)}, |
| grid_cfg=DEFGridConfig(0, 0, 50, 20, 4, 2), |
| warning_threshold=0.45, |
| critical_threshold=0.7, |
| ) |
| fragment = to_def_blockages_fragment(rows) |
| parsed_rows, meta = parse_eda_text(fragment, "def_blockages") |
| self.assertEqual(meta["format"], "def_blockages") |
| self.assertEqual(len(parsed_rows), 2) |
| self.assertEqual(parsed_rows[0]["qubit"], 1) |
| self.assertEqual(parsed_rows[0]["mode"], "SOFT") |
| self.assertEqual(parsed_rows[1]["mode"], "PARTIAL") |
|
|
| def test_parse_uploaded_def_fragment_without_metadata_comments(self): |
| fragment = "\n".join( |
| [ |
| "BLOCKAGES 2 ;", |
| " - PLACEMENT + PARTIAL 70", |
| " RECT ( 100 200 ) ( 140 260 ) ;", |
| " - PLACEMENT + SOFT", |
| " RECT ( 140 200 ) ( 180 260 ) ;", |
| "END BLOCKAGES", |
| ] |
| ) |
| rows, meta = parse_eda_text(fragment, "def_blockages") |
| self.assertEqual(meta["format"], "def_blockages") |
| self.assertEqual(len(rows), 2) |
| self.assertIsNone(rows[0]["qubit"]) |
| self.assertEqual(rows[0]["mode"], "PARTIAL") |
| self.assertEqual(rows[1]["mode"], "SOFT") |
| self.assertEqual(rows[1]["rect_dbu"], (140, 200, 180, 260)) |
|
|
| def test_parse_eda_text_errors_on_unrecognized_input(self): |
| with self.assertRaises(ValueError): |
| parse_eda_text("not an eda script", "auto") |
|
|
| def test_parse_eda_text_errors_on_empty_def(self): |
| with self.assertRaises(ValueError): |
| parse_eda_text("BLOCKAGES 0 ;\nEND BLOCKAGES\n", "def_blockages") |
|
|
|
|
| if __name__ == "__main__": |
| unittest.main() |
|
|