Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
signals.py
Go to the documentation of this file.
1 from __future__ import annotations
2 
3 from collections import defaultdict
4 from statistics import median
5 
6 from squander.partitioning.noisy_runtime import PHASE3_FUSION_CLASS_SUPPORTED_UNFUSED
7 
8 PLANNER_CALIBRATION_DENSITY_SIGNAL_SCHEMA_VERSION = "phase3_planner_calibration_density_signal_v1"
9 PLANNER_CALIBRATION_STATE_VECTOR_PROXY_NAME = "state_vector_partition_proxy_v1"
10 PLANNER_CALIBRATION_DENSITY_AWARE_OBJECTIVE_NAME = "phase3_benchmark_cost_v1"
11 
12 
13 def build_state_vector_proxy_score(descriptor_set) -> float:
14  descriptor_member_count = max(descriptor_set.descriptor_member_count, 1)
15  return sum(
16  (2 ** len(partition.local_to_global_qbits)) * partition.member_count
17  for partition in descriptor_set.partitions
18  ) / descriptor_member_count
19 
20 
21 def build_density_partition_cost(descriptor_set) -> float:
22  descriptor_member_count = max(descriptor_set.descriptor_member_count, 1)
23  return sum(
24  (4 ** len(partition.local_to_global_qbits)) * partition.member_count
25  for partition in descriptor_set.partitions
26  ) / descriptor_member_count
27 
28 
29 def count_eligible_unitary_regions(runtime_result) -> int:
30  return sum(
31  region.classification == PHASE3_FUSION_CLASS_SUPPORTED_UNFUSED
32  and region.reason == "fusion_disabled"
33  for region in runtime_result.fused_regions
34  )
35 
36 
38  metadata: dict,
39  descriptor_set,
40  runtime_result,
41  density_metrics: dict,
42 ) -> dict:
43  peak_rss_mb = runtime_result.peak_rss_kb / 1024.0
44  descriptor_member_count = max(descriptor_set.descriptor_member_count, 1)
45  partition_count = max(descriptor_set.partition_count, 1)
46  return {
47  "signal_schema_version": PLANNER_CALIBRATION_DENSITY_SIGNAL_SCHEMA_VERSION,
48  "candidate_id": metadata["candidate_id"],
49  "planner_family": metadata["planner_family"],
50  "planner_variant": metadata["planner_variant"],
51  "max_partition_qubits": metadata["max_partition_qubits"],
52  "case_kind": metadata["case_kind"],
53  "workload_id": metadata["workload_id"],
54  "workload_family": metadata["workload_family"],
55  "qbit_num": metadata["qbit_num"],
56  "family_name": metadata["family_name"],
57  "noise_pattern": metadata["noise_pattern"],
58  "planning_time_ms": metadata["planning_time_ms"],
59  "runtime_path": runtime_result.runtime_path,
60  "runtime_ms": runtime_result.runtime_ms,
61  "peak_rss_kb": runtime_result.peak_rss_kb,
62  "peak_rss_mb": peak_rss_mb,
63  "partition_count": descriptor_set.partition_count,
64  "max_partition_span": descriptor_set.max_partition_span,
65  "descriptor_member_count": descriptor_set.descriptor_member_count,
66  "noise_count": descriptor_set.noise_count,
67  "noise_density": descriptor_set.noise_count / descriptor_member_count,
68  "density_partition_cost": build_density_partition_cost(descriptor_set),
69  "eligible_unitary_region_count": count_eligible_unitary_regions(runtime_result),
70  "eligible_unitary_region_fraction": (
71  count_eligible_unitary_regions(runtime_result) / partition_count
72  ),
73  "supported_unfused_region_count": runtime_result.supported_unfused_region_count,
74  "deferred_region_count": runtime_result.deferred_region_count,
75  "actual_fused_execution": runtime_result.actual_fused_execution,
76  "state_vector_proxy_name": PLANNER_CALIBRATION_STATE_VECTOR_PROXY_NAME,
77  "state_vector_proxy_score": build_state_vector_proxy_score(descriptor_set),
78  "frobenius_norm_diff": density_metrics["frobenius_norm_diff"],
79  "max_abs_diff": density_metrics["max_abs_diff"],
80  }
81 
82 
83 def calibrate_memory_weight(records: list[dict]) -> float:
84  peak_rss_mb_values = [record["peak_rss_mb"] for record in records if record["peak_rss_mb"] > 0.0]
85  runtime_values = [record["runtime_ms"] for record in records if record["runtime_ms"] > 0.0]
86  if not peak_rss_mb_values or not runtime_values:
87  return 0.0
88  return float(median(runtime_values) / median(peak_rss_mb_values))
89 
90 
91 def build_density_aware_score(record: dict, *, memory_weight: float) -> float:
92  return float(
93  record["runtime_ms"]
94  + record["planning_time_ms"]
95  + memory_weight * record["peak_rss_mb"]
96  )
97 
98 
100  records: list[dict], *, objective_name: str = PLANNER_CALIBRATION_DENSITY_AWARE_OBJECTIVE_NAME
101 ) -> list[dict]:
102  calibrated_memory_weight = calibrate_memory_weight(records)
103  for record in records:
104  record["density_aware_objective_name"] = objective_name
105  record["calibrated_memory_weight"] = calibrated_memory_weight
106  record["density_aware_score"] = build_density_aware_score(
107  record, memory_weight=calibrated_memory_weight
108  )
109 
110  grouped_records: dict[str, list[dict]] = defaultdict(list)
111  for record in records:
112  grouped_records[record["workload_id"]].append(record)
113 
114  for workload_records in grouped_records.values():
115  density_sorted = sorted(
116  workload_records,
117  key=lambda record: (record["density_aware_score"], record["candidate_id"]),
118  )
119  for index, record in enumerate(density_sorted, start=1):
120  record["density_aware_rank"] = index
121 
122  proxy_sorted = sorted(
123  workload_records,
124  key=lambda record: (record["state_vector_proxy_score"], record["candidate_id"]),
125  )
126  for index, record in enumerate(proxy_sorted, start=1):
127  record["state_vector_proxy_rank"] = index
128 
129  return records
def build_density_partition_cost(descriptor_set)
Definition: signals.py:21
def apply_density_scores_and_rankings
Definition: signals.py:100
def count_eligible_unitary_regions(runtime_result)
Definition: signals.py:29
def build_density_aware_score
Definition: signals.py:91
def build_state_vector_proxy_score(descriptor_set)
Definition: signals.py:13
def build_density_signal_record
Definition: signals.py:38
def calibrate_memory_weight
Definition: signals.py:83