1 from __future__
import annotations
3 from typing
import Any, Iterable, Mapping, cast
6 qgd_Variational_Quantum_Eigensolver_Base,
9 from squander.partitioning.noisy_types
import (
10 PARTITIONED_DENSITY_MODE,
12 SUPPORTED_NOISE_NAMES,
13 SUPPORTED_PLANNER_SOURCE_TYPES,
15 PLANNER_OP_KIND_NOISE,
17 PlannerOperationKindWire,
18 CanonicalNoisyPlannerOperation,
19 CanonicalNoisyPlannerSurface,
21 from squander.partitioning.noisy_validation_errors
import NoisyPlannerValidationError
24 normalized = name.strip()
31 return aliases.get(normalized.lower(), normalized.upper())
35 normalized = name.strip()
37 "localdepolarizing":
"local_depolarizing",
38 "local_depolarizing":
"local_depolarizing",
39 "depolarizing":
"depolarizing",
40 "amplitudedamping":
"amplitude_damping",
41 "amplitude_damping":
"amplitude_damping",
42 "phasedamping":
"phase_damping",
43 "phase_damping":
"phase_damping",
44 "dephasing":
"phase_damping",
46 return aliases.get(normalized.replace(
" ",
"").lower(), normalized.lower())
51 if raw_kind
not in PLANNER_OP_KINDS:
53 "Unsupported planner kind '{}', expected one of {}".format(
54 raw_kind, sorted(PLANNER_OP_KINDS)
57 return cast(PlannerOperationKindWire, raw_kind)
61 if kind == PLANNER_OP_KIND_GATE:
63 if kind == PLANNER_OP_KIND_NOISE:
81 payload: Mapping[str, Any], *, fallback_index: int
82 ) -> CanonicalNoisyPlannerOperation:
85 return CanonicalNoisyPlannerOperation(
86 index=
int(payload.get(
"index", fallback_index)),
89 is_unitary=
bool(payload[
"is_unitary"]),
90 source_gate_index=
int(payload[
"source_gate_index"]),
93 param_count=
int(payload[
"param_count"]),
94 param_start=
int(payload[
"param_start"]),
100 payload: Mapping[str, Any],
103 default_param_start: int,
105 ) -> CanonicalNoisyPlannerOperation:
108 return CanonicalNoisyPlannerOperation(
112 is_unitary=
bool(payload.get(
"is_unitary", kind == PLANNER_OP_KIND_GATE)),
113 source_gate_index=
int(payload.get(
"source_gate_index", gate_index)),
116 param_count=
int(payload.get(
"param_count", 0)),
117 param_start=
int(payload.get(
"param_start", default_param_start)),
122 def _validate_mode(requested_mode: str, *, stage: str, source_type: str) ->
None:
123 if requested_mode != PARTITIONED_DENSITY_MODE:
124 raise NoisyPlannerValidationError(
126 first_unsupported_condition=
"unsupported_mode",
128 source_type=source_type,
129 requested_mode=requested_mode,
131 "Phase 3 canonical planner surface supports only '{}' requests, got " 132 "'{}'".format(PARTITIONED_DENSITY_MODE, requested_mode)
138 surface: CanonicalNoisyPlannerSurface,
141 strict_phase3_support: bool,
142 ) -> CanonicalNoisyPlannerSurface:
143 if surface.qbit_num <= 0:
144 raise ValueError(
"Canonical planner surface requires qbit_num > 0")
145 if surface.parameter_count < 0:
146 raise ValueError(
"Canonical planner surface requires parameter_count >= 0")
147 if not surface.operations:
148 raise ValueError(
"Canonical planner surface requires at least one operation")
152 seen_param_starts: list[int] = []
153 for operation
in surface.operations:
154 if operation.index != expected_index:
156 "Canonical planner operations must use contiguous indices starting at 0" 158 if operation.param_start < 0
or operation.param_count < 0:
160 "Planner operation parameter metadata must be non-negative" 162 seen_param_starts.append(operation.param_start)
164 if operation.kind == PLANNER_OP_KIND_GATE:
166 if operation.target_qbit
is None:
168 "{} planner records must provide target_qbit".format(
172 if strict_phase3_support
and operation.name
not in SUPPORTED_GATE_NAMES:
173 raise NoisyPlannerValidationError(
174 category=
"gate_family",
175 first_unsupported_condition=operation.name,
177 source_type=surface.source_type,
178 requested_mode=surface.requested_mode,
180 "Unsupported Phase 3 planner gate '{}' in canonical surface" 181 ).format(operation.name),
183 elif operation.kind == PLANNER_OP_KIND_NOISE:
184 if operation.target_qbit
is None:
186 "{} planner records must provide target_qbit".format(
187 PLANNER_OP_KIND_NOISE
191 operation.source_gate_index < 0
192 or operation.source_gate_index >= gate_count
194 raise NoisyPlannerValidationError(
195 category=
"noise_insertion",
196 first_unsupported_condition=
"after_gate_index",
198 source_type=surface.source_type,
199 requested_mode=surface.requested_mode,
201 "Canonical planner noise operation references unsupported " 202 "after_gate_index {}".format(operation.source_gate_index)
205 if strict_phase3_support
and operation.name
not in SUPPORTED_NOISE_NAMES:
206 raise NoisyPlannerValidationError(
207 category=
"noise_type",
208 first_unsupported_condition=operation.name,
210 source_type=surface.source_type,
211 requested_mode=surface.requested_mode,
213 "Unsupported Phase 3 planner noise model '{}' in canonical " 215 ).format(operation.name),
218 raise ValueError(
"Unsupported planner kind '{}'".format(operation.kind))
222 if seen_param_starts != sorted(seen_param_starts):
224 "Canonical planner operations must preserve monotonically increasing " 232 bridge_metadata: Mapping[str, Any],
235 requested_mode: str = PARTITIONED_DENSITY_MODE,
236 source_type: str |
None =
None,
237 strict_phase3_support: bool =
True,
238 ) -> CanonicalNoisyPlannerSurface:
239 resolved_source_type = str(source_type
or bridge_metadata[
"source_type"])
242 stage=
"planner_entry_from_bridge_metadata_preflight",
243 source_type=resolved_source_type,
248 for index, payload
in enumerate(bridge_metadata[
"operations"])
251 surface = CanonicalNoisyPlannerSurface(
252 requested_mode=requested_mode,
253 source_type=resolved_source_type,
254 workload_id=workload_id,
255 qbit_num=
int(bridge_metadata[
"qbit_num"]),
256 parameter_count=
int(bridge_metadata[
"parameter_count"]),
257 operations=operations,
261 stage=
"planner_entry_from_bridge_metadata_preflight",
262 strict_phase3_support=strict_phase3_support,
271 operation_specs: Iterable[Mapping[str, Any]],
272 requested_mode: str = PARTITIONED_DENSITY_MODE,
273 strict_phase3_support: bool =
True,
274 ) -> CanonicalNoisyPlannerSurface:
277 stage=
"planner_entry_from_operation_specs_preflight",
278 source_type=source_type,
281 canonical_operations: list[CanonicalNoisyPlannerOperation] = []
284 for index, payload
in enumerate(operation_specs):
286 if kind == PLANNER_OP_KIND_GATE:
291 default_param_start=param_start,
292 gate_index=gate_index,
294 canonical_operations.append(operation)
295 param_start = max(param_start, operation.param_start + operation.param_count)
297 surface = CanonicalNoisyPlannerSurface(
298 requested_mode=requested_mode,
299 source_type=source_type,
300 workload_id=workload_id,
301 qbit_num=
int(qbit_num),
304 operation.param_start + operation.param_count
305 for operation
in canonical_operations
309 operations=tuple(canonical_operations),
313 stage=
"planner_entry_from_operation_specs_preflight",
314 strict_phase3_support=strict_phase3_support,
319 spec: Mapping[str, Any],
326 return float(spec[
"value"])
328 "local_depolarizing":
"error_rate",
329 "amplitude_damping":
"gamma",
330 "phase_damping":
"lambda",
332 value_key = key_by_channel.get(channel)
333 if value_key
is None or value_key
not in spec:
334 raise NoisyPlannerValidationError(
335 category=
"noise_type",
336 first_unsupported_condition=channel,
337 failure_stage=
"planner_entry_preflight",
338 source_type=source_type,
339 requested_mode=requested_mode,
341 "Legacy-source planner lowering requires an explicit fixed value for " 342 "noise channel '{}'".format(channel)
345 return float(spec[value_key])
349 density_noise: Iterable[Mapping[str, Any]],
354 ) -> list[dict[str, Any]]:
355 normalized_specs: list[dict[str, Any]] = []
356 for spec
in density_noise:
358 if channel
not in SUPPORTED_NOISE_NAMES:
359 raise NoisyPlannerValidationError(
360 category=
"noise_type",
361 first_unsupported_condition=channel,
362 failure_stage=
"planner_entry_preflight",
363 source_type=source_type,
364 requested_mode=requested_mode,
366 "Unsupported Phase 3 planner noise model '{}' in legacy-source " 367 "lowering".format(channel)
370 after_gate_index =
int(spec[
"after_gate_index"])
371 if after_gate_index < 0
or after_gate_index >= gate_count:
372 raise NoisyPlannerValidationError(
373 category=
"noise_insertion",
374 first_unsupported_condition=
"after_gate_index",
375 failure_stage=
"planner_entry_preflight",
376 source_type=source_type,
377 requested_mode=requested_mode,
379 "Legacy-source planner lowering references unsupported " 380 "after_gate_index {}".format(after_gate_index)
383 normalized_specs.append(
387 "target_qbit":
int(spec[
"target"]),
388 "source_gate_index": after_gate_index,
392 source_type=source_type,
393 requested_mode=requested_mode,
398 return normalized_specs
405 density_noise: Iterable[Mapping[str, Any]] |
None =
None,
406 requested_mode: str = PARTITIONED_DENSITY_MODE,
407 source_type: str =
"legacy_qgd_circuit_exact",
408 strict_phase3_support: bool =
True,
409 ) -> CanonicalNoisyPlannerSurface:
412 stage=
"planner_entry_preflight",
413 source_type=source_type,
416 required_methods = (
"get_Gates",
"get_Qbit_Num")
417 if any(
not hasattr(legacy_circuit, method)
for method
in required_methods):
418 raise NoisyPlannerValidationError(
419 category=
"source_type",
420 first_unsupported_condition=
"legacy_source_type",
421 failure_stage=
"planner_entry_preflight",
422 source_type=source_type,
423 requested_mode=requested_mode,
425 "Legacy-source planner lowering requires a qgd_Circuit- or " 426 "Gates_block-like object exposing get_Gates() and get_Qbit_Num()" 430 gate_specs: list[dict[str, Any]] = []
431 for gate
in legacy_circuit.get_Gates():
433 if strict_phase3_support
and gate_name
not in SUPPORTED_GATE_NAMES:
434 raise NoisyPlannerValidationError(
435 category=
"gate_family",
436 first_unsupported_condition=gate_name,
437 failure_stage=
"planner_entry_preflight",
438 source_type=source_type,
439 requested_mode=requested_mode,
441 "Unsupported Phase 3 planner gate '{}' in legacy-source lowering" 447 "target_qbit":
int(gate.get_Target_Qbit()),
448 "param_count":
int(gate.get_Parameter_Num()),
449 "param_start":
int(gate.get_Parameter_Start_Index()),
451 if hasattr(gate,
"get_Control_Qbit"):
452 control_qbit =
int(gate.get_Control_Qbit())
453 if control_qbit >= 0:
454 spec[
"control_qbit"] = control_qbit
455 gate_specs.append(spec)
458 raise NoisyPlannerValidationError(
459 category=
"source_type",
460 first_unsupported_condition=
"empty_legacy_circuit",
461 failure_stage=
"planner_entry_preflight",
462 source_type=source_type,
463 requested_mode=requested_mode,
464 reason=
"Legacy-source planner lowering requires at least one supported gate",
468 []
if density_noise
is None else density_noise,
469 gate_count=len(gate_specs),
470 source_type=source_type,
471 requested_mode=requested_mode,
474 noise_by_gate: dict[int, list[dict[str, Any]]] = {}
475 for noise_spec
in noise_specs:
476 noise_by_gate.setdefault(noise_spec[
"source_gate_index"], []).append(noise_spec)
478 operation_specs: list[dict[str, Any]] = []
479 for gate_index, gate_spec
in enumerate(gate_specs):
480 operation_specs.append(gate_spec)
481 operation_specs.extend(noise_by_gate.get(gate_index, []))
484 qbit_num=
int(legacy_circuit.get_Qbit_Num()),
485 source_type=source_type,
486 workload_id=workload_id,
487 operation_specs=operation_specs,
488 requested_mode=requested_mode,
489 strict_phase3_support=strict_phase3_support,
497 density_noise: Iterable[Mapping[str, Any]] |
None =
None,
498 requested_mode: str = PARTITIONED_DENSITY_MODE,
499 strict_phase3_support: bool =
True,
500 ) -> CanonicalNoisyPlannerSurface:
503 workload_id=workload_id,
504 density_noise=density_noise,
505 requested_mode=requested_mode,
506 source_type=
"legacy_qgd_circuit_exact",
507 strict_phase3_support=strict_phase3_support,
515 requested_mode: str = PARTITIONED_DENSITY_MODE,
516 bridge_metadata: Mapping[str, Any] |
None =
None,
517 operation_specs: Iterable[Mapping[str, Any]] |
None =
None,
518 qbit_num: int |
None =
None,
519 legacy_circuit: Any |
None =
None,
520 density_noise: Iterable[Mapping[str, Any]] |
None =
None,
521 strict_phase3_support: bool =
True,
522 ) -> CanonicalNoisyPlannerSurface:
523 resolved_source_type = str(source_type)
524 if resolved_source_type
not in SUPPORTED_PLANNER_SOURCE_TYPES:
525 raise NoisyPlannerValidationError(
526 category=
"source_type",
527 first_unsupported_condition=resolved_source_type,
528 failure_stage=
"planner_entry_preflight",
529 source_type=resolved_source_type,
530 requested_mode=requested_mode,
532 "Unsupported Phase 3 planner source type '{}'".format(
538 provided_payload_count = sum(
540 for payload
in (bridge_metadata, operation_specs, legacy_circuit)
542 if provided_payload_count != 1:
543 raise NoisyPlannerValidationError(
544 category=
"malformed_request",
545 first_unsupported_condition=(
546 "missing_source_payload" 547 if provided_payload_count == 0
548 else "ambiguous_source_payload" 550 failure_stage=
"planner_entry_preflight",
551 source_type=resolved_source_type,
552 requested_mode=requested_mode,
554 "Phase 3 planner preflight requires exactly one source payload " 555 "(bridge_metadata, operation_specs, or legacy_circuit)" 559 if bridge_metadata
is not None:
562 workload_id=workload_id,
563 requested_mode=requested_mode,
564 source_type=resolved_source_type,
565 strict_phase3_support=strict_phase3_support,
568 if operation_specs
is not None:
570 raise NoisyPlannerValidationError(
571 category=
"malformed_request",
572 first_unsupported_condition=
"missing_qbit_num",
573 failure_stage=
"planner_entry_preflight",
574 source_type=resolved_source_type,
575 requested_mode=requested_mode,
576 reason=
"Operation-spec planner preflight requires qbit_num",
580 source_type=resolved_source_type,
581 workload_id=workload_id,
582 operation_specs=operation_specs,
583 requested_mode=requested_mode,
584 strict_phase3_support=strict_phase3_support,
589 workload_id=workload_id,
590 density_noise=density_noise,
591 requested_mode=requested_mode,
592 source_type=resolved_source_type,
593 strict_phase3_support=strict_phase3_support,
604 vqe: qgd_Variational_Quantum_Eigensolver_Base,
606 workload_id: str |
None =
None,
607 requested_mode: str = PARTITIONED_DENSITY_MODE,
608 ) -> CanonicalNoisyPlannerSurface:
609 bridge_metadata = vqe.describe_density_bridge()
610 resolved_workload_id = workload_id
or "phase2_xxz_hea_q{}_continuity".format(
611 bridge_metadata[
"qbit_num"]
615 workload_id=resolved_workload_id,
616 requested_mode=requested_mode,
617 strict_phase3_support=
True,
622 surface: CanonicalNoisyPlannerSurface,
624 metadata: Mapping[str, Any] |
None =
None,
626 payload = surface.to_dict()
628 "requested_mode": payload[
"requested_mode"],
629 "provenance": payload[
"provenance"],
631 "qbit_num": payload[
"qbit_num"],
632 "parameter_count": payload[
"parameter_count"],
633 "operation_count": payload[
"operation_count"],
634 "gate_count": payload[
"gate_count"],
635 "noise_count": payload[
"noise_count"],
636 "gate_sequence": payload[
"gate_sequence"],
637 "noise_sequence": payload[
"noise_sequence"],
638 "max_qubit_span": payload[
"max_qubit_span"],
640 "operations": payload[
"operations"],
641 "metadata": dict(metadata)
if metadata
is not None else {},
651 surface: CanonicalNoisyPlannerSurface, bridge_metadata: Mapping[str, Any]
653 payload = surface.to_dict()
654 mismatches: list[dict[str, Any]] = []
656 for key
in (
"parameter_count",
"operation_count",
"gate_count",
"noise_count"):
657 if payload[key] != bridge_metadata[key]:
662 "actual": payload[key],
663 "expected": bridge_metadata[key],
667 for index, (actual, expected)
in enumerate(
668 zip(payload[
"operations"], bridge_metadata[
"operations"])
681 if actual[key] != expected[key]:
687 "actual": actual[key],
688 "expected": expected[key],
693 for q
in (expected[
"control_qbit"], expected[
"target_qbit"])
696 if actual[
"qubit_support"] != expected_support:
701 "field":
"qubit_support",
702 "actual": actual[
"qubit_support"],
703 "expected": expected_support,
708 "bridge_overlap_pass":
not mismatches,
709 "mismatches": mismatches,
710 "compared_operation_count": min(
711 len(payload[
"operations"]), len(bridge_metadata[
"operations"])
def _normalize_legacy_noise_specs
def _extract_legacy_noise_value
def build_bridge_overlap_report
Build a bridge overlap report from a canonical planner surface and a bridge metadata.
def _normalize_noise_name
def build_canonical_planner_surface_from_bridge_metadata
def _coerce_optional_float
def build_phase3_continuity_planner_surface
Build a canonical planner surface from a Phase 2 continuity VQE instance.
def _build_operation_from_mapping
def _canonicalize_operation_name
def build_planner_audit_record
def build_canonical_planner_surface_from_operation_specs
def _build_operation_from_spec
def preflight_planner_request
def _coerce_operation_kind
def build_canonical_planner_surface_from_legacy_circuit
def build_canonical_planner_surface_from_qgd_circuit