-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port RemoveDiagonalGatesBeforeMeasure to rust (#13065)
* add rust code for remove_diagonal_gates_before_measure * replace python code by rust code for remove_diagonal_gates_brefore_measure * make some dag_circuit functions public * fix some of the tests failures * fix another failing test, add more diagonal gates * add tests for added diagonal gates: p, cp, cs, csdg * make the lists of diagonal gates into static arrays * formatting * change nodes_to_remove type to Vec * remove the HashSet following review * add CCZ diagonal gate * add tests for CCZ diagonal gate * add release notes * fix lint
- Loading branch information
1 parent
86c63eb
commit 8606f05
Showing
8 changed files
with
269 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
crates/accelerate/src/remove_diagonal_gates_before_measure.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// This code is part of Qiskit. | ||
// | ||
// (C) Copyright IBM 2024 | ||
// | ||
// 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. | ||
|
||
/// Remove diagonal gates (including diagonal 2Q gates) before a measurement. | ||
use pyo3::prelude::*; | ||
|
||
use qiskit_circuit::dag_circuit::{DAGCircuit, NodeType}; | ||
use qiskit_circuit::operations::Operation; | ||
use qiskit_circuit::operations::StandardGate; | ||
|
||
/// Run the RemoveDiagonalGatesBeforeMeasure pass on `dag`. | ||
/// Args: | ||
/// dag (DAGCircuit): the DAG to be optimized. | ||
/// Returns: | ||
/// DAGCircuit: the optimized DAG. | ||
#[pyfunction] | ||
#[pyo3(name = "remove_diagonal_gates_before_measure")] | ||
fn run_remove_diagonal_before_measure(dag: &mut DAGCircuit) -> PyResult<()> { | ||
static DIAGONAL_1Q_GATES: [StandardGate; 8] = [ | ||
StandardGate::RZGate, | ||
StandardGate::ZGate, | ||
StandardGate::TGate, | ||
StandardGate::SGate, | ||
StandardGate::TdgGate, | ||
StandardGate::SdgGate, | ||
StandardGate::U1Gate, | ||
StandardGate::PhaseGate, | ||
]; | ||
static DIAGONAL_2Q_GATES: [StandardGate; 7] = [ | ||
StandardGate::CZGate, | ||
StandardGate::CRZGate, | ||
StandardGate::CU1Gate, | ||
StandardGate::RZZGate, | ||
StandardGate::CPhaseGate, | ||
StandardGate::CSGate, | ||
StandardGate::CSdgGate, | ||
]; | ||
static DIAGONAL_3Q_GATES: [StandardGate; 1] = [StandardGate::CCZGate]; | ||
|
||
let mut nodes_to_remove = Vec::new(); | ||
for index in dag.op_nodes(true) { | ||
let node = &dag.dag[index]; | ||
let NodeType::Operation(inst) = node else {panic!()}; | ||
|
||
if inst.op.name() == "measure" { | ||
let predecessor = (dag.quantum_predecessors(index)) | ||
.next() | ||
.expect("index is an operation node, so it must have a predecessor."); | ||
|
||
match &dag.dag[predecessor] { | ||
NodeType::Operation(pred_inst) => match pred_inst.standard_gate() { | ||
Some(gate) => { | ||
if DIAGONAL_1Q_GATES.contains(&gate) { | ||
nodes_to_remove.push(predecessor); | ||
} else if DIAGONAL_2Q_GATES.contains(&gate) | ||
|| DIAGONAL_3Q_GATES.contains(&gate) | ||
{ | ||
let successors = dag.quantum_successors(predecessor); | ||
let remove_s = successors | ||
.map(|s| { | ||
let node_s = &dag.dag[s]; | ||
if let NodeType::Operation(inst_s) = node_s { | ||
inst_s.op.name() == "measure" | ||
} else { | ||
false | ||
} | ||
}) | ||
.all(|ok_to_remove| ok_to_remove); | ||
if remove_s { | ||
nodes_to_remove.push(predecessor); | ||
} | ||
} | ||
} | ||
None => { | ||
continue; | ||
} | ||
}, | ||
_ => { | ||
continue; | ||
} | ||
} | ||
} | ||
} | ||
|
||
for node_to_remove in nodes_to_remove { | ||
if dag.dag.node_weight(node_to_remove).is_some() { | ||
dag.remove_op_node(node_to_remove); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[pymodule] | ||
pub fn remove_diagonal_gates_before_measure(m: &Bound<PyModule>) -> PyResult<()> { | ||
m.add_wrapped(wrap_pyfunction!(run_remove_diagonal_before_measure))?; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
releasenotes/notes/update-remove-diagonal-gates-before-measure-86abe39e46d5dad5.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
features_transpiler: | ||
- | | ||
The :class:`.RemoveDiagonalGatesBeforeMeasure` transpiler pass has been upgraded to | ||
include more diagonal gates: :class:`.PhaseGate`, :class:`.CPhaseGate`, | ||
:class:`.CSGate`, :class:`.CSdgGate` and :class:`.CCZGate`. | ||
In addition, the code of the :class:`.RemoveDiagonalGatesBeforeMeasure` was ported to Rust, | ||
and is now x20 faster for a 20 qubit circuit. |
Oops, something went wrong.