Upload app.py
Browse files
app.py
CHANGED
|
@@ -31,6 +31,7 @@ from quread.metrics import (
|
|
| 31 |
MetricWeights,
|
| 32 |
MetricThresholds,
|
| 33 |
)
|
|
|
|
| 34 |
|
| 35 |
# --- Qubit cap (configurable) ---
|
| 36 |
DEFAULT_MAX_QUBITS = 16 # safe default for CPU Spaces; change if you want
|
|
@@ -76,6 +77,51 @@ def _write_tmp(filename: str, content: str) -> str:
|
|
| 76 |
return f.name
|
| 77 |
|
| 78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
def _circuit_hash(history):
|
| 80 |
return hashlib.sha256(str(history).encode()).hexdigest()
|
| 81 |
|
|
@@ -238,13 +284,19 @@ def _metric_controls_to_models(
|
|
| 238 |
return weights, thresholds
|
| 239 |
|
| 240 |
|
| 241 |
-
def _hotspot_rows(metrics, n_qubits, top_k):
|
| 242 |
rows = []
|
| 243 |
n = int(n_qubits)
|
| 244 |
for q in range(n):
|
| 245 |
risk = float(metrics["composite_risk"][q])
|
| 246 |
level = int(metrics["hotspot_level"][q])
|
| 247 |
status = "critical" if level == 2 else ("warning" if level == 1 else "ok")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
rows.append(
|
| 249 |
[
|
| 250 |
q,
|
|
@@ -258,6 +310,8 @@ def _hotspot_rows(metrics, n_qubits, top_k):
|
|
| 258 |
round(float(metrics["coherence_health"][q]), 6),
|
| 259 |
round(float(metrics["decoherence_risk"][q]), 6),
|
| 260 |
round(float(metrics["fidelity"][q]), 6),
|
|
|
|
|
|
|
| 261 |
]
|
| 262 |
)
|
| 263 |
rows.sort(key=lambda x: x[2], reverse=True)
|
|
@@ -265,7 +319,7 @@ def _hotspot_rows(metrics, n_qubits, top_k):
|
|
| 265 |
return rows[:k]
|
| 266 |
|
| 267 |
|
| 268 |
-
def _hotspot_detail_markdown(metrics, meta, n_qubits, focus_qubit):
|
| 269 |
n = int(n_qubits)
|
| 270 |
if n < 1:
|
| 271 |
return "No qubits available."
|
|
@@ -279,6 +333,10 @@ def _hotspot_detail_markdown(metrics, meta, n_qubits, focus_qubit):
|
|
| 279 |
thr_warning = float(getattr(thresholds, "warning", 0.45))
|
| 280 |
thr_critical = float(getattr(thresholds, "critical", 0.70))
|
| 281 |
fidelity_backend = str(meta.get("fidelity_backend", "unknown"))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
|
| 283 |
return (
|
| 284 |
f"### Hotspot Detail: q{q}\n"
|
|
@@ -286,6 +344,7 @@ def _hotspot_detail_markdown(metrics, meta, n_qubits, focus_qubit):
|
|
| 286 |
f"- Composite risk: **{risk:.6f}**\n"
|
| 287 |
f"- Thresholds: warning={thr_warning:.2f}, critical={thr_critical:.2f}\n"
|
| 288 |
f"- Fidelity backend: `{fidelity_backend}`\n"
|
|
|
|
| 289 |
f"- Activity count: {float(metrics['activity_count'][q]):.3f}\n"
|
| 290 |
f"- Gate error: {float(metrics['gate_error'][q]):.6f}\n"
|
| 291 |
f"- Readout error: {float(metrics['readout_error'][q]):.6f}\n"
|
|
@@ -573,6 +632,13 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 573 |
label="Calibration JSON (optional)",
|
| 574 |
placeholder='{"qubits":{"0":{"gate_error":0.012,"readout_error":0.02,"t1_us":82,"t2_us":61,"fidelity":0.991}}}',
|
| 575 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 576 |
with gr.Accordion("Advanced Weights & Thresholds", open=False):
|
| 577 |
gr.Markdown("<div class='small-note'>Composite risk weights are normalized automatically.</div>")
|
| 578 |
with gr.Row():
|
|
@@ -610,6 +676,8 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 610 |
"coherence_health",
|
| 611 |
"decoherence_risk",
|
| 612 |
"fidelity",
|
|
|
|
|
|
|
| 613 |
],
|
| 614 |
interactive=False,
|
| 615 |
label="Hotspot ranking (highest composite risk first)",
|
|
@@ -756,6 +824,9 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 756 |
def _dl_synopsys_tcl(
|
| 757 |
qc,
|
| 758 |
n_qubits,
|
|
|
|
|
|
|
|
|
|
| 759 |
calibration_text,
|
| 760 |
activity_w,
|
| 761 |
gate_error_w,
|
|
@@ -783,15 +854,25 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 783 |
weights=weights,
|
| 784 |
thresholds=thresholds,
|
| 785 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 786 |
mapping = build_eda_mapping(
|
| 787 |
metrics,
|
| 788 |
cfg=None,
|
|
|
|
| 789 |
)
|
| 790 |
return _write_tmp("quread_risk_synopsys.tcl", to_synopsys_tcl(mapping))
|
| 791 |
|
| 792 |
def _dl_cadence_skill(
|
| 793 |
qc,
|
| 794 |
n_qubits,
|
|
|
|
|
|
|
|
|
|
| 795 |
calibration_text,
|
| 796 |
activity_w,
|
| 797 |
gate_error_w,
|
|
@@ -819,9 +900,16 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 819 |
weights=weights,
|
| 820 |
thresholds=thresholds,
|
| 821 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 822 |
mapping = build_eda_mapping(
|
| 823 |
metrics,
|
| 824 |
cfg=None,
|
|
|
|
| 825 |
)
|
| 826 |
return _write_tmp("quread_risk_cadence.il", to_cadence_skill_reliability(mapping))
|
| 827 |
|
|
@@ -838,6 +926,7 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 838 |
cols,
|
| 839 |
metric,
|
| 840 |
render_mode,
|
|
|
|
| 841 |
calibration_text,
|
| 842 |
activity_w,
|
| 843 |
gate_error_w,
|
|
@@ -864,6 +953,12 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 864 |
threshold_value = None if float(metric_thr) <= 0 else float(metric_thr)
|
| 865 |
render_choice = str(render_mode or "interactive").strip().lower()
|
| 866 |
notes = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 867 |
|
| 868 |
if render_choice == "interactive":
|
| 869 |
if plotly_available():
|
|
@@ -877,6 +972,7 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 877 |
weights=weights,
|
| 878 |
thresholds=thresholds,
|
| 879 |
highlight_threshold=threshold_value,
|
|
|
|
| 880 |
)
|
| 881 |
else:
|
| 882 |
fig = make_metric_heatmap(
|
|
@@ -889,6 +985,7 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 889 |
weights=weights,
|
| 890 |
thresholds=thresholds,
|
| 891 |
highlight_threshold=threshold_value,
|
|
|
|
| 892 |
)
|
| 893 |
notes.append("Plotly unavailable in this runtime; using static heatmap.")
|
| 894 |
else:
|
|
@@ -902,6 +999,7 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 902 |
weights=weights,
|
| 903 |
thresholds=thresholds,
|
| 904 |
highlight_threshold=threshold_value,
|
|
|
|
| 905 |
)
|
| 906 |
|
| 907 |
metrics, meta = compute_metrics_from_csv(
|
|
@@ -912,8 +1010,23 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 912 |
weights=weights,
|
| 913 |
thresholds=thresholds,
|
| 914 |
)
|
| 915 |
-
hotspot_rows = _hotspot_rows(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 916 |
note = notes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 917 |
skipped = int(meta.get("skipped_rows", 0))
|
| 918 |
if skipped:
|
| 919 |
note.append(f"Skipped malformed CSV rows: {skipped}")
|
|
@@ -924,7 +1037,13 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 924 |
if fidelity_backend:
|
| 925 |
note.append(f"Fidelity backend: {fidelity_backend}")
|
| 926 |
summary = " | ".join(note) if note else "Hotspot ranking updated."
|
| 927 |
-
detail_md = _hotspot_detail_markdown(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 928 |
detail_fig = _hotspot_detail_plot(metrics, meta, int(n_qubits), int(focus_qubit))
|
| 929 |
return fig, summary, hotspot_rows, detail_md, detail_fig
|
| 930 |
|
|
@@ -969,6 +1088,7 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 969 |
chip_cols,
|
| 970 |
heat_metric,
|
| 971 |
heat_render_mode,
|
|
|
|
| 972 |
calibration_json,
|
| 973 |
w_activity,
|
| 974 |
w_gate,
|
|
@@ -1006,6 +1126,9 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 1006 |
inputs=[
|
| 1007 |
qc_state,
|
| 1008 |
n_qubits,
|
|
|
|
|
|
|
|
|
|
| 1009 |
calibration_json,
|
| 1010 |
w_activity,
|
| 1011 |
w_gate,
|
|
@@ -1023,6 +1146,9 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
|
|
| 1023 |
inputs=[
|
| 1024 |
qc_state,
|
| 1025 |
n_qubits,
|
|
|
|
|
|
|
|
|
|
| 1026 |
calibration_json,
|
| 1027 |
w_activity,
|
| 1028 |
w_gate,
|
|
|
|
| 31 |
MetricWeights,
|
| 32 |
MetricThresholds,
|
| 33 |
)
|
| 34 |
+
from quread.layout_mapper import parse_layout_csv_text
|
| 35 |
|
| 36 |
# --- Qubit cap (configurable) ---
|
| 37 |
DEFAULT_MAX_QUBITS = 16 # safe default for CPU Spaces; change if you want
|
|
|
|
| 77 |
return f.name
|
| 78 |
|
| 79 |
|
| 80 |
+
def _read_uploaded_text(uploaded_file) -> str:
|
| 81 |
+
if uploaded_file is None:
|
| 82 |
+
return ""
|
| 83 |
+
|
| 84 |
+
if isinstance(uploaded_file, bytes):
|
| 85 |
+
return uploaded_file.decode("utf-8", errors="replace")
|
| 86 |
+
if isinstance(uploaded_file, str):
|
| 87 |
+
path = pathlib.Path(uploaded_file)
|
| 88 |
+
if path.exists():
|
| 89 |
+
return path.read_text(encoding="utf-8", errors="replace")
|
| 90 |
+
return ""
|
| 91 |
+
|
| 92 |
+
if isinstance(uploaded_file, dict):
|
| 93 |
+
raw = uploaded_file.get("data")
|
| 94 |
+
if isinstance(raw, bytes):
|
| 95 |
+
return raw.decode("utf-8", errors="replace")
|
| 96 |
+
maybe_path = uploaded_file.get("name") or uploaded_file.get("path")
|
| 97 |
+
if maybe_path:
|
| 98 |
+
path = pathlib.Path(str(maybe_path))
|
| 99 |
+
if path.exists():
|
| 100 |
+
return path.read_text(encoding="utf-8", errors="replace")
|
| 101 |
+
return ""
|
| 102 |
+
|
| 103 |
+
maybe_path = getattr(uploaded_file, "name", None)
|
| 104 |
+
if maybe_path:
|
| 105 |
+
path = pathlib.Path(str(maybe_path))
|
| 106 |
+
if path.exists():
|
| 107 |
+
return path.read_text(encoding="utf-8", errors="replace")
|
| 108 |
+
|
| 109 |
+
raw = getattr(uploaded_file, "data", None)
|
| 110 |
+
if isinstance(raw, bytes):
|
| 111 |
+
return raw.decode("utf-8", errors="replace")
|
| 112 |
+
return ""
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def _resolve_layout_coords(layout_file, n_qubits, rows, cols):
|
| 116 |
+
layout_text = _read_uploaded_text(layout_file)
|
| 117 |
+
return parse_layout_csv_text(
|
| 118 |
+
layout_text,
|
| 119 |
+
int(n_qubits),
|
| 120 |
+
rows=int(rows),
|
| 121 |
+
cols=int(cols),
|
| 122 |
+
)
|
| 123 |
+
|
| 124 |
+
|
| 125 |
def _circuit_hash(history):
|
| 126 |
return hashlib.sha256(str(history).encode()).hexdigest()
|
| 127 |
|
|
|
|
| 284 |
return weights, thresholds
|
| 285 |
|
| 286 |
|
| 287 |
+
def _hotspot_rows(metrics, n_qubits, top_k, qubit_coords=None):
|
| 288 |
rows = []
|
| 289 |
n = int(n_qubits)
|
| 290 |
for q in range(n):
|
| 291 |
risk = float(metrics["composite_risk"][q])
|
| 292 |
level = int(metrics["hotspot_level"][q])
|
| 293 |
status = "critical" if level == 2 else ("warning" if level == 1 else "ok")
|
| 294 |
+
layout_row = ""
|
| 295 |
+
layout_col = ""
|
| 296 |
+
if qubit_coords and q in qubit_coords:
|
| 297 |
+
rr, cc = qubit_coords[q]
|
| 298 |
+
layout_row = int(rr)
|
| 299 |
+
layout_col = int(cc)
|
| 300 |
rows.append(
|
| 301 |
[
|
| 302 |
q,
|
|
|
|
| 310 |
round(float(metrics["coherence_health"][q]), 6),
|
| 311 |
round(float(metrics["decoherence_risk"][q]), 6),
|
| 312 |
round(float(metrics["fidelity"][q]), 6),
|
| 313 |
+
layout_row,
|
| 314 |
+
layout_col,
|
| 315 |
]
|
| 316 |
)
|
| 317 |
rows.sort(key=lambda x: x[2], reverse=True)
|
|
|
|
| 319 |
return rows[:k]
|
| 320 |
|
| 321 |
|
| 322 |
+
def _hotspot_detail_markdown(metrics, meta, n_qubits, focus_qubit, qubit_coords=None):
|
| 323 |
n = int(n_qubits)
|
| 324 |
if n < 1:
|
| 325 |
return "No qubits available."
|
|
|
|
| 333 |
thr_warning = float(getattr(thresholds, "warning", 0.45))
|
| 334 |
thr_critical = float(getattr(thresholds, "critical", 0.70))
|
| 335 |
fidelity_backend = str(meta.get("fidelity_backend", "unknown"))
|
| 336 |
+
coord_line = ""
|
| 337 |
+
if qubit_coords and q in qubit_coords:
|
| 338 |
+
rr, cc = qubit_coords[q]
|
| 339 |
+
coord_line = f"- Layout coordinate: row={int(rr)}, col={int(cc)}\n"
|
| 340 |
|
| 341 |
return (
|
| 342 |
f"### Hotspot Detail: q{q}\n"
|
|
|
|
| 344 |
f"- Composite risk: **{risk:.6f}**\n"
|
| 345 |
f"- Thresholds: warning={thr_warning:.2f}, critical={thr_critical:.2f}\n"
|
| 346 |
f"- Fidelity backend: `{fidelity_backend}`\n"
|
| 347 |
+
f"{coord_line}"
|
| 348 |
f"- Activity count: {float(metrics['activity_count'][q]):.3f}\n"
|
| 349 |
f"- Gate error: {float(metrics['gate_error'][q]):.6f}\n"
|
| 350 |
f"- Readout error: {float(metrics['readout_error'][q]):.6f}\n"
|
|
|
|
| 632 |
label="Calibration JSON (optional)",
|
| 633 |
placeholder='{"qubits":{"0":{"gate_error":0.012,"readout_error":0.02,"t1_us":82,"t2_us":61,"fidelity":0.991}}}',
|
| 634 |
)
|
| 635 |
+
with gr.Accordion("Physical Layout Mapper", open=False):
|
| 636 |
+
layout_csv_file = gr.File(
|
| 637 |
+
label="Layout CSV (optional): qubit,row,col",
|
| 638 |
+
file_types=[".csv"],
|
| 639 |
+
type="filepath",
|
| 640 |
+
)
|
| 641 |
+
gr.Markdown("<div class='small-note'>Accepted aliases: qubit_id/q/id and row(r/y), col(c/x).</div>")
|
| 642 |
with gr.Accordion("Advanced Weights & Thresholds", open=False):
|
| 643 |
gr.Markdown("<div class='small-note'>Composite risk weights are normalized automatically.</div>")
|
| 644 |
with gr.Row():
|
|
|
|
| 676 |
"coherence_health",
|
| 677 |
"decoherence_risk",
|
| 678 |
"fidelity",
|
| 679 |
+
"layout_row",
|
| 680 |
+
"layout_col",
|
| 681 |
],
|
| 682 |
interactive=False,
|
| 683 |
label="Hotspot ranking (highest composite risk first)",
|
|
|
|
| 824 |
def _dl_synopsys_tcl(
|
| 825 |
qc,
|
| 826 |
n_qubits,
|
| 827 |
+
rows,
|
| 828 |
+
cols,
|
| 829 |
+
layout_file,
|
| 830 |
calibration_text,
|
| 831 |
activity_w,
|
| 832 |
gate_error_w,
|
|
|
|
| 854 |
weights=weights,
|
| 855 |
thresholds=thresholds,
|
| 856 |
)
|
| 857 |
+
qubit_coords, _layout_meta = _resolve_layout_coords(
|
| 858 |
+
layout_file,
|
| 859 |
+
int(n_qubits),
|
| 860 |
+
int(rows),
|
| 861 |
+
int(cols),
|
| 862 |
+
)
|
| 863 |
mapping = build_eda_mapping(
|
| 864 |
metrics,
|
| 865 |
cfg=None,
|
| 866 |
+
qubit_coords=qubit_coords,
|
| 867 |
)
|
| 868 |
return _write_tmp("quread_risk_synopsys.tcl", to_synopsys_tcl(mapping))
|
| 869 |
|
| 870 |
def _dl_cadence_skill(
|
| 871 |
qc,
|
| 872 |
n_qubits,
|
| 873 |
+
rows,
|
| 874 |
+
cols,
|
| 875 |
+
layout_file,
|
| 876 |
calibration_text,
|
| 877 |
activity_w,
|
| 878 |
gate_error_w,
|
|
|
|
| 900 |
weights=weights,
|
| 901 |
thresholds=thresholds,
|
| 902 |
)
|
| 903 |
+
qubit_coords, _layout_meta = _resolve_layout_coords(
|
| 904 |
+
layout_file,
|
| 905 |
+
int(n_qubits),
|
| 906 |
+
int(rows),
|
| 907 |
+
int(cols),
|
| 908 |
+
)
|
| 909 |
mapping = build_eda_mapping(
|
| 910 |
metrics,
|
| 911 |
cfg=None,
|
| 912 |
+
qubit_coords=qubit_coords,
|
| 913 |
)
|
| 914 |
return _write_tmp("quread_risk_cadence.il", to_cadence_skill_reliability(mapping))
|
| 915 |
|
|
|
|
| 926 |
cols,
|
| 927 |
metric,
|
| 928 |
render_mode,
|
| 929 |
+
layout_file,
|
| 930 |
calibration_text,
|
| 931 |
activity_w,
|
| 932 |
gate_error_w,
|
|
|
|
| 953 |
threshold_value = None if float(metric_thr) <= 0 else float(metric_thr)
|
| 954 |
render_choice = str(render_mode or "interactive").strip().lower()
|
| 955 |
notes = []
|
| 956 |
+
qubit_coords, layout_meta = _resolve_layout_coords(
|
| 957 |
+
layout_file,
|
| 958 |
+
int(n_qubits),
|
| 959 |
+
int(rows),
|
| 960 |
+
int(cols),
|
| 961 |
+
)
|
| 962 |
|
| 963 |
if render_choice == "interactive":
|
| 964 |
if plotly_available():
|
|
|
|
| 972 |
weights=weights,
|
| 973 |
thresholds=thresholds,
|
| 974 |
highlight_threshold=threshold_value,
|
| 975 |
+
qubit_coords=qubit_coords,
|
| 976 |
)
|
| 977 |
else:
|
| 978 |
fig = make_metric_heatmap(
|
|
|
|
| 985 |
weights=weights,
|
| 986 |
thresholds=thresholds,
|
| 987 |
highlight_threshold=threshold_value,
|
| 988 |
+
qubit_coords=qubit_coords,
|
| 989 |
)
|
| 990 |
notes.append("Plotly unavailable in this runtime; using static heatmap.")
|
| 991 |
else:
|
|
|
|
| 999 |
weights=weights,
|
| 1000 |
thresholds=thresholds,
|
| 1001 |
highlight_threshold=threshold_value,
|
| 1002 |
+
qubit_coords=qubit_coords,
|
| 1003 |
)
|
| 1004 |
|
| 1005 |
metrics, meta = compute_metrics_from_csv(
|
|
|
|
| 1010 |
weights=weights,
|
| 1011 |
thresholds=thresholds,
|
| 1012 |
)
|
| 1013 |
+
hotspot_rows = _hotspot_rows(
|
| 1014 |
+
metrics,
|
| 1015 |
+
int(n_qubits),
|
| 1016 |
+
int(top_k),
|
| 1017 |
+
qubit_coords=qubit_coords,
|
| 1018 |
+
)
|
| 1019 |
note = notes
|
| 1020 |
+
if layout_meta.get("source") == "uploaded":
|
| 1021 |
+
note.append(
|
| 1022 |
+
"Layout map uploaded: "
|
| 1023 |
+
f"mapped={int(layout_meta.get('mapped', 0))}, "
|
| 1024 |
+
f"fallback={int(layout_meta.get('fallback', 0))}, "
|
| 1025 |
+
f"skipped={int(layout_meta.get('skipped', 0))}, "
|
| 1026 |
+
f"duplicates={int(layout_meta.get('duplicates', 0))}"
|
| 1027 |
+
)
|
| 1028 |
+
else:
|
| 1029 |
+
note.append("Layout map: using default row-major mapping.")
|
| 1030 |
skipped = int(meta.get("skipped_rows", 0))
|
| 1031 |
if skipped:
|
| 1032 |
note.append(f"Skipped malformed CSV rows: {skipped}")
|
|
|
|
| 1037 |
if fidelity_backend:
|
| 1038 |
note.append(f"Fidelity backend: {fidelity_backend}")
|
| 1039 |
summary = " | ".join(note) if note else "Hotspot ranking updated."
|
| 1040 |
+
detail_md = _hotspot_detail_markdown(
|
| 1041 |
+
metrics,
|
| 1042 |
+
meta,
|
| 1043 |
+
int(n_qubits),
|
| 1044 |
+
int(focus_qubit),
|
| 1045 |
+
qubit_coords=qubit_coords,
|
| 1046 |
+
)
|
| 1047 |
detail_fig = _hotspot_detail_plot(metrics, meta, int(n_qubits), int(focus_qubit))
|
| 1048 |
return fig, summary, hotspot_rows, detail_md, detail_fig
|
| 1049 |
|
|
|
|
| 1088 |
chip_cols,
|
| 1089 |
heat_metric,
|
| 1090 |
heat_render_mode,
|
| 1091 |
+
layout_csv_file,
|
| 1092 |
calibration_json,
|
| 1093 |
w_activity,
|
| 1094 |
w_gate,
|
|
|
|
| 1126 |
inputs=[
|
| 1127 |
qc_state,
|
| 1128 |
n_qubits,
|
| 1129 |
+
chip_rows,
|
| 1130 |
+
chip_cols,
|
| 1131 |
+
layout_csv_file,
|
| 1132 |
calibration_json,
|
| 1133 |
w_activity,
|
| 1134 |
w_gate,
|
|
|
|
| 1146 |
inputs=[
|
| 1147 |
qc_state,
|
| 1148 |
n_qubits,
|
| 1149 |
+
chip_rows,
|
| 1150 |
+
chip_cols,
|
| 1151 |
+
layout_csv_file,
|
| 1152 |
calibration_json,
|
| 1153 |
w_activity,
|
| 1154 |
w_gate,
|