From 10120feb307c3738fa58b2b80b8399203b17dabf Mon Sep 17 00:00:00 2001 From: Kevin Krsulich Date: Tue, 18 Aug 2020 18:42:33 -0400 Subject: [PATCH] Fix parameterized Gate.definition to have valid ParameterTable. --- qiskit/circuit/instruction.py | 2 +- qiskit/circuit/library/standard_gates/dcx.py | 4 +- qiskit/circuit/library/standard_gates/h.py | 8 +++- .../circuit/library/standard_gates/iswap.py | 4 +- qiskit/circuit/library/standard_gates/ms.py | 5 +-- qiskit/circuit/library/standard_gates/p.py | 2 +- qiskit/circuit/library/standard_gates/r.py | 4 +- qiskit/circuit/library/standard_gates/rx.py | 8 +++- qiskit/circuit/library/standard_gates/rxx.py | 4 +- qiskit/circuit/library/standard_gates/ry.py | 8 +++- qiskit/circuit/library/standard_gates/ryy.py | 4 +- qiskit/circuit/library/standard_gates/rz.py | 8 +++- qiskit/circuit/library/standard_gates/rzx.py | 4 +- qiskit/circuit/library/standard_gates/rzz.py | 4 +- qiskit/circuit/library/standard_gates/s.py | 8 +++- qiskit/circuit/library/standard_gates/swap.py | 8 +++- qiskit/circuit/library/standard_gates/t.py | 8 +++- qiskit/circuit/library/standard_gates/u1.py | 11 +++-- qiskit/circuit/library/standard_gates/u2.py | 4 +- qiskit/circuit/library/standard_gates/u3.py | 4 +- qiskit/circuit/library/standard_gates/x.py | 30 +++++++++---- qiskit/circuit/library/standard_gates/y.py | 8 +++- qiskit/circuit/library/standard_gates/z.py | 8 +++- qiskit/converters/ast_to_dag.py | 3 +- qiskit/converters/circuit_to_gate.py | 3 +- qiskit/converters/circuit_to_instruction.py | 3 +- ...plete-ParameterTable-a9becfb8aff7d906.yaml | 8 ++++ test/python/circuit/test_gate_definitions.py | 42 ++++++++++++++++++- 28 files changed, 169 insertions(+), 48 deletions(-) create mode 100644 releasenotes/notes/4863-Parameterized-gate-definitions-built-with-incomplete-ParameterTable-a9becfb8aff7d906.yaml diff --git a/qiskit/circuit/instruction.py b/qiskit/circuit/instruction.py index a1a45767941b..10767cdabd6d 100644 --- a/qiskit/circuit/instruction.py +++ b/qiskit/circuit/instruction.py @@ -383,6 +383,6 @@ def repeat(self, n): qc.add_register(qargs) if cargs: qc.add_register(cargs) - qc._data = [(self, qargs[:], cargs[:])] * n + qc.data = [(self, qargs[:], cargs[:])] * n instruction.definition = qc return instruction diff --git a/qiskit/circuit/library/standard_gates/dcx.py b/qiskit/circuit/library/standard_gates/dcx.py index f1f26b345706..24fcd6babffe 100644 --- a/qiskit/circuit/library/standard_gates/dcx.py +++ b/qiskit/circuit/library/standard_gates/dcx.py @@ -61,7 +61,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (CXGate(), [q[1], q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def to_matrix(self): diff --git a/qiskit/circuit/library/standard_gates/h.py b/qiskit/circuit/library/standard_gates/h.py index 55213072987f..23585b88a354 100644 --- a/qiskit/circuit/library/standard_gates/h.py +++ b/qiskit/circuit/library/standard_gates/h.py @@ -63,7 +63,9 @@ def _define(self): rules = [ (U2Gate(0, pi), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -194,7 +196,9 @@ def _define(self): (HGate(), [q[1]], []), (SdgGate(), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/iswap.py b/qiskit/circuit/library/standard_gates/iswap.py index 83b1127d911a..b20ce83c988b 100644 --- a/qiskit/circuit/library/standard_gates/iswap.py +++ b/qiskit/circuit/library/standard_gates/iswap.py @@ -105,7 +105,9 @@ def _define(self): (CXGate(), [q[1], q[0]], []), (HGate(), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def to_matrix(self): diff --git a/qiskit/circuit/library/standard_gates/ms.py b/qiskit/circuit/library/standard_gates/ms.py index 0918bfeaecda..e310f27412e6 100644 --- a/qiskit/circuit/library/standard_gates/ms.py +++ b/qiskit/circuit/library/standard_gates/ms.py @@ -40,9 +40,8 @@ def _define(self): theta = self.params[0] q = QuantumRegister(self.num_qubits, 'q') qc = QuantumCircuit(q, name=self.name) - rules = [] for i in range(self.num_qubits): for j in range(i + 1, self.num_qubits): - rules += [(RXXGate(theta), [q[i], q[j]], [])] - qc._data = rules + qc._append(RXXGate(theta), [q[i], q[j]], []) + self.definition = qc diff --git a/qiskit/circuit/library/standard_gates/p.py b/qiskit/circuit/library/standard_gates/p.py index c1596000555c..13702bfcf23d 100644 --- a/qiskit/circuit/library/standard_gates/p.py +++ b/qiskit/circuit/library/standard_gates/p.py @@ -259,7 +259,7 @@ def _define(self): scaled_lam = self.params[0] / (2 ** (self.num_ctrl_qubits - 1)) bottom_gate = CPhaseGate(scaled_lam) definition = _gray_code_chain(q, self.num_ctrl_qubits, bottom_gate) - qc._data = definition + qc.data = definition self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): diff --git a/qiskit/circuit/library/standard_gates/r.py b/qiskit/circuit/library/standard_gates/r.py index 46613269f3d9..4b0adedb1b97 100644 --- a/qiskit/circuit/library/standard_gates/r.py +++ b/qiskit/circuit/library/standard_gates/r.py @@ -61,7 +61,9 @@ def _define(self): rules = [ (U3Gate(theta, phi - pi / 2, -phi + pi / 2), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/rx.py b/qiskit/circuit/library/standard_gates/rx.py index 3bf6364b525c..dae8cf805d07 100644 --- a/qiskit/circuit/library/standard_gates/rx.py +++ b/qiskit/circuit/library/standard_gates/rx.py @@ -60,7 +60,9 @@ def _define(self): rules = [ (RGate(self.params[0], 0), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -181,7 +183,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (U3Gate(self.params[0] / 2, -pi / 2, 0), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/rxx.py b/qiskit/circuit/library/standard_gates/rxx.py index 3f162061e7d8..16ed34fdb110 100644 --- a/qiskit/circuit/library/standard_gates/rxx.py +++ b/qiskit/circuit/library/standard_gates/rxx.py @@ -89,7 +89,9 @@ def _define(self): (HGate(), [q[1]], []), (HGate(), [q[0]], []), ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/ry.py b/qiskit/circuit/library/standard_gates/ry.py index 9bbb007276dd..682f1a1143d1 100644 --- a/qiskit/circuit/library/standard_gates/ry.py +++ b/qiskit/circuit/library/standard_gates/ry.py @@ -60,7 +60,9 @@ def _define(self): rules = [ (RGate(self.params[0], pi / 2), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -176,7 +178,9 @@ def _define(self): (U3Gate(-self.params[0] / 2, 0, 0), [q[1]], []), (CXGate(), [q[0], q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/ryy.py b/qiskit/circuit/library/standard_gates/ryy.py index e1953ef8ef39..fda1322b6110 100644 --- a/qiskit/circuit/library/standard_gates/ryy.py +++ b/qiskit/circuit/library/standard_gates/ryy.py @@ -91,7 +91,9 @@ def _define(self): (RXGate(-np.pi / 2), [q[0]], []), (RXGate(-np.pi / 2), [q[1]], []), ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/rz.py b/qiskit/circuit/library/standard_gates/rz.py index 05e8a3f7a929..fb08516afce4 100644 --- a/qiskit/circuit/library/standard_gates/rz.py +++ b/qiskit/circuit/library/standard_gates/rz.py @@ -71,7 +71,9 @@ def _define(self): rules = [ (U1Gate(theta), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -193,7 +195,9 @@ def _define(self): (U1Gate(-self.params[0] / 2), [q[1]], []), (CXGate(), [q[0], q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/rzx.py b/qiskit/circuit/library/standard_gates/rzx.py index 8f0c6283d2c9..cfe9d7c5558a 100644 --- a/qiskit/circuit/library/standard_gates/rzx.py +++ b/qiskit/circuit/library/standard_gates/rzx.py @@ -135,7 +135,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (HGate(), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/rzz.py b/qiskit/circuit/library/standard_gates/rzz.py index 1ae5525db0e4..1c17685a382a 100644 --- a/qiskit/circuit/library/standard_gates/rzz.py +++ b/qiskit/circuit/library/standard_gates/rzz.py @@ -99,7 +99,9 @@ def _define(self): (RZGate(theta), [q[1]], []), (CXGate(), [q[0], q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/s.py b/qiskit/circuit/library/standard_gates/s.py index f707c6739dae..9313265b4c4f 100644 --- a/qiskit/circuit/library/standard_gates/s.py +++ b/qiskit/circuit/library/standard_gates/s.py @@ -61,7 +61,9 @@ def _define(self): rules = [ (U1Gate(pi / 2), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): @@ -117,7 +119,9 @@ def _define(self): rules = [ (U1Gate(-pi / 2), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/swap.py b/qiskit/circuit/library/standard_gates/swap.py index ac3abb5d6f26..74c92e202878 100644 --- a/qiskit/circuit/library/standard_gates/swap.py +++ b/qiskit/circuit/library/standard_gates/swap.py @@ -68,7 +68,9 @@ def _define(self): (CXGate(), [q[1], q[0]], []), (CXGate(), [q[0], q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -217,7 +219,9 @@ def _define(self): (CCXGate(), [q[0], q[1], q[2]], []), (CXGate(), [q[2], q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/t.py b/qiskit/circuit/library/standard_gates/t.py index 6ceeba9d8eb2..648852249d70 100644 --- a/qiskit/circuit/library/standard_gates/t.py +++ b/qiskit/circuit/library/standard_gates/t.py @@ -62,7 +62,9 @@ def _define(self): rules = [ (U1Gate(pi / 4), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): @@ -118,7 +120,9 @@ def _define(self): rules = [ (U1Gate(-pi / 4), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/u1.py b/qiskit/circuit/library/standard_gates/u1.py index b76db3e27fb4..267bca34a1cd 100644 --- a/qiskit/circuit/library/standard_gates/u1.py +++ b/qiskit/circuit/library/standard_gates/u1.py @@ -86,7 +86,9 @@ def _define(self): rules = [ (U3Gate(0, 0, self.params[0]), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -184,7 +186,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (U1Gate(self.params[0] / 2), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -273,7 +277,8 @@ def _define(self): scaled_lam = self.params[0] / (2 ** (self.num_ctrl_qubits - 1)) bottom_gate = CU1Gate(scaled_lam) definition = _gray_code_chain(q, self.num_ctrl_qubits, bottom_gate) - qc._data = definition + for instr, qargs, cargs in definition: + qc._append(instr, qargs, cargs) self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): diff --git a/qiskit/circuit/library/standard_gates/u2.py b/qiskit/circuit/library/standard_gates/u2.py index 1f901a88e40e..2a58677fc179 100644 --- a/qiskit/circuit/library/standard_gates/u2.py +++ b/qiskit/circuit/library/standard_gates/u2.py @@ -69,7 +69,9 @@ def _define(self): q = QuantumRegister(1, 'q') qc = QuantumCircuit(q, name=self.name) rules = [(U3Gate(pi / 2, self.params[0], self.params[1]), [q[0]], [])] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/u3.py b/qiskit/circuit/library/standard_gates/u3.py index 3e4d1c7771d0..c26bf010ba1b 100644 --- a/qiskit/circuit/library/standard_gates/u3.py +++ b/qiskit/circuit/library/standard_gates/u3.py @@ -189,7 +189,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (U3Gate(self.params[0] / 2, self.params[1], 0), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/x.py b/qiskit/circuit/library/standard_gates/x.py index 1c3883c65757..39b26e28d8dc 100644 --- a/qiskit/circuit/library/standard_gates/x.py +++ b/qiskit/circuit/library/standard_gates/x.py @@ -84,7 +84,9 @@ def _define(self): rules = [ (U3Gate(pi, 0, pi), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -317,7 +319,9 @@ def _define(self): (TdgGate(), [q[1]], []), (CXGate(), [q[0], q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -396,7 +400,9 @@ def _define(self): (U1Gate(-pi / 4), [q[2]], []), # inverse T gate (U2Gate(0, pi), [q[2]], []), # H gate ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def to_matrix(self): @@ -487,7 +493,9 @@ def _define(self): (HGate(), [q[3]], []) ] qc = QuantumCircuit(q) - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -596,7 +604,9 @@ def _define(self): (U1Gate(-pi / 4), [q[3]], []), (U2Gate(0, pi), [q[3]], []), ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def to_matrix(self): @@ -677,7 +687,9 @@ def _define(self): (C3XGate(), [q[0], q[1], q[2], q[3]], []), (C3XGate(numpy.pi / 8), [q[0], q[1], q[2], q[4]], []), ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -841,8 +853,9 @@ def _define(self): qc._append(C4XGate(), q[:], []) self.definition = qc else: + for instr, qargs, cargs in self._recurse(q[:-1], q_ancilla=q[-1]): + qc._append(instr, qargs, cargs) self.definition = qc - self.definition._data = self._recurse(q[:-1], q_ancilla=q[-1]) def _recurse(self, q, q_ancilla=None): # recursion stop @@ -954,5 +967,6 @@ def _define(self): definition.append( (RCCXGate(), [q_controls[j], q_ancillas[i], q_ancillas[i + 1]], [])) - qc._data = definition + for instr, qargs, cargs in definition: + qc._append(instr, qargs, cargs) self.definition = qc diff --git a/qiskit/circuit/library/standard_gates/y.py b/qiskit/circuit/library/standard_gates/y.py index 84fe4f8a5c66..222eb718841b 100644 --- a/qiskit/circuit/library/standard_gates/y.py +++ b/qiskit/circuit/library/standard_gates/y.py @@ -76,7 +76,9 @@ def _define(self): rules = [ (U3Gate(pi, pi / 2, pi / 2), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -192,7 +194,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (SGate(), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/circuit/library/standard_gates/z.py b/qiskit/circuit/library/standard_gates/z.py index 4d4b86d547b3..66a1ce8bfe38 100644 --- a/qiskit/circuit/library/standard_gates/z.py +++ b/qiskit/circuit/library/standard_gates/z.py @@ -75,7 +75,9 @@ def _define(self): rules = [ (U1Gate(pi), [q[0]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None): @@ -159,7 +161,9 @@ def _define(self): (CXGate(), [q[0], q[1]], []), (HGate(), [q[1]], []) ] - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) + self.definition = qc def inverse(self): diff --git a/qiskit/converters/ast_to_dag.py b/qiskit/converters/ast_to_dag.py index 8c77ce208385..b99edfad1cc5 100644 --- a/qiskit/converters/ast_to_dag.py +++ b/qiskit/converters/ast_to_dag.py @@ -388,7 +388,8 @@ def _gate_rules_to_qiskit_circuit(self, node, params): op = self._create_op(child_op.name, params=eparams) rules.append((op, qparams, [])) circ = QuantumCircuit(qreg) - circ._data = rules + for instr, qargs, cargs in rules: + circ._append(instr, qargs, cargs) return circ def _create_dag_op(self, name, params, qargs): diff --git a/qiskit/converters/circuit_to_gate.py b/qiskit/converters/circuit_to_gate.py index 666d8838b9d7..9008e90fc089 100644 --- a/qiskit/converters/circuit_to_gate.py +++ b/qiskit/converters/circuit_to_gate.py @@ -101,6 +101,7 @@ def find_bit_position(bit): []), rules)) qc = QuantumCircuit(q, name=gate.name, global_phase=target.global_phase) - qc._data = rules + for instr, qargs, cargs in rules: + qc._append(instr, qargs, cargs) gate.definition = qc return gate diff --git a/qiskit/converters/circuit_to_instruction.py b/qiskit/converters/circuit_to_instruction.py index 33c1c7dec0f6..d564e4323428 100644 --- a/qiskit/converters/circuit_to_instruction.py +++ b/qiskit/converters/circuit_to_instruction.py @@ -121,7 +121,8 @@ def find_bit_position(bit): 'multiple classical registers to instruction') qc = QuantumCircuit(*regs, name=instruction.name) - qc._data = definition + for instr, qargs, cargs in definition: + qc._append(instr, qargs, cargs) if circuit.global_phase: qc.global_phase = circuit.global_phase diff --git a/releasenotes/notes/4863-Parameterized-gate-definitions-built-with-incomplete-ParameterTable-a9becfb8aff7d906.yaml b/releasenotes/notes/4863-Parameterized-gate-definitions-built-with-incomplete-ParameterTable-a9becfb8aff7d906.yaml new file mode 100644 index 000000000000..869808790afa --- /dev/null +++ b/releasenotes/notes/4863-Parameterized-gate-definitions-built-with-incomplete-ParameterTable-a9becfb8aff7d906.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + When accessing the ``definition`` attribute of a parameterized ``Gate`` + instance, the generated ``QuantumCircuit`` had been generated with an invalid + ``ParameterTable``, such that reading from ``QuantumCircuit.parameters`` or + calling ``QuantumCircuit.bind_parameters`` would incorrectly report the + unbound parameters. This has been resolved. diff --git a/test/python/circuit/test_gate_definitions.py b/test/python/circuit/test_gate_definitions.py index e5e6ca4c26b1..6fa89dbf3965 100644 --- a/test/python/circuit/test_gate_definitions.py +++ b/test/python/circuit/test_gate_definitions.py @@ -13,15 +13,17 @@ """Test hardcoded decomposition rules and matrix definitions for standard gates.""" +import inspect + import numpy as np -from ddt import ddt, data +from ddt import ddt, data, unpack from qiskit import QuantumCircuit from qiskit.quantum_info import Operator from qiskit.test import QiskitTestCase from qiskit.circuit import ParameterVector, Gate, ControlledGate - +from qiskit.circuit.library import standard_gates from qiskit.circuit.library import ( HGate, CHGate, IGate, RGate, RXGate, CRXGate, RYGate, CRYGate, RZGate, CRZGate, SGate, SdgGate, CSwapGate, TGate, TdgGate, U1Gate, CU1Gate, @@ -115,6 +117,42 @@ def test_cx_definition(self): self.assertTrue(Operator(circ).equiv(Operator(decomposed_circ))) +@ddt +class TestStandardGates(QiskitTestCase): + """Standard Extension Test.""" + + @unpack + @data( + *inspect.getmembers( + standard_gates, + predicate=lambda value: (inspect.isclass(value) + and issubclass(value, Gate))) + ) + def test_definition_parameters(self, class_name, gate_class): + """Verify definitions from standard library include correct parameters.""" + + free_params = _get_free_params(gate_class) + n_params = len(free_params) + param_vector = ParameterVector('th', n_params) + + if class_name in ('MCPhaseGate', 'MCU1Gate'): + param_vector = param_vector[:-1] + gate = gate_class(*param_vector, num_ctrl_qubits=2) + elif class_name in ('MCXGate', 'MCXGrayCode', 'MCXRecursive', 'MCXVChain'): + num_ctrl_qubits = 2 + param_vector = param_vector[:-1] + gate = gate_class(num_ctrl_qubits, *param_vector) + elif class_name == 'MSGate': + num_qubits = 2 + param_vector = param_vector[:-1] + gate = gate_class(num_qubits, *param_vector) + else: + gate = gate_class(*param_vector) + + if gate.definition is not None: + self.assertEqual(gate.definition.parameters, set(param_vector)) + + class TestGateEquivalenceEqual(QiskitTestCase): """Test the decomposition of a gate in terms of other gates yields the same matrix as the hardcoded matrix definition."""