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()