Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support stretchy delays in box #13899

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,018 changes: 584 additions & 434 deletions crates/accelerate/src/unitary_synthesis.rs

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions crates/circuit/src/dag_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2533,6 +2533,7 @@ def _format(operand):
let condition_op_check = imports::CONDITION_OP_CHECK.get_bound(py);
let switch_case_op_check = imports::SWITCH_CASE_OP_CHECK.get_bound(py);
let for_loop_op_check = imports::FOR_LOOP_OP_CHECK.get_bound(py);
let box_op_check = imports::BOX_OP_CHECK.get_bound(py);
let node_match = |n1: &NodeType, n2: &NodeType| -> PyResult<bool> {
match [n1, n2] {
[NodeType::Operation(inst1), NodeType::Operation(inst2)] => {
Expand Down Expand Up @@ -2604,6 +2605,10 @@ def _format(operand):
for_loop_op_check
.call1((n1, n2, &self_bit_indices, &other_bit_indices))?
.extract()
} else if name == "box" {
box_op_check
.call1((n1, n2, &self_bit_indices, &other_bit_indices))?
.extract()
} else {
Err(PyRuntimeError::new_err(format!(
"unhandled control-flow operation: {}",
Expand Down
36 changes: 36 additions & 0 deletions crates/circuit/src/duration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This code is part of Qiskit.
//
// (C) Copyright IBM 2025
//
// This code is licensed under the Apache License, Version 2.0. You may
// obtain a copy of this license in the LICENSE.txt file in the root directory
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.

use pyo3::prelude::*;

#[pyclass(eq, module = "qiskit._accelerate.circuit")]
#[derive(PartialEq, Clone, Copy, Debug)]
#[allow(non_camel_case_types)]
pub enum Duration {
dt(u64),
ns(f64),
us(f64),
ms(f64),
s(f64),
}

impl Duration {
fn __repr__(&self) -> String {
match self {
Duration::ns(t) => format!("Duration.ns({})", t),
Duration::us(t) => format!("Duration.us({})", t),
Duration::ms(t) => format!("Duration.ms({})", t),
Duration::s(t) => format!("Duration.s({})", t),
Duration::dt(t) => format!("Duration.dt({})", t),
}
}
}
2 changes: 2 additions & 0 deletions crates/circuit/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ pub static SWITCH_CASE_OP_CHECK: ImportOnceCell =
ImportOnceCell::new("qiskit.dagcircuit.dagnode", "_switch_case_eq");
pub static FOR_LOOP_OP_CHECK: ImportOnceCell =
ImportOnceCell::new("qiskit.dagcircuit.dagnode", "_for_loop_eq");
pub static BOX_OP_CHECK: ImportOnceCell =
ImportOnceCell::new("qiskit.dagcircuit.dagnode", "_box_eq");
pub static UUID: ImportOnceCell = ImportOnceCell::new("uuid", "UUID");
pub static BARRIER: ImportOnceCell = ImportOnceCell::new("qiskit.circuit", "Barrier");
pub static DELAY: ImportOnceCell = ImportOnceCell::new("qiskit.circuit", "Delay");
Expand Down
2 changes: 2 additions & 0 deletions crates/circuit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod converters;
pub mod dag_circuit;
pub mod dag_node;
mod dot_utils;
pub mod duration;
pub mod error;
pub mod gate_matrix;
pub mod imports;
Expand Down Expand Up @@ -157,6 +158,7 @@ macro_rules! impl_intopyobject_for_copy_pyclass {
}

pub fn circuit(m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<duration::Duration>()?;
m.add_class::<circuit_data::CircuitData>()?;
m.add_class::<circuit_instruction::CircuitInstruction>()?;
m.add_class::<dag_circuit::DAGCircuit>()?;
Expand Down
5 changes: 4 additions & 1 deletion crates/circuit/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,14 @@ pub enum DelayUnit {
MS,
S,
DT,
EXPR,
}

unsafe impl ::bytemuck::CheckedBitPattern for DelayUnit {
type Bits = u8;

fn is_valid_bit_pattern(bits: &Self::Bits) -> bool {
*bits < 6
*bits < 7
}
}
unsafe impl ::bytemuck::NoUninit for DelayUnit {}
Expand All @@ -321,6 +322,7 @@ impl fmt::Display for DelayUnit {
DelayUnit::MS => "ms",
DelayUnit::S => "s",
DelayUnit::DT => "dt",
DelayUnit::EXPR => "expr",
}
)
}
Expand All @@ -336,6 +338,7 @@ impl<'py> FromPyObject<'py> for DelayUnit {
"ms" => DelayUnit::MS,
"s" => DelayUnit::S,
"dt" => DelayUnit::DT,
"expr" => DelayUnit::EXPR,
unknown_unit => {
return Err(PyValueError::new_err(format!(
"Unit '{}' is invalid.",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Issues = "https://github.com/Qiskit/qiskit/issues"
Changelog = "https://docs.quantum.ibm.com/api/qiskit/release-notes"

[project.entry-points."qiskit.unitary_synthesis"]
default = "qiskit.transpiler.passes.synthesis.unitary_synthesis:DefaultUnitarySynthesis"
default = "qiskit.transpiler.passes.synthesis.default_unitary_synth_plugin:DefaultUnitarySynthesis"
aqc = "qiskit.transpiler.passes.synthesis.aqc_plugin:AQCSynthesisPlugin"
sk = "qiskit.transpiler.passes.synthesis.solovay_kitaev_synthesis:SolovayKitaevSynthesis"

Expand Down
3 changes: 3 additions & 0 deletions qiskit/circuit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,8 @@ def __array__(self, dtype=None, copy=None):
\end{pmatrix}
"""

from qiskit._accelerate.circuit import Duration # pylint: disable=unused-import

from .exceptions import CircuitError
from . import _utils
from .quantumcircuit import QuantumCircuit
Expand Down Expand Up @@ -1313,6 +1315,7 @@ def __array__(self, dtype=None, copy=None):

from .controlflow import (
ControlFlowOp,
BoxOp,
WhileLoopOp,
ForLoopOp,
IfElseOp,
Expand Down
8 changes: 8 additions & 0 deletions qiskit/circuit/classical/expr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@
"greater",
"greater_equal",
"index",
"add",
"sub",
"mul",
"div",
"lift_legacy_condition",
]

Expand All @@ -234,5 +238,9 @@
shift_left,
shift_right,
index,
add,
sub,
mul,
div,
lift_legacy_condition,
)
Loading
Loading