Skip to main content

Module compile

Module compile 

Source
Expand description

Compiler pipeline for lowering and optimizing quantum circuits.

This module is the public entry point for cqlib circuit compilation. It takes a logical Circuit, applies a deterministic staged lowering workflow, and returns a rebuilt circuit together with step-level diagnostics.

The compiler workflow is intentionally a staged lowering pipeline rather than a dynamic pass manager. High-level circuit representations are lowered through stable compiler layers:

logical circuit
  -> canonicalized logical IR
  -> expanded circuit-backed definitions
  -> decomposed unitary and multi-controlled gates
  -> global commutation-set cancellation
  -> knowledge-rule optimization
  -> optional physical layout and SABRE routing
  -> optional target-basis translation
  -> canonicalized output
  -> exact device instruction lowering
  -> native-input canonicalization and fixed-point optimization
  -> target-specific candidate validation
  -> optional validated SABRE Pareto selection

The last step applies only to CompileMode::Enhanced with a strict CompileTarget::Device. Candidate zero is finalized and validated first; every exploratory route then repeats the same post-routing suffix through validation. Selection performs no further circuit transform and either retains candidate zero or chooses an already validated Pareto improvement.

§Public Entry Points

Lower-level modules such as transform, sabre, knowledge, and commutation expose reusable compiler infrastructure. They are intended for advanced users and internal composition; ordinary compilation should start with compile.

§Target Constraints

CompileTarget::Logical keeps logical operations, CompileTarget::Basis lowers to an explicit basis, and CompileTarget::Device routes and lowers for one device. The CompileTarget::TopologyBasis target routes on a device topology and lowers to a non-empty caller-supplied basis without claiming native-device compatibility. Strict device compilation uses an exact-plan-aware SABRE movement graph and checks local unary and ordered two-qubit capabilities during routing. Its following device-lowering stage emits the shared exact-qargs plans, then Device::validate_circuit validates the completed output. A successful device compilation therefore never returns a circuit rejected by the configured device.

DeviceCompileTarget::initial_layout may skip automatic initial-layout selection. DeviceCompileTarget::seed controls only device layout and routing heuristics. CompileResult::device_metadata records the initial and final layouts whenever compilation performs device-topology routing.

§Classical Control and High-Level Operations

The workflow preserves classical-control structure. Transforms that support control-flow bodies recurse into them and report whether they changed the IR through TransformOutcome. The workflow does not pre-scan control-flow trees to decide whether a transform should run. This module does not currently lower dynamic classical control into a hardware runtime instruction format.

§Step Reports

WorkflowStepReport records the workflow-local stage and step name, plus whether the step changed the circuit, was skipped, or emitted a short reason. Step names describe workflow positions such as route.sabre or translate.target_basis; they are not required to equal Transformer::name.

For an enhanced strict-device run, the returned reports describe the retained baseline or winning candidate path followed by select.sabre_pareto_beam; they are not an exhaustive trace of every discarded exploratory branch.

§Examples

Compile a logical circuit with default logical optimization:

use cqlib_core::circuit::{Circuit, Qubit};
use cqlib_core::compile::{CompileConfig, CompileMode, CompileTarget, compile};
use cqlib_core::compile::resource::ResourcePolicy;

let mut circuit = Circuit::new(2);
circuit.h(Qubit::new(0)).unwrap();
circuit.cx(Qubit::new(0), Qubit::new(1)).unwrap();

let result = compile(
    &circuit,
    CompileConfig {
        mode: CompileMode::Normal,
        target: CompileTarget::Logical,
        resource_policy: ResourcePolicy::default(),
    },
)
.unwrap();

assert_eq!(result.mode, CompileMode::Normal);
assert!(!result.steps.is_empty());

Compile to an explicit target basis:

use cqlib_core::circuit::{Circuit, Instruction, Qubit, StandardGate};
use cqlib_core::compile::{CompileConfig, CompileMode, CompileTarget, compile};
use cqlib_core::compile::resource::ResourcePolicy;

let mut circuit = Circuit::new(2);
circuit.h(Qubit::new(0)).unwrap();
circuit.cx(Qubit::new(0), Qubit::new(1)).unwrap();

let result = compile(
    &circuit,
    CompileConfig {
        mode: CompileMode::Normal,
        target: CompileTarget::Basis(vec![
            Instruction::Standard(StandardGate::H),
            Instruction::Standard(StandardGate::CZ),
        ]),
        resource_policy: ResourcePolicy::default(),
    },
)
.unwrap();

assert!(
    result
        .steps
        .iter()
        .any(|step| step.name == "translate.target_basis" && step.changed)
);

Compile for a device topology:

use cqlib_core::circuit::{Circuit, Qubit};
use cqlib_core::compile::{CompileConfig, CompileMode, CompileTarget, DeviceCompileTarget, compile};
use cqlib_core::compile::resource::ResourcePolicy;
use cqlib_core::device::Device;
use cqlib_core::circuit::{Instruction, StandardGate};

let mut circuit = Circuit::new(2);
circuit.cx(Qubit::new(0), Qubit::new(1)).unwrap();
let device = Device::bidirectional_line("line-2", 2)
    .unwrap()
    .with_native_gates(vec![Instruction::Standard(StandardGate::CX)])
    .unwrap();

let result = compile(
    &circuit,
    CompileConfig {
        mode: CompileMode::Normal,
        target: CompileTarget::Device(DeviceCompileTarget {
            device,
            initial_layout: None,
            seed: Some(7),
        }),
        resource_policy: ResourcePolicy::default(),
    },
)
.unwrap();

assert!(
    result
        .steps
        .iter()
        .any(|step| step.name == "route.sabre" && !step.skipped)
);

Route from a supplied initial layout:

use cqlib_core::circuit::{Circuit, Qubit};
use cqlib_core::compile::{CompileConfig, CompileMode, CompileTarget, DeviceCompileTarget, compile};
use cqlib_core::compile::resource::ResourcePolicy;
use cqlib_core::device::{Device, Layout};

let mut circuit = Circuit::new(1);
circuit.h(Qubit::new(0)).unwrap();
let layout = Layout::from_pairs(&[(0, 2)], 3).unwrap();

let result = compile(
    &circuit,
    CompileConfig {
        mode: CompileMode::Normal,
        target: CompileTarget::Device(DeviceCompileTarget {
            device: Device::line("line-3", 3)
                .unwrap()
                .with_native_gates(vec![
                    cqlib_core::circuit::Instruction::Standard(
                        cqlib_core::circuit::StandardGate::H,
                    ),
                ])
                .unwrap(),
            initial_layout: Some(layout),
            seed: Some(11),
        }),
        resource_policy: ResourcePolicy::default(),
    },
)
.unwrap();

assert_eq!(result.circuit.operations()[0].qubits.as_slice(), &[Qubit::new(2)]);

Inspect workflow step reports:

use cqlib_core::circuit::Circuit;
use cqlib_core::compile::{CompileConfig, CompileMode, CompileTarget, compile};
use cqlib_core::compile::resource::ResourcePolicy;

let result = compile(
    &Circuit::new(1),
    CompileConfig {
        mode: CompileMode::Enhanced,
        target: CompileTarget::Logical,
        resource_policy: ResourcePolicy::default(),
    },
)
.unwrap();

let routing = result
    .steps
    .iter()
    .find(|step| step.name == "route.sabre")
    .unwrap();
assert!(routing.skipped);

Re-exports§

pub use commutation::Commutation;
pub use commutation::CommutationChecker;
pub use commutation::CommutationConfig;
pub use commutation::CommutationResult;
pub use commutation::algebraic_commutation;
pub use commutation::check_commutation;
pub use compiler::CompileConfig;
pub use compiler::CompileMode;
pub use compiler::CompileResult;
pub use compiler::CompileTarget;
pub use compiler::DeviceCompilationMetadata;
pub use compiler::DeviceCompileTarget;
pub use compiler::compile;
pub use compiler::compile_owned;
pub use error::CompilerError;
pub use error::SabreRoutingFailure;
pub use sabre::SabreConfig;
pub use sabre::SabreHeuristicConfig;
pub use sabre::SabreRoutingDiagnostics;
pub use sabre::SabreRoutingResult;
pub use sabre::SabreVf2PrepassConfig;
pub use sabre::normalize_initial_layout;
pub use sabre::sabre_route;
pub use sabre::validate_reachable_interactions;
pub use transform::KnowledgeRewriteDiagnostics;
pub use transform::VirtualPermutation;
pub use workflow::CompilerWorkflow;
pub use workflow::WorkflowStepReport;

Modules§

commutation
Gate Commutation
compiler
Public compiler entry point.
error
knowledge
Compiler knowledge-base rules.
physical_target
Physical topology view used by layout and routing preparation.
resource
Shared logical-qubit ancillary-resource management for compiler stages.
sabre
SABRE routing core.
transform
Circuit transforms used by the compiler workflow.
workflow
Workflow-level orchestration for the new compiler optimization pipeline.