From 2575431409004602508af7c2f3c0cf1388ce5ffa Mon Sep 17 00:00:00 2001 From: Raynel Sanchez <87539502+raynelfss@users.noreply.github.com> Date: Mon, 13 May 2024 15:41:02 -0400 Subject: [PATCH] Fix: More failing tests - Fix repeated erroneous calls to `add_instruction` in `update_from_instruction_schedule_map` - Add missing condition in `instruction_supported` - Use `IndexSet` instead of `HashSet` for `QargsSet`. - Other small tweaks and fixes. --- .../accelerate/src/target_transpiler/mod.rs | 89 ++++++++++--------- .../accelerate/src/target_transpiler/qargs.rs | 10 +-- 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/crates/accelerate/src/target_transpiler/mod.rs b/crates/accelerate/src/target_transpiler/mod.rs index 2b23ee6f64eb..1db907af0513 100644 --- a/crates/accelerate/src/target_transpiler/mod.rs +++ b/crates/accelerate/src/target_transpiler/mod.rs @@ -689,45 +689,45 @@ impl Target { let params = params.bind(py); param_names.add(tupleize(params)?)?; } - if qlen.len() > 1 || param_names.len() > 1 { - return Err(QiskitError::new_err(format!( - "Schedules for {:?} are defined non-uniformly for - multiple qubit lengths {:?}, - or different parameter names {:?}. - Provide these schedules with inst_name_map or define them with - different names for different gate parameters.", - &inst_name, - qlen.iter().collect::>(), - param_names, - ))); - } - let gate_class = py.import_bound("qiskit.circuit.gate")?.getattr("Gate")?; - let kwargs = [ - ("name", inst_name.as_str().into_py(py)), - ("num_qubits", qlen.iter().next().to_object(py)), - ("params", Vec::::new().to_object(py)), - ] - .into_py_dict_bound(py); - let mut inst_obj = gate_class.call((), Some(&kwargs))?; - if let Some(param) = param_names.iter().next() { - if param.is_truthy()? { - let parameter_class = py - .import_bound("qiskit.circuit.parameter")? - .getattr("Parameter")?; - let params = param - .iter()? - .flat_map(|x| -> PyResult> { - parameter_class.call1((x?,)) - }) - .collect_vec(); - let kwargs = [ - ("name", inst_name.as_str().into_py(py)), - ("num_qubits", qlen.iter().next().to_object(py)), - ("params", params.to_object(py)), - ] - .into_py_dict_bound(py); - inst_obj = gate_class.call((), Some(&kwargs))?; - } + } + if qlen.len() > 1 || param_names.len() > 1 { + return Err(QiskitError::new_err(format!( + "Schedules for {:?} are defined non-uniformly for + multiple qubit lengths {:?}, + or different parameter names {:?}. + Provide these schedules with inst_name_map or define them with + different names for different gate parameters.", + &inst_name, + qlen.iter().collect::>(), + param_names, + ))); + } + let gate_class = py.import_bound("qiskit.circuit.gate")?.getattr("Gate")?; + let kwargs = [ + ("name", inst_name.as_str().into_py(py)), + ("num_qubits", qlen.iter().next().to_object(py)), + ("params", Vec::::new().to_object(py)), + ] + .into_py_dict_bound(py); + let mut inst_obj = gate_class.call((), Some(&kwargs))?; + if let Some(param) = param_names.iter().next() { + if param.is_truthy()? { + let parameter_class = py + .import_bound("qiskit.circuit.parameter")? + .getattr("Parameter")?; + let params = param + .iter()? + .flat_map(|x| -> PyResult> { + parameter_class.call1((x?,)) + }) + .collect_vec(); + let kwargs = [ + ("name", inst_name.as_str().into_py(py)), + ("num_qubits", qlen.iter().next().to_object(py)), + ("params", params.to_object(py)), + ] + .into_py_dict_bound(py); + inst_obj = gate_class.call((), Some(&kwargs))?; } self.add_instruction( py, @@ -1109,7 +1109,7 @@ impl Target { { return Ok(false); } - if param.eq(¶m_at_index)? && !param_at_index.is_instance(parameter_class)? { + if !param.eq(¶m_at_index)? && !param_at_index.is_instance(parameter_class)? { return Ok(false); } } @@ -1238,9 +1238,8 @@ impl Target { } if let Some(_qargs) = qargs.as_ref() { let qarg_set: HashSet = _qargs.vec.iter().cloned().collect(); - if self.gate_map.map.contains_key(operation_names) { - let gate_map_name = - &self.gate_map.map[operation_names].extract::(py)?; + if let Some(gate_prop_name) = self.gate_map.map.get(operation_names) { + let gate_map_name = gate_prop_name.extract::(py)?; if gate_map_name.map.contains_key(&qargs) { return Ok(true); } @@ -1290,6 +1289,8 @@ impl Target { })); } } + } else { + return Ok(true); } } } @@ -1533,7 +1534,7 @@ impl Target { /// The set of qargs in the target. #[getter] fn qargs(&self) -> PyResult> { - let qargs: HashSet> = self.qarg_gate_map.keys().cloned().collect(); + let qargs: IndexSet> = self.qarg_gate_map.keys().cloned().collect(); // Modify logic to account for the case of {None} let next_entry = qargs.iter().flatten().next(); if qargs.len() == 1 && (qargs.iter().next().is_none() || next_entry.is_none()) { diff --git a/crates/accelerate/src/target_transpiler/qargs.rs b/crates/accelerate/src/target_transpiler/qargs.rs index 6bbdb2a6dbad..24c078fadcd8 100644 --- a/crates/accelerate/src/target_transpiler/qargs.rs +++ b/crates/accelerate/src/target_transpiler/qargs.rs @@ -18,8 +18,7 @@ use std::{ hash::{Hash, Hasher}, }; -use hashbrown::{hash_set::IntoIter, HashSet}; - +use indexmap::{set::IntoIter, IndexSet}; use itertools::Itertools; use pyo3::{ exceptions::{PyKeyError, PyTypeError}, @@ -85,16 +84,11 @@ impl QargsIter { #[pyclass(sequence)] #[derive(Debug, Clone)] pub struct QargsSet { - pub set: HashSet>, + pub set: IndexSet>, } #[pymethods] impl QargsSet { - #[new] - pub fn new(set: HashSet>) -> Self { - Self { set } - } - fn __eq__(slf: PyRef, other: Bound) -> PyResult { for item in other.iter() { let qargs = if item.is_none() {