cqlib_core/compile/transform/resynthesis/mod.rs
1// This code is part of Cqlib.
2//
3// (C) Copyright China Telecom Quantum Group 2026
4//
5// This code is licensed under the Apache License, Version 2.0. You may
6// obtain a copy of this license in the LICENSE.txt file in the root directory
7// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8//
9// Any modifications or derivative works of this code must retain this
10// copyright notice, and modified files need to carry a notice indicating
11// that they have been altered from the originals.
12
13//! Numeric block resynthesis transforms.
14//!
15//! This module optimizes already-lowered standard-gate circuits by collecting
16//! fixed-parameter one- and two-qubit operations over the same qubit pair,
17//! rebuilding their exact 4x4 unitary, and resynthesizing that unitary with the
18//! configured two-qubit basis. Maximal uninterrupted pair runs are collected
19//! in one linear pass without a size budget. A bounded dependency collector
20//! then supplements them with candidates that require legal commutation
21//! crossing. A candidate is accepted only when its local cost is strictly lower
22//! and every crossed operation still commutes with the synthesized replacement.
23//!
24//! The pass is intentionally conservative:
25//!
26//! - symbolic parameters, non-standard gates, measurements, resets, delays,
27//! labels, directives, and control-flow instructions are collection
28//! boundaries;
29//! - supplemental commutation-aware collection is bounded by `max_scan_span`,
30//! `max_block_ops`, and `max_crossed_ops`;
31//! - control-flow bodies are optimized recursively, with body-local synthesis
32//! phase emitted as a leading `GPhase`.
33//!
34//! # Example
35//!
36//! ```
37//! use cqlib_core::circuit::{Circuit, Qubit};
38//! use cqlib_core::circuit::{Instruction, StandardGate};
39//! use cqlib_core::compile::transform::{
40//! ResynthesizeTwoQubitBlocks, TransformOutcome, TwoQubitBlockResynthesisConfig, Transformer,
41//! };
42//! use cqlib_core::compile::transform::decompose::unitary::TwoQubitSynthesisTarget;
43//!
44//! let q0 = Qubit::new(0);
45//! let q1 = Qubit::new(1);
46//! let mut circuit = Circuit::new(2);
47//! circuit.cx(q0, q1)?;
48//! circuit.cx(q0, q1)?;
49//!
50//! let target = TwoQubitSynthesisTarget::from_instructions(Some(&[
51//! Instruction::Standard(StandardGate::U),
52//! Instruction::Standard(StandardGate::CX),
53//! ]))?;
54//! let config = TwoQubitBlockResynthesisConfig::normal(target);
55//! let result = ResynthesizeTwoQubitBlocks::new(config).transform(&circuit, None)?;
56//! let TransformOutcome::Changed(resynthesized) = result else {
57//! panic!("the cancelling block should be resynthesized");
58//! };
59//! assert!(resynthesized.operations().is_empty());
60//! # Ok::<(), Box<dyn std::error::Error>>(())
61//! ```
62
63mod collector;
64mod commutation;
65mod config;
66mod cost;
67mod dag_collector;
68mod incremental;
69mod maximal_run;
70mod resynthesizer;
71mod selector;
72mod synthesis_cache;
73
74pub use config::TwoQubitBlockResynthesisConfig;
75pub(crate) use incremental::{
76 NativeResynthesisPolicy, NativeResynthesisSession, NativeWorksetStats,
77};
78pub use resynthesizer::{
79 DeviceResynthesisPlacement, ResynthesizeTwoQubitBlocks, resynthesize_two_qubit_blocks,
80 resynthesize_two_qubit_blocks_for_device,
81};
82pub(crate) use resynthesizer::{
83 WorkflowResynthesisSession, resynthesize_two_qubit_blocks_incremental,
84 resynthesize_two_qubit_blocks_workflow,
85};