hchevva commited on
Commit
b59c2e9
·
verified ·
1 Parent(s): 161f80b

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -9
app.py CHANGED
@@ -13,7 +13,12 @@ from quread.circuit_diagram import draw_circuit_svg
13
  from quread.cost_guard import allow_request
14
  from quread.export_pdf import md_to_pdf
15
  from quread.heatmap import make_metric_heatmap, HeatmapConfig
16
- from quread.metrics import compute_metrics_from_csv, to_metrics_csv
 
 
 
 
 
17
 
18
  # --- Qubit cap (configurable) ---
19
  DEFAULT_MAX_QUBITS = 16 # safe default for CPU Spaces; change if you want
@@ -180,6 +185,53 @@ def _on_qubit_count_change(n):
180
  return qc, last_counts, selected_gate, t, c, ct, msg
181
 
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  # ---------- Styling ----------
184
  CSS = """
185
  #title h1 { font-size: 42px !important; margin-bottom: 6px; }
@@ -319,9 +371,36 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
319
  label="Calibration JSON (optional)",
320
  placeholder='{"qubits":{"0":{"gate_error":0.012,"readout_error":0.02,"t1_us":82,"t2_us":61,"fidelity":0.991}}}',
321
  )
 
 
 
 
 
 
 
 
 
 
 
 
322
  metrics_csv_dl = gr.DownloadButton("Download metrics CSV")
323
  heat_btn = gr.Button("Generate heatmap from CSV", variant="secondary")
324
  heat_plot = gr.Plot()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
 
327
  with gr.Group(elem_classes=["card"]):
@@ -445,35 +524,126 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
445
  outputs=[llm_out, last_explained_hash, explanation_md],
446
  )
447
 
448
- def _heat_from_current(qc, n_qubits, rows, cols, metric, calibration_text):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
  csv_text = to_csv(qc.history) # must exist from Task 2A
450
  cfg = HeatmapConfig(rows=int(rows), cols=int(cols))
451
- return make_metric_heatmap(
 
 
 
 
 
 
 
 
 
452
  csv_text=csv_text,
453
  n_qubits=int(n_qubits),
454
  metric=str(metric),
455
  cfg=cfg,
456
  calibration_json=str(calibration_text or ""),
 
 
457
  )
458
-
459
- def _dl_metrics_csv(qc, n_qubits, calibration_text):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  csv_text = to_csv(qc.history)
 
 
 
 
 
 
 
 
 
461
  metrics, _meta = compute_metrics_from_csv(
462
  csv_text,
463
  int(n_qubits),
464
  calibration_json=str(calibration_text or ""),
 
 
465
  )
466
  return _write_tmp("qubit_metrics.csv", to_metrics_csv(metrics))
467
 
468
  heat_btn.click(
469
- fn=_heat_from_current,
470
- inputs=[qc_state, n_qubits, chip_rows, chip_cols, heat_metric, calibration_json],
471
- outputs=[heat_plot],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
  )
473
 
474
  metrics_csv_dl.click(
475
  fn=_dl_metrics_csv,
476
- inputs=[qc_state, n_qubits, calibration_json],
 
 
 
 
 
 
 
 
 
 
 
477
  outputs=[metrics_csv_dl],
478
  )
479
 
 
13
  from quread.cost_guard import allow_request
14
  from quread.export_pdf import md_to_pdf
15
  from quread.heatmap import make_metric_heatmap, HeatmapConfig
16
+ from quread.metrics import (
17
+ compute_metrics_from_csv,
18
+ to_metrics_csv,
19
+ MetricWeights,
20
+ MetricThresholds,
21
+ )
22
 
23
  # --- Qubit cap (configurable) ---
24
  DEFAULT_MAX_QUBITS = 16 # safe default for CPU Spaces; change if you want
 
185
  return qc, last_counts, selected_gate, t, c, ct, msg
186
 
187
 
188
+ def _metric_controls_to_models(
189
+ activity_w,
190
+ gate_error_w,
191
+ readout_error_w,
192
+ decoherence_w,
193
+ fidelity_w,
194
+ warning_thr,
195
+ critical_thr,
196
+ ):
197
+ weights = MetricWeights(
198
+ activity=float(activity_w),
199
+ gate_error=float(gate_error_w),
200
+ readout_error=float(readout_error_w),
201
+ decoherence=float(decoherence_w),
202
+ fidelity=float(fidelity_w),
203
+ )
204
+ thresholds = MetricThresholds(
205
+ warning=float(warning_thr),
206
+ critical=float(critical_thr),
207
+ )
208
+ return weights, thresholds
209
+
210
+
211
+ def _hotspot_rows(metrics, n_qubits, top_k):
212
+ rows = []
213
+ n = int(n_qubits)
214
+ for q in range(n):
215
+ risk = float(metrics["composite_risk"][q])
216
+ level = int(metrics["hotspot_level"][q])
217
+ status = "critical" if level == 2 else ("warning" if level == 1 else "ok")
218
+ rows.append(
219
+ [
220
+ q,
221
+ status,
222
+ round(risk, 6),
223
+ round(float(metrics["activity_count"][q]), 3),
224
+ round(float(metrics["gate_error"][q]), 6),
225
+ round(float(metrics["readout_error"][q]), 6),
226
+ round(float(metrics["decoherence_risk"][q]), 6),
227
+ round(float(metrics["fidelity"][q]), 6),
228
+ ]
229
+ )
230
+ rows.sort(key=lambda x: x[2], reverse=True)
231
+ k = max(1, min(int(top_k), len(rows)))
232
+ return rows[:k]
233
+
234
+
235
  # ---------- Styling ----------
236
  CSS = """
237
  #title h1 { font-size: 42px !important; margin-bottom: 6px; }
 
371
  label="Calibration JSON (optional)",
372
  placeholder='{"qubits":{"0":{"gate_error":0.012,"readout_error":0.02,"t1_us":82,"t2_us":61,"fidelity":0.991}}}',
373
  )
374
+ gr.Markdown("<div class='small-note'>Composite risk weights are normalized automatically.</div>")
375
+ with gr.Row():
376
+ w_activity = gr.Slider(0.0, 1.0, value=0.25, step=0.01, label="Weight: activity")
377
+ w_gate = gr.Slider(0.0, 1.0, value=0.20, step=0.01, label="Weight: gate error")
378
+ w_readout = gr.Slider(0.0, 1.0, value=0.15, step=0.01, label="Weight: readout error")
379
+ with gr.Row():
380
+ w_decoherence = gr.Slider(0.0, 1.0, value=0.25, step=0.01, label="Weight: decoherence")
381
+ w_fidelity = gr.Slider(0.0, 1.0, value=0.15, step=0.01, label="Weight: fidelity risk")
382
+ with gr.Row():
383
+ thr_warning = gr.Slider(0.0, 1.0, value=0.45, step=0.01, label="Threshold: warning")
384
+ thr_critical = gr.Slider(0.0, 1.0, value=0.70, step=0.01, label="Threshold: critical")
385
+ hotspot_top_k = gr.Slider(1, 64, value=16, step=1, label="Hotspot rows")
386
  metrics_csv_dl = gr.DownloadButton("Download metrics CSV")
387
  heat_btn = gr.Button("Generate heatmap from CSV", variant="secondary")
388
  heat_plot = gr.Plot()
389
+ hotspot_status = gr.Markdown()
390
+ hotspot_table = gr.Dataframe(
391
+ headers=[
392
+ "qubit",
393
+ "status",
394
+ "composite_risk",
395
+ "activity_count",
396
+ "gate_error",
397
+ "readout_error",
398
+ "decoherence_risk",
399
+ "fidelity",
400
+ ],
401
+ interactive=False,
402
+ label="Hotspot ranking (highest composite risk first)",
403
+ )
404
 
405
 
406
  with gr.Group(elem_classes=["card"]):
 
524
  outputs=[llm_out, last_explained_hash, explanation_md],
525
  )
526
 
527
+ def _heat_and_hotspots_from_current(
528
+ qc,
529
+ n_qubits,
530
+ rows,
531
+ cols,
532
+ metric,
533
+ calibration_text,
534
+ activity_w,
535
+ gate_error_w,
536
+ readout_error_w,
537
+ decoherence_w,
538
+ fidelity_w,
539
+ warning_thr,
540
+ critical_thr,
541
+ top_k,
542
+ ):
543
  csv_text = to_csv(qc.history) # must exist from Task 2A
544
  cfg = HeatmapConfig(rows=int(rows), cols=int(cols))
545
+ weights, thresholds = _metric_controls_to_models(
546
+ activity_w,
547
+ gate_error_w,
548
+ readout_error_w,
549
+ decoherence_w,
550
+ fidelity_w,
551
+ warning_thr,
552
+ critical_thr,
553
+ )
554
+ fig = make_metric_heatmap(
555
  csv_text=csv_text,
556
  n_qubits=int(n_qubits),
557
  metric=str(metric),
558
  cfg=cfg,
559
  calibration_json=str(calibration_text or ""),
560
+ weights=weights,
561
+ thresholds=thresholds,
562
  )
563
+ metrics, meta = compute_metrics_from_csv(
564
+ csv_text,
565
+ int(n_qubits),
566
+ calibration_json=str(calibration_text or ""),
567
+ weights=weights,
568
+ thresholds=thresholds,
569
+ )
570
+ hotspot_rows = _hotspot_rows(metrics, int(n_qubits), int(top_k))
571
+ note = []
572
+ skipped = int(meta.get("skipped_rows", 0))
573
+ if skipped:
574
+ note.append(f"Skipped malformed CSV rows: {skipped}")
575
+ calibration_note = str(meta.get("calibration_note", "") or "").strip()
576
+ if calibration_note:
577
+ note.append(calibration_note)
578
+ summary = " | ".join(note) if note else "Hotspot ranking updated."
579
+ return fig, summary, hotspot_rows
580
+
581
+ def _dl_metrics_csv(
582
+ qc,
583
+ n_qubits,
584
+ calibration_text,
585
+ activity_w,
586
+ gate_error_w,
587
+ readout_error_w,
588
+ decoherence_w,
589
+ fidelity_w,
590
+ warning_thr,
591
+ critical_thr,
592
+ ):
593
  csv_text = to_csv(qc.history)
594
+ weights, thresholds = _metric_controls_to_models(
595
+ activity_w,
596
+ gate_error_w,
597
+ readout_error_w,
598
+ decoherence_w,
599
+ fidelity_w,
600
+ warning_thr,
601
+ critical_thr,
602
+ )
603
  metrics, _meta = compute_metrics_from_csv(
604
  csv_text,
605
  int(n_qubits),
606
  calibration_json=str(calibration_text or ""),
607
+ weights=weights,
608
+ thresholds=thresholds,
609
  )
610
  return _write_tmp("qubit_metrics.csv", to_metrics_csv(metrics))
611
 
612
  heat_btn.click(
613
+ fn=_heat_and_hotspots_from_current,
614
+ inputs=[
615
+ qc_state,
616
+ n_qubits,
617
+ chip_rows,
618
+ chip_cols,
619
+ heat_metric,
620
+ calibration_json,
621
+ w_activity,
622
+ w_gate,
623
+ w_readout,
624
+ w_decoherence,
625
+ w_fidelity,
626
+ thr_warning,
627
+ thr_critical,
628
+ hotspot_top_k,
629
+ ],
630
+ outputs=[heat_plot, hotspot_status, hotspot_table],
631
  )
632
 
633
  metrics_csv_dl.click(
634
  fn=_dl_metrics_csv,
635
+ inputs=[
636
+ qc_state,
637
+ n_qubits,
638
+ calibration_json,
639
+ w_activity,
640
+ w_gate,
641
+ w_readout,
642
+ w_decoherence,
643
+ w_fidelity,
644
+ thr_warning,
645
+ thr_critical,
646
+ ],
647
  outputs=[metrics_csv_dl],
648
  )
649