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

Add Rust representation for most controlled gates #12659

Merged
merged 25 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6c1c84f
Add C3X (MCX), extend rust tests to multi-controlled gates.
ElePT Jun 24, 2024
e0fc815
Merge branch 'main' of https://github.com/Qiskit/qiskit into oxidize-…
ElePT Jun 25, 2024
ba76884
Add macro to generate multi-controlled gates. Add CU, CU1, CU3, C3SX,…
ElePT Jun 25, 2024
6270ace
Kill C4XGate
ElePT Jun 25, 2024
8cc2886
Finish adding gates, add circuit construction methods when possible.
ElePT Jun 25, 2024
325cf6c
Add import paths, fix drawer test.
ElePT Jun 26, 2024
9b47121
Establish CGates with non-default control states as non-standard in c…
ElePT Jun 27, 2024
2f2e697
Fix merge conflicts
ElePT Jul 1, 2024
2a67f73
Fix merge conflicts
ElePT Jul 1, 2024
9a41e6f
Apply macro on missing gates
ElePT Jul 1, 2024
4e089b1
Add RCCX gate and RC3X (RCCCX) gate.
ElePT Jul 2, 2024
0284d15
Merge branch 'main' of https://github.com/Qiskit/qiskit into oxidize-…
ElePT Jul 2, 2024
e393557
Make equivalence tests more explicit
ElePT Jul 2, 2024
466bced
Fix lint
ElePT Jul 2, 2024
617af9d
Modify circuit methods for consistency
ElePT Jul 2, 2024
05fe760
Fix default ctrl state for 3q+ gates, add test for CCZ
ElePT Jul 2, 2024
da3e598
Apply comments from Matt's code review
ElePT Jul 2, 2024
b70799a
Fix ctrl_state logic
ElePT Jul 2, 2024
f05c9a1
Rename c3x to mcx?
ElePT Jul 2, 2024
5812ecc
Brackets didn't match explanation
ElePT Jul 2, 2024
5583095
Merge branch 'main' into oxidize-gates-5
ElePT Jul 3, 2024
6e7b076
Make sure controlled test doesn't use custom ControlledGate instances.
ElePT Jul 3, 2024
8c922aa
Rename c4x to mcx in Rust space.
ElePT Jul 3, 2024
2a98908
Return PyResult rather than panic on error
jlapeyre Jul 3, 2024
d834621
Add suggestion from Matt's code review
ElePT Jul 8, 2024
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
37 changes: 31 additions & 6 deletions crates/circuit/src/circuit_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use pyo3::{intern, IntoPy, PyObject, PyResult};
use smallvec::{smallvec, SmallVec};

use crate::imports::{
get_std_gate_class, populate_std_gate_map, GATE, INSTRUCTION, OPERATION,
get_std_gate_class, populate_std_gate_map, CONTROLLED_GATE, GATE, INSTRUCTION, OPERATION,
SINGLETON_CONTROLLED_GATE, SINGLETON_GATE, WARNINGS_WARN,
};
use crate::interner::Index;
Expand Down Expand Up @@ -878,24 +878,49 @@ pub fn convert_py_to_operation_type(
Ok(stdgate) => stdgate.extract().ok().unwrap_or_default(),
Err(_) => None,
};
// If the input instruction is a standard gate and a singleton instance
// If the input instruction is a standard gate and a singleton instance,
// we should check for mutable state. A mutable instance should be treated
// as a custom gate not a standard gate because it has custom properties.
//
// In the futuer we can revisit this when we've dropped `duration`, `unit`,
// Controlled gates with non-default control states are also considered
// custom gates even if a standard representation exists for the default
// control state.

// In the future we can revisit this when we've dropped `duration`, `unit`,
// and `condition` from the api as we should own the label in the
// `CircuitInstruction`. The other piece here is for controlled gates there
// is the control state, so for `SingletonControlledGates` we'll still need
// this check.
if standard.is_some() {
let mutable: bool = py_op.getattr(py, intern!(py, "mutable"))?.extract(py)?;
if mutable
// The default ctrl_states are the all 1 state and None.
// These are the only cases where controlled gates can be standard.
let is_default_ctrl_state = || -> PyResult<bool> {
match py_op.getattr(py, intern!(py, "ctrl_state")) {
Ok(c_state) => match c_state.extract::<Option<i32>>(py) {
mtreinish marked this conversation as resolved.
Show resolved Hide resolved
Ok(c_state_int) => match c_state_int {
Some(c_int) => {
let qubits: u32 =
py_op.getattr(py, intern!(py, "num_qubits"))?.extract(py)?;
Ok(c_int == (2_i32.pow(qubits - 1) - 1))
}
None => Ok(true),
},
Err(_) => Ok(false),
},
Err(_) => Ok(false),
}
};

if (mutable
&& (py_op_bound.is_instance(SINGLETON_GATE.get_bound(py))?
|| py_op_bound.is_instance(SINGLETON_CONTROLLED_GATE.get_bound(py))?)
|| py_op_bound.is_instance(SINGLETON_CONTROLLED_GATE.get_bound(py))?))
|| (py_op_bound.is_instance(CONTROLLED_GATE.get_bound(py))?
&& !is_default_ctrl_state()?)
{
standard = None;
}
}

if let Some(op) = standard {
let base_class = op_type.to_object(py);
populate_std_gate_map(py, op, base_class);
Expand Down
Loading
Loading