Skip to content

Commit 0715eff

Browse files
Add explicit tests for MCX synthesis algorithms (#13961)
* add explicit tests for MCX synthesis algorithms * improving comment * rename variable * remove duplicated tests * add tests for counting CX gates * add some more cx_count tests * remove tests * improving docstring comments (minor) * pass over tests * docstring * increasing the number of control qubits in some tests * improving in-code comments and adding tests as per discussion with Shelly * Shelly's review comments + pylint * using setUp * review comments * removing some tests * removing some more tests --------- Co-authored-by: ShellyGarion <shelly@il.ibm.com>
1 parent cbe07be commit 0715eff

2 files changed

Lines changed: 380 additions & 87 deletions

File tree

test/python/circuit/test_controlled_gate.py

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,8 @@
6262
CRZGate,
6363
CU3Gate,
6464
CUGate,
65-
SGate,
66-
SdgGate,
6765
SXGate,
6866
SXdgGate,
69-
TGate,
70-
TdgGate,
7167
CSXGate,
7268
MSGate,
7369
Barrier,
@@ -713,47 +709,6 @@ def test_mcx_gates_yield_explicit_gates(self, num_ctrl_qubits):
713709
explicit = {1: CXGate, 2: CCXGate}
714710
self.assertEqual(cls, explicit[num_ctrl_qubits])
715711

716-
@combine(num_ctrl_qubits=[1, 2, 3, 4], base_gate=[XGate(), YGate(), ZGate(), HGate()])
717-
def test_small_mcx_gates_yield_cx_count(self, num_ctrl_qubits, base_gate):
718-
"""Test the creating a MCX gate (and other locally equivalent multi-controlled gates)
719-
with small number of controls (with no ancillas) yields the expected number of cx gates
720-
and provides the correct unitary.
721-
"""
722-
qc = QuantumCircuit(num_ctrl_qubits + 1)
723-
qc.append(base_gate.control(num_ctrl_qubits), range(num_ctrl_qubits + 1))
724-
725-
base_mat = base_gate.to_matrix()
726-
test_op = Operator(qc)
727-
cop_mat = _compute_control_matrix(base_mat, num_ctrl_qubits)
728-
self.assertTrue(matrix_equal(cop_mat, test_op.data))
729-
730-
cqc = transpile(qc, basis_gates=["u", "cx"])
731-
cx_count = cqc.count_ops()["cx"]
732-
expected = {1: 1, 2: 6, 3: 14, 4: 36}
733-
self.assertEqual(cx_count, expected[num_ctrl_qubits])
734-
735-
@combine(
736-
num_ctrl_qubits=[1, 2, 3, 4],
737-
base_gate=[PhaseGate(0.123), SGate(), SdgGate(), TGate(), TdgGate(), SXGate(), SXdgGate()],
738-
)
739-
def test_small_mcp_gates_yield_cx_count(self, num_ctrl_qubits, base_gate):
740-
"""Test the creating a MCPhase gate (and other locally equivalent multi-controlled gates)
741-
with small number of controls (with no ancillas) yields the expected number of cx gates
742-
and provides the correct unitary.
743-
"""
744-
qc = QuantumCircuit(num_ctrl_qubits + 1)
745-
qc.append(base_gate.control(num_ctrl_qubits), range(num_ctrl_qubits + 1))
746-
747-
base_mat = base_gate.to_matrix()
748-
test_op = Operator(qc)
749-
cop_mat = _compute_control_matrix(base_mat, num_ctrl_qubits)
750-
self.assertTrue(matrix_equal(cop_mat, test_op.data))
751-
752-
cqc = transpile(qc, basis_gates=["u", "cx"])
753-
cx_count = cqc.count_ops()["cx"]
754-
expected = {1: 2, 2: 6, 3: 20, 4: 44}
755-
self.assertEqual(cx_count, expected[num_ctrl_qubits])
756-
757712
@data(1, 2, 3, 4)
758713
def test_mcxgraycode_gates_yield_explicit_gates(self, num_ctrl_qubits):
759714
"""Test an MCXGrayCode yields explicit definition."""
@@ -790,48 +745,6 @@ def test_mcx_gates(self, num_ctrl_qubits):
790745
statevector = corrected
791746
np.testing.assert_array_almost_equal(statevector.real, reference)
792747

793-
@data(5, 10, 15)
794-
def test_mcxvchain_dirty_ancilla_cx_count(self, num_ctrl_qubits):
795-
"""Test if cx count of the v-chain mcx with dirty ancilla
796-
is less than upper bound."""
797-
mcx_vchain = MCXVChain(num_ctrl_qubits, dirty_ancillas=True)
798-
qc = QuantumCircuit(mcx_vchain.num_qubits)
799-
800-
qc.append(mcx_vchain, list(range(mcx_vchain.num_qubits)))
801-
802-
tr_mcx_vchain = transpile(qc, basis_gates=["u", "cx"])
803-
cx_count = tr_mcx_vchain.count_ops()["cx"]
804-
805-
self.assertLessEqual(cx_count, 8 * num_ctrl_qubits - 6)
806-
807-
@data(5, 10, 15)
808-
def test_mcxvchain_clean_ancilla_cx_count(self, num_ctrl_qubits):
809-
"""Test if cx count of the v-chain mcx with clean ancilla
810-
is less than upper bound."""
811-
mcx_vchain = MCXVChain(num_ctrl_qubits, dirty_ancillas=False)
812-
qc = QuantumCircuit(mcx_vchain.num_qubits)
813-
814-
qc.append(mcx_vchain, list(range(mcx_vchain.num_qubits)))
815-
816-
tr_mcx_vchain = transpile(qc, basis_gates=["u", "cx"])
817-
cx_count = tr_mcx_vchain.count_ops()["cx"]
818-
819-
self.assertLessEqual(cx_count, 6 * num_ctrl_qubits - 6)
820-
821-
@data(7, 10, 15)
822-
def test_mcxrecursive_clean_ancilla_cx_count(self, num_ctrl_qubits):
823-
"""Test if cx count of the mcx with one clean ancilla
824-
is less than upper bound."""
825-
mcx_recursive = MCXRecursive(num_ctrl_qubits)
826-
qc = QuantumCircuit(mcx_recursive.num_qubits)
827-
828-
qc.append(mcx_recursive, list(range(mcx_recursive.num_qubits)))
829-
830-
tr_mcx_rec = transpile(qc, basis_gates=["u", "cx"])
831-
cx_count = tr_mcx_rec.count_ops()["cx"]
832-
833-
self.assertLessEqual(cx_count, 16 * num_ctrl_qubits - 8)
834-
835748
def test_mcxvchain_dirty_ancilla_action_only(self):
836749
"""Test the v-chain mcx with dirty auxiliary qubits
837750
with gate cancelling with mirrored circuit."""

0 commit comments

Comments
 (0)