mirror of https://github.com/Qiskit/qiskit-aer.git
1363 lines
45 KiB
Python
1363 lines
45 KiB
Python
# This code is part of Qiskit.
|
|
#
|
|
# (C) Copyright IBM 2018, 2021.
|
|
#
|
|
# 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.
|
|
"""
|
|
Integration Tests for jump/mark instructions
|
|
"""
|
|
from ddt import ddt, data
|
|
import unittest
|
|
import numpy
|
|
import logging
|
|
from test.terra.backends.simulator_test_case import SimulatorTestCase, supported_methods
|
|
from qiskit_aer import AerSimulator
|
|
from qiskit import QuantumCircuit, transpile
|
|
from qiskit.circuit import Parameter, Qubit, Clbit, QuantumRegister, ClassicalRegister
|
|
from qiskit.circuit.controlflow import *
|
|
from qiskit.circuit.classical import expr, types
|
|
from qiskit_aer.library.default_qubits import default_qubits
|
|
from qiskit_aer.library.control_flow_instructions import AerMark, AerJump
|
|
|
|
|
|
@ddt
|
|
class TestControlFlow(SimulatorTestCase):
|
|
"""Test instructions for jump and mark instructions and compiler functions."""
|
|
|
|
def add_mark(self, circ, name):
|
|
"""Create a mark instruction which can be a destination of jump instructions.
|
|
|
|
Args:
|
|
name (str): an unique name of this mark instruction in a circuit
|
|
"""
|
|
qubits = default_qubits(circ)
|
|
instr = AerMark(name, len(qubits))
|
|
return circ.append(instr, qubits)
|
|
|
|
def add_jump(self, circ, jump_to, clbit=None, value=0):
|
|
"""Create a jump instruction to move a program counter to a named mark.
|
|
|
|
Args:
|
|
jump_to (str): a name of a destination mark instruction
|
|
clbit (Clbit): a classical bit for a condition
|
|
value (int): an int value for a condition. if clbit is value, jump is performed.
|
|
"""
|
|
qubits = default_qubits(circ)
|
|
instr = AerJump(jump_to, len(qubits))
|
|
if clbit:
|
|
instr.c_if(clbit, value)
|
|
return circ.append(instr, qubits)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_jump_always(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(4)
|
|
mark = "mark"
|
|
self.add_jump(circ, mark)
|
|
|
|
for i in range(4):
|
|
circ.h(i)
|
|
|
|
self.add_mark(circ, mark)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0000", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_jump_conditional(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(4, 1)
|
|
mark = "mark"
|
|
self.add_jump(circ, mark, circ.clbits[0])
|
|
|
|
for i in range(4):
|
|
circ.h(i)
|
|
|
|
self.add_mark(circ, mark)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0000 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_no_jump_conditional(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(4, 1)
|
|
mark = "mark"
|
|
self.add_jump(circ, mark, circ.clbits[0], 1)
|
|
|
|
for i in range(4):
|
|
circ.h(i)
|
|
|
|
self.add_mark(circ, mark)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertNotEqual(len(counts), 1)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_invalid_jump(self, method):
|
|
logging.disable(level=logging.WARN)
|
|
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(4, 1)
|
|
mark = "mark"
|
|
invalid_mark = "invalid_mark"
|
|
self.add_jump(circ, invalid_mark, circ.clbits[0])
|
|
|
|
for i in range(4):
|
|
circ.h(i)
|
|
|
|
self.add_mark(circ, mark)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertNotSuccess(result)
|
|
|
|
logging.disable(level=logging.NOTSET)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_duplicated_mark(self, method):
|
|
logging.disable(level=logging.WARN)
|
|
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(4, 1)
|
|
mark = "mark"
|
|
self.add_jump(circ, mark, circ.clbits[0])
|
|
|
|
for i in range(4):
|
|
circ.h(i)
|
|
|
|
self.add_mark(circ, mark)
|
|
self.add_mark(circ, mark)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertNotSuccess(result)
|
|
|
|
logging.disable(level=logging.NOTSET)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_if_true_body_builder(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(4)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.h(circ.qubits[1:4])
|
|
circ.barrier()
|
|
circ.measure(0, 0)
|
|
|
|
with circ.if_test((creg, 1)):
|
|
circ.h(circ.qubits[1:4])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0001 1", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_if_else_body_builder(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(4)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.h(circ.qubits[1:4])
|
|
circ.barrier()
|
|
circ.measure(0, 0)
|
|
|
|
with circ.if_test((creg, 1)) as else_:
|
|
pass
|
|
with else_:
|
|
circ.h(circ.qubits[1:4])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0000 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state")
|
|
def test_for_loop_builder(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(5, 0)
|
|
|
|
with circ.for_loop(range(0)) as a:
|
|
circ.ry(a * numpy.pi, 0)
|
|
with circ.for_loop(range(1)) as a:
|
|
circ.ry(a * numpy.pi, 1)
|
|
with circ.for_loop(range(2)) as a:
|
|
circ.ry(a * numpy.pi, 2)
|
|
with circ.for_loop(range(3)) as a:
|
|
circ.ry(a * numpy.pi, 3)
|
|
with circ.for_loop(range(4)) as a:
|
|
circ.ry(a * numpy.pi, 4)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("01100", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_for_loop_builder_no_loop_variable(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(5, 0)
|
|
|
|
with circ.for_loop(range(0)):
|
|
circ.x(0)
|
|
with circ.for_loop(range(1)):
|
|
circ.x(1)
|
|
with circ.for_loop(range(2)):
|
|
circ.x(2)
|
|
with circ.for_loop(range(3)):
|
|
circ.x(3)
|
|
with circ.for_loop(range(4)):
|
|
circ.x(4)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("01010", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state")
|
|
def test_for_loop_break_builder(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(5)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
|
|
with circ.for_loop(range(0)) as a:
|
|
circ.ry(a * numpy.pi, 0)
|
|
circ.measure(0, 0)
|
|
with circ.if_test((creg, 1)):
|
|
circ.break_loop()
|
|
with circ.for_loop(range(1)) as a:
|
|
circ.ry(a * numpy.pi, 1)
|
|
circ.measure(1, 0)
|
|
with circ.if_test((creg, 1)):
|
|
circ.break_loop()
|
|
with circ.for_loop(range(2)) as a:
|
|
circ.ry(a * numpy.pi, 2)
|
|
circ.measure(2, 0)
|
|
with circ.if_test((creg, 1)):
|
|
circ.break_loop()
|
|
with circ.for_loop(range(3)) as a:
|
|
circ.ry(a * numpy.pi, 3)
|
|
circ.measure(3, 0)
|
|
with circ.if_test((creg, 1)):
|
|
circ.break_loop()
|
|
with circ.for_loop(range(4)) as a:
|
|
circ.ry(a * numpy.pi, 4)
|
|
circ.measure(4, 0)
|
|
with circ.if_test((creg, 1)):
|
|
circ.break_loop()
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("11100 1", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state")
|
|
def test_for_loop_continue_builder(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(5)
|
|
cregs = [ClassicalRegister(1) for _ in range(5)]
|
|
circ = QuantumCircuit(qreg, *cregs)
|
|
|
|
with circ.for_loop(range(0)) as a:
|
|
circ.ry(a * numpy.pi, 0) # dead code
|
|
circ.measure(0, 0) # dead code
|
|
with circ.if_test((cregs[0], 1)):
|
|
circ.continue_loop() # dead code
|
|
circ.y(0) # dead code
|
|
# 1st cbit -> 0
|
|
# 1st meas cbit -> 0
|
|
|
|
with circ.for_loop(range(1)) as a:
|
|
circ.ry(a * numpy.pi, 1)
|
|
circ.measure(1, 1)
|
|
with circ.if_test((cregs[1], 1)):
|
|
circ.continue_loop() # dead code
|
|
circ.y(1)
|
|
# 2nd cbit -> 0
|
|
# 2nd meas cbit -> 1
|
|
|
|
with circ.for_loop(range(2)) as a:
|
|
circ.ry(a * numpy.pi, 2)
|
|
circ.measure(2, 2)
|
|
with circ.if_test((cregs[2], 1)):
|
|
circ.continue_loop()
|
|
circ.y(2)
|
|
# 3rd cbit -> 0
|
|
# 3rd meas cbit -> 1
|
|
|
|
with circ.for_loop(range(3)) as a:
|
|
circ.ry(a * numpy.pi, 3)
|
|
circ.measure(3, 3)
|
|
with circ.if_test((cregs[3], 1)):
|
|
circ.continue_loop()
|
|
circ.y(3)
|
|
# 4th cbit -> 1
|
|
# 4th meas cbit -> 1
|
|
|
|
with circ.for_loop(range(4)) as a:
|
|
circ.ry(a * numpy.pi, 4)
|
|
circ.measure(4, 4)
|
|
with circ.if_test((cregs[4], 1)):
|
|
circ.continue_loop()
|
|
circ.y(4)
|
|
# 5th cbit -> 0
|
|
# 5th meas cbit -> 1
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("11110 0 1 0 0 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_while_loop_no_iteration(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(1)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.measure(0, 0)
|
|
with circ.while_loop((creg, 1)):
|
|
circ.y(0)
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_while_loop_single_iteration(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(2)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.measure(0, 0)
|
|
|
|
# does not work
|
|
# while circ.while_loop((creg, 1)):
|
|
# circ.y(0)
|
|
# circ.measure(0, 0)
|
|
# circ.y(1)
|
|
|
|
circ_while = QuantumCircuit(qreg, creg)
|
|
circ_while.y(0)
|
|
circ_while.measure(0, 0)
|
|
circ_while.y(1)
|
|
circ.while_loop((creg, 1), circ_while, [0, 1], [0])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("10 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_while_loop_double_iterations(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(2)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.measure(0, 0)
|
|
|
|
# does not work
|
|
# while circ.while_loop((creg, 1)):
|
|
# circ.y(0)
|
|
# circ.measure(0, 0)
|
|
# circ.y(1)
|
|
|
|
circ_while = QuantumCircuit(qreg, creg)
|
|
circ_while.measure(0, 0)
|
|
circ_while.y(0)
|
|
circ_while.y(1)
|
|
circ.while_loop((creg, 1), circ_while, [0, 1], [0])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("01 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_while_loop_continue(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(1)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.measure(0, 0)
|
|
|
|
# does not work
|
|
# while circ.while_loop((creg, 1)):
|
|
# circ.y(0)
|
|
# circ.measure(0, 0)
|
|
# circ.continue_loop()
|
|
# circ.y(0)
|
|
|
|
circ_while = QuantumCircuit(qreg, creg)
|
|
circ_while.y(0)
|
|
circ_while.measure(0, 0)
|
|
circ_while.continue_loop()
|
|
circ_while.y(0)
|
|
circ_while.break_loop()
|
|
circ.while_loop((creg, 1), circ_while, [0], [0])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0 0", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state")
|
|
def test_nested_loop(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(3)
|
|
|
|
with circ.for_loop(range(2)) as a:
|
|
with circ.for_loop(range(2)) as b:
|
|
circ.ry(a * b * numpy.pi, 0)
|
|
|
|
with circ.for_loop(range(3)) as a:
|
|
with circ.for_loop(range(3)) as b:
|
|
circ.ry(a * b * numpy.pi, 1)
|
|
|
|
with circ.for_loop(range(4)) as a:
|
|
with circ.for_loop(range(2)) as b:
|
|
circ.ry(a * b * numpy.pi, 2)
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("011", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_while_loop_last(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
circ = QuantumCircuit(1, 1)
|
|
circ.h(0)
|
|
circ.measure(0, 0)
|
|
with circ.while_loop((circ.clbits[0], True)):
|
|
circ.h(0)
|
|
circ.measure(0, 0)
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_no_invalid_nested_reordering(self, method):
|
|
"""Test that the jump/mark system doesn't allow nested conditional marks to jump incorrectly
|
|
relative to their outer marks. Regression test of gh-1665."""
|
|
backend = self.backend(method=method)
|
|
|
|
circuit = QuantumCircuit(3, 3)
|
|
circuit.initialize("010", circuit.qubits)
|
|
circuit.measure(0, 0)
|
|
circuit.measure(1, 1)
|
|
with circuit.if_test((0, True)):
|
|
with circuit.if_test((1, False)):
|
|
circuit.x(2)
|
|
with circuit.if_test((0, False)):
|
|
with circuit.if_test((1, True)):
|
|
circuit.x(2)
|
|
circuit.measure(range(3), range(3))
|
|
|
|
result = backend.run(circuit, method=method, shots=100).result()
|
|
self.assertSuccess(result)
|
|
self.assertEqual(result.get_counts(), {"110": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_no_invalid_reordering_if(self, method):
|
|
"""Test that the jump/mark system doesn't allow an unrelated operation to jump inside a
|
|
conditional statement."""
|
|
backend = self.backend(method=method)
|
|
|
|
circuit = QuantumCircuit(3, 3)
|
|
circuit.measure(1, 1)
|
|
# This should never be entered.
|
|
with circuit.if_test((1, True)):
|
|
circuit.x(0)
|
|
circuit.x(2)
|
|
# In the topological ordering that `DAGCircuit` uses, this X on qubit 1 will naturally
|
|
# appear between the X on 0 and X on 2 once they are inlined, and the jump/mark instructions
|
|
# won't act as a full barrier, because the if test doesn't touch qubit 1. In this case, the
|
|
# X on 1 will migrate to between the jump and mark, causing it to be skipped along with the
|
|
# other X gates. This test ensures that suitable full-width barriers are in place to stop
|
|
# that from happening.
|
|
circuit.x(1)
|
|
|
|
circuit.measure(circuit.qubits, circuit.clbits)
|
|
|
|
result = backend.run(circuit, method=method, shots=100).result()
|
|
self.assertSuccess(result)
|
|
self.assertEqual(result.get_counts(), {"010": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_no_invalid_reordering_while(self, method):
|
|
"""Test that the jump/mark system doesn't allow an unrelated operation to jump inside a
|
|
conditional statement."""
|
|
backend = self.backend(method=method)
|
|
|
|
circuit = QuantumCircuit(3, 3)
|
|
circuit.measure(1, 1)
|
|
# This should never be entered.
|
|
with circuit.while_loop((1, True)):
|
|
circuit.x(0)
|
|
circuit.x(2)
|
|
# In the topological ordering that `DAGCircuit` uses, this X on qubit 1 will naturally
|
|
# appear between the X on 0 and X on 2 once they are inlined, and the jump/mark instructions
|
|
# won't act as a full barrier, because the if test doesn't touch qubit 1. In this case, the
|
|
# X on 1 will migrate to between the jump and mark, causing it to be skipped along with the
|
|
# other X gates. This test ensures that suitable full-width barriers are in place to stop
|
|
# that from happening.
|
|
circuit.x(1)
|
|
|
|
circuit.measure(circuit.qubits, circuit.clbits)
|
|
|
|
result = backend.run(circuit, method=method, shots=100).result()
|
|
self.assertSuccess(result)
|
|
self.assertEqual(result.get_counts(), {"010": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_transpile_break_and_continue_loop(self, method):
|
|
"""Test that transpiler can transpile break_loop and continue_loop with AerSimulator"""
|
|
|
|
backend = self.backend(method=method, seed_simulator=1)
|
|
|
|
qc = QuantumCircuit(1, 1)
|
|
|
|
with qc.for_loop(range(1000)):
|
|
qc.h(0)
|
|
qc.measure(0, 0)
|
|
with qc.if_test((0, True)):
|
|
qc.break_loop()
|
|
|
|
transpiled = transpile(qc, backend)
|
|
result = backend.run(transpiled, method=method, shots=100).result()
|
|
self.assertEqual(result.get_counts(), {"1": 100})
|
|
|
|
qc = QuantumCircuit(1, 1)
|
|
|
|
with qc.for_loop(range(1000)):
|
|
qc.h(0)
|
|
qc.measure(0, 0)
|
|
with qc.if_test((0, False)):
|
|
qc.continue_loop()
|
|
qc.break_loop()
|
|
|
|
transpiled = transpile(qc, backend)
|
|
result = backend.run(transpiled, method=method, shots=100).result()
|
|
self.assertEqual(result.get_counts(), {"1": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_switch_clbit(self, method):
|
|
"""Test that a switch statement can be constructed with a bit as a condition."""
|
|
|
|
backend = self.backend(method=method)
|
|
|
|
qubit = Qubit()
|
|
clbit = Clbit()
|
|
case0 = QuantumCircuit([qubit, clbit])
|
|
case0.x(0)
|
|
case1 = QuantumCircuit([qubit, clbit])
|
|
case1.h(0)
|
|
|
|
op = SwitchCaseOp(clbit, [(False, case0), (True, case1)])
|
|
|
|
qc0 = QuantumCircuit([qubit, clbit])
|
|
qc0.measure(qubit, clbit)
|
|
qc0.append(op, [qubit], [clbit])
|
|
qc0.measure_all()
|
|
|
|
qc0_expected = QuantumCircuit([qubit, clbit])
|
|
qc0_expected.measure(qubit, clbit)
|
|
qc0_expected.append(case0, [qubit], [clbit])
|
|
qc0_expected.measure_all()
|
|
qc0_expected = transpile(qc0_expected, backend)
|
|
|
|
ret0 = backend.run(qc0, shots=10000, seed_simulator=1).result()
|
|
ret0_expected = backend.run(qc0_expected, shots=10000, seed_simulator=1).result()
|
|
self.assertSuccess(ret0)
|
|
self.assertEqual(ret0.get_counts(), ret0_expected.get_counts())
|
|
|
|
qc1 = QuantumCircuit([qubit, clbit])
|
|
qc1.x(0)
|
|
qc1.measure(qubit, clbit)
|
|
qc1.append(op, [qubit], [clbit])
|
|
qc1.measure_all()
|
|
|
|
qc1_expected = QuantumCircuit([qubit, clbit])
|
|
qc1_expected.x(0)
|
|
qc1_expected.measure(qubit, clbit)
|
|
qc1_expected.append(case1, [qubit], [clbit])
|
|
qc1_expected.measure_all()
|
|
qc1_expected = transpile(qc1_expected, backend)
|
|
|
|
ret1 = backend.run(qc1, shots=10000, seed_simulator=1).result()
|
|
ret1_expected = backend.run(qc1_expected, shots=10000, seed_simulator=1).result()
|
|
self.assertSuccess(ret1)
|
|
self.assertEqual(ret1.get_counts(), ret1_expected.get_counts())
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_switch_register(self, method):
|
|
"""Test that a switch statement can be constructed with a register as a condition."""
|
|
|
|
backend = self.backend(method=method, seed_simulator=1)
|
|
|
|
qubit0 = Qubit()
|
|
qubit1 = Qubit()
|
|
qubit2 = Qubit()
|
|
creg = ClassicalRegister(2)
|
|
case1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case1.x(0)
|
|
case2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case2.x(1)
|
|
case3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case3.x(2)
|
|
|
|
op = SwitchCaseOp(creg, [(0, case1), (1, case2), (2, case3)])
|
|
|
|
qc0 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc0.measure(0, creg[0])
|
|
qc0.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc0.measure_all()
|
|
|
|
ret0 = backend.run(qc0, shots=100).result()
|
|
self.assertSuccess(ret0)
|
|
self.assertEqual(ret0.get_counts(), {"001 00": 100})
|
|
|
|
qc1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc1.x(0)
|
|
qc1.measure(0, creg[0])
|
|
qc1.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc1.measure_all()
|
|
|
|
ret1 = backend.run(qc1, shots=100).result()
|
|
self.assertSuccess(ret1)
|
|
self.assertEqual(ret1.get_counts(), {"011 01": 100})
|
|
|
|
qc2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc2.x(1)
|
|
qc2.measure(0, creg[0])
|
|
qc2.measure(1, creg[1])
|
|
qc2.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc2.measure_all()
|
|
|
|
ret2 = backend.run(qc2, shots=100).result()
|
|
self.assertSuccess(ret2)
|
|
self.assertEqual(ret2.get_counts(), {"110 10": 100})
|
|
|
|
qc3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc3.x(0)
|
|
qc3.x(1)
|
|
qc3.measure(0, creg[0])
|
|
qc3.measure(1, creg[1])
|
|
qc3.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc3.measure_all()
|
|
|
|
ret3 = backend.run(qc3, shots=100).result()
|
|
self.assertSuccess(ret3)
|
|
self.assertEqual(ret3.get_counts(), {"011 11": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_switch_with_default(self, method):
|
|
"""Test that a switch statement can be constructed with a default case at the end."""
|
|
|
|
backend = self.backend(method=method, seed_simulator=1)
|
|
|
|
qubit0 = Qubit()
|
|
qubit1 = Qubit()
|
|
qubit2 = Qubit()
|
|
creg = ClassicalRegister(2)
|
|
case1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case1.x(0)
|
|
case2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case2.x(1)
|
|
case3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case3.x(2)
|
|
|
|
op = SwitchCaseOp(creg, [(0, case1), (1, case2), (CASE_DEFAULT, case3)])
|
|
|
|
qc0 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc0.measure(0, creg[0])
|
|
qc0.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc0.measure_all()
|
|
|
|
ret0 = backend.run(qc0, shots=100).result()
|
|
self.assertSuccess(ret0)
|
|
self.assertEqual(ret0.get_counts(), {"001 00": 100})
|
|
|
|
qc1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc1.x(0)
|
|
qc1.measure(0, creg[0])
|
|
qc1.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc1.measure_all()
|
|
|
|
ret1 = backend.run(qc1, shots=100).result()
|
|
self.assertSuccess(ret1)
|
|
self.assertEqual(ret1.get_counts(), {"011 01": 100})
|
|
|
|
qc2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc2.x(1)
|
|
qc2.measure(0, creg[0])
|
|
qc2.measure(1, creg[1])
|
|
qc2.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc2.measure_all()
|
|
|
|
ret2 = backend.run(qc2, shots=100).result()
|
|
self.assertSuccess(ret2)
|
|
self.assertEqual(ret2.get_counts(), {"110 10": 100})
|
|
|
|
qc3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc3.x(0)
|
|
qc3.x(1)
|
|
qc3.measure(0, creg[0])
|
|
qc3.measure(1, creg[1])
|
|
qc3.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc3.measure_all()
|
|
|
|
ret3 = backend.run(qc3, shots=100).result()
|
|
self.assertSuccess(ret3)
|
|
self.assertEqual(ret3.get_counts(), {"111 11": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_switch_multiple_cases_to_same_block(self, method):
|
|
"""Test that it is possible to add multiple cases that apply to the same block, if they are
|
|
given as a compound value. This is an allowed special case of block fall-through."""
|
|
|
|
backend = self.backend(method=method, seed_simulator=1)
|
|
|
|
qubit0 = Qubit()
|
|
qubit1 = Qubit()
|
|
qubit2 = Qubit()
|
|
creg = ClassicalRegister(2)
|
|
case1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case1.x(0)
|
|
case2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case2.x(1)
|
|
|
|
creg = ClassicalRegister(2)
|
|
|
|
op = SwitchCaseOp(creg, [(0, case1), ((1, 2), case2)])
|
|
|
|
qc0 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc0.measure(0, creg[0])
|
|
qc0.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc0.measure_all()
|
|
|
|
ret0 = backend.run(qc0, shots=100).result()
|
|
self.assertSuccess(ret0)
|
|
self.assertEqual(ret0.get_counts(), {"001 00": 100})
|
|
|
|
qc1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc1.x(0)
|
|
qc1.measure(0, creg[0])
|
|
qc1.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc1.measure_all()
|
|
|
|
ret1 = backend.run(qc1, shots=100).result()
|
|
self.assertSuccess(ret1)
|
|
self.assertEqual(ret1.get_counts(), {"011 01": 100})
|
|
|
|
qc2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc2.x(1)
|
|
qc2.measure(0, creg[0])
|
|
qc2.measure(1, creg[1])
|
|
qc2.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc2.measure_all()
|
|
|
|
ret2 = backend.run(qc2, shots=100).result()
|
|
self.assertSuccess(ret2)
|
|
self.assertEqual(ret2.get_counts(), {"000 10": 100})
|
|
|
|
qc3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc3.x(0)
|
|
qc3.x(1)
|
|
qc3.measure(0, creg[0])
|
|
qc3.measure(1, creg[1])
|
|
qc3.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc3.measure_all()
|
|
|
|
ret3 = backend.run(qc3, shots=100).result()
|
|
self.assertSuccess(ret3)
|
|
self.assertEqual(ret3.get_counts(), {"011 11": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_switch_transpilation(self, method):
|
|
"""Test swtich test cases can be transpiled"""
|
|
|
|
backend = self.backend(method=method, seed_simulator=1)
|
|
|
|
qubit0 = Qubit()
|
|
qubit1 = Qubit()
|
|
qubit2 = Qubit()
|
|
|
|
creg = ClassicalRegister(2)
|
|
qc = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
|
|
with qc.switch(creg) as case:
|
|
with case(0):
|
|
qc.x(0)
|
|
with case(1):
|
|
qc.x(1)
|
|
with case(case.DEFAULT):
|
|
qc.x(2)
|
|
|
|
qc.measure_all()
|
|
|
|
transpiled = transpile(qc, backend)
|
|
|
|
ret0 = backend.run(transpiled, shots=100).result()
|
|
self.assertSuccess(ret0)
|
|
self.assertEqual(ret0.get_counts(), {"001 00": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_switch_register_with_classical_expression(self, method):
|
|
"""Test that a switch statement can be constructed with a register as a condition."""
|
|
|
|
backend = self.backend(method=method, seed_simulator=1)
|
|
|
|
qubit0 = Qubit()
|
|
qubit1 = Qubit()
|
|
qubit2 = Qubit()
|
|
creg = ClassicalRegister(2)
|
|
case1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case1.x(0)
|
|
case2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case2.x(1)
|
|
case3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
case3.x(2)
|
|
|
|
op = SwitchCaseOp(expr.lift(creg), [(0, case1), (1, case2), (2, case3)])
|
|
|
|
qc0 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc0.measure(0, creg[0])
|
|
qc0.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc0.measure_all()
|
|
|
|
ret0 = backend.run(qc0, shots=100).result()
|
|
self.assertSuccess(ret0)
|
|
self.assertEqual(ret0.get_counts(), {"001 00": 100})
|
|
|
|
qc1 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc1.x(0)
|
|
qc1.measure(0, creg[0])
|
|
qc1.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc1.measure_all()
|
|
|
|
ret1 = backend.run(qc1, shots=1).result()
|
|
self.assertSuccess(ret1)
|
|
self.assertEqual(ret1.get_counts(), {"011 01": 1})
|
|
|
|
qc2 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc2.x(1)
|
|
qc2.measure(0, creg[0])
|
|
qc2.measure(1, creg[1])
|
|
qc2.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc2.measure_all()
|
|
|
|
ret2 = backend.run(qc2, shots=100).result()
|
|
self.assertSuccess(ret2)
|
|
self.assertEqual(ret2.get_counts(), {"110 10": 100})
|
|
|
|
qc3 = QuantumCircuit([qubit0, qubit1, qubit2], creg)
|
|
qc3.x(0)
|
|
qc3.x(1)
|
|
qc3.measure(0, creg[0])
|
|
qc3.measure(1, creg[1])
|
|
qc3.append(op, [qubit0, qubit1, qubit2], creg)
|
|
qc3.measure_all()
|
|
|
|
ret3 = backend.run(qc3, shots=100).result()
|
|
self.assertSuccess(ret3)
|
|
self.assertEqual(ret3.get_counts(), {"011 11": 100})
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_if_expr_true_body_builder(self, method):
|
|
"""test expression with branch operation"""
|
|
backend = self.backend(method=method)
|
|
|
|
# case creg==1
|
|
qreg = QuantumRegister(4)
|
|
creg = ClassicalRegister(3, "test")
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.h(circ.qubits[1:4])
|
|
circ.barrier()
|
|
circ.measure(0, 0) # 001
|
|
|
|
with circ.if_test(expr.equal(ClassicalRegister(3, "test"), 1)):
|
|
circ.h(circ.qubits[1:4])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0001 001", counts)
|
|
|
|
# case creg==3
|
|
qreg = QuantumRegister(4)
|
|
creg = ClassicalRegister(3, "test")
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.h(circ.qubits[1:4])
|
|
circ.barrier()
|
|
circ.measure(0, 0)
|
|
circ.measure(0, 1) # 011
|
|
|
|
with circ.if_test(expr.equal(ClassicalRegister(3, "test"), 3)):
|
|
circ.h(circ.qubits[1:4])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0001 011", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_if_expr_false_body_builder(self, method):
|
|
"""test expression with branch operation"""
|
|
backend = self.backend(method=method)
|
|
|
|
# case creg==1
|
|
qreg = QuantumRegister(4)
|
|
creg = ClassicalRegister(3, "test")
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.h(circ.qubits[1:4])
|
|
circ.barrier()
|
|
circ.measure(0, 0) # 001
|
|
|
|
with circ.if_test(expr.equal(ClassicalRegister(3, "test"), 2)) as else_:
|
|
circ.y(0)
|
|
with else_:
|
|
circ.h(circ.qubits[1:4])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0001 001", counts)
|
|
|
|
# case creg==3
|
|
qreg = QuantumRegister(4)
|
|
creg = ClassicalRegister(3, "test")
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.h(circ.qubits[1:4])
|
|
circ.barrier()
|
|
circ.measure(0, 0)
|
|
circ.measure(0, 1) # 011
|
|
|
|
with circ.if_test(expr.equal(ClassicalRegister(3, "test"), 1)) as else_:
|
|
circ.y(0)
|
|
with else_:
|
|
circ.h(circ.qubits[1:4])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0001 011", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_while_expr_loop_break(self, method):
|
|
backend = self.backend(method=method)
|
|
|
|
qreg = QuantumRegister(1)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.measure(0, 0)
|
|
|
|
circ_while = QuantumCircuit(qreg, creg)
|
|
circ_while.y(0)
|
|
circ_while.measure(0, 0)
|
|
circ_while.break_loop()
|
|
circ.while_loop(expr.Value(True, types.Bool()), circ_while, [0], [0])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0 0", counts)
|
|
|
|
qreg = QuantumRegister(1)
|
|
creg = ClassicalRegister(1)
|
|
circ = QuantumCircuit(qreg, creg)
|
|
circ.y(0)
|
|
circ.measure(0, 0)
|
|
|
|
circ_while = QuantumCircuit(qreg, creg)
|
|
circ_while.y(0)
|
|
circ_while.measure(0, 0)
|
|
circ_while.break_loop()
|
|
circ.while_loop(expr.Value(False, types.Bool()), circ_while, [0], [0])
|
|
|
|
circ.measure_all()
|
|
|
|
result = backend.run(circ, method=method).result()
|
|
self.assertSuccess(result)
|
|
|
|
counts = result.get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("1 1", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_bit_and_operation(self, method):
|
|
"""test bit-and operation"""
|
|
qr = QuantumRegister(7)
|
|
cr = ClassicalRegister(7)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(0)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4)) # 0101
|
|
qc.barrier()
|
|
b01 = expr.bit_and(cr[0], cr[1]) # 1 & 0 -> 0
|
|
with qc.if_test(b01):
|
|
qc.x(4) # q4 -> 0
|
|
|
|
b02 = expr.bit_and(cr[0], cr[2]) # 1 & 1 -> 1
|
|
with qc.if_test(b02):
|
|
qc.x(5) # q5 -> 0
|
|
|
|
b13 = expr.bit_and(cr[1], cr[3]) # 0 & 0 -> 0
|
|
with qc.if_test(b13):
|
|
qc.x(6) # q6 -> 0
|
|
|
|
qc.measure(range(7), range(7)) # 0100101
|
|
|
|
backend = self.backend(method=method)
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0100101", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_bit_or_operation(self, method):
|
|
"""test bit-or operation"""
|
|
qr = QuantumRegister(7)
|
|
cr = ClassicalRegister(7)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(0)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4)) # 0101
|
|
qc.barrier()
|
|
b01 = expr.bit_or(cr[0], cr[1]) # 1 & 0 -> 1
|
|
with qc.if_test(b01):
|
|
qc.x(4) # q4 -> 1
|
|
|
|
b02 = expr.bit_or(cr[0], cr[2]) # 1 & 1 -> 1
|
|
with qc.if_test(b02):
|
|
qc.x(5) # q5 -> 0
|
|
|
|
b13 = expr.bit_or(cr[1], cr[3]) # 0 & 0 -> 0
|
|
with qc.if_test(b13):
|
|
qc.x(6) # q6 -> 0
|
|
|
|
qc.measure(range(7), range(7)) # 0110101
|
|
|
|
backend = self.backend(method=method)
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0110101", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_bit_xor_operation(self, method):
|
|
"""test bit-or operation"""
|
|
qr = QuantumRegister(8)
|
|
cr = ClassicalRegister(8)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(0)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4)) # 0101
|
|
qc.barrier()
|
|
b01 = expr.bit_xor(cr[0], cr[1]) # (bool) 1 & (bool) 0 -> (bool) 1
|
|
with qc.if_test(b01):
|
|
qc.x(4) # q4 -> 1
|
|
|
|
b02 = expr.bit_xor(cr[0], cr[2]) # (bool) 1 & (bool) 1 -> (bool) 0
|
|
with qc.if_test(b02):
|
|
qc.x(5) # q5 -> 0
|
|
|
|
b03 = expr.bit_xor(cr[1], cr[3]) # (bool) 0 & (bool) 0 -> (bool) 0
|
|
with qc.if_test(b03):
|
|
qc.x(6) # q6 -> 0
|
|
|
|
b04 = expr.bit_xor(
|
|
expr.Value(True, types.Bool()), expr.Value(False, types.Bool())
|
|
) # (bool) 1 & (bool) 0 -> (bool) 1
|
|
with qc.if_test(b04):
|
|
qc.x(7) # q7 -> 1
|
|
|
|
qc.measure(range(8), range(8)) # 10010101
|
|
|
|
backend = self.backend(method=method)
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("10010101", counts)
|
|
|
|
qr = QuantumRegister(7)
|
|
cr = ClassicalRegister(7)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(0)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4)) # 0101
|
|
qc.barrier()
|
|
try:
|
|
b04 = expr.bit_xor(
|
|
expr.Var(cr, types.Uint(cr.size)), expr.Var(cr, types.Uint(cr.size))
|
|
) # (bool) 1 ^ (uint) 0101 -> error
|
|
self.fail("do not reach here")
|
|
except Exception:
|
|
pass
|
|
|
|
qr = QuantumRegister(7)
|
|
cr = ClassicalRegister(7)
|
|
cr0 = ClassicalRegister(7)
|
|
qc = QuantumCircuit(qr, cr, cr0)
|
|
qc.x(0)
|
|
qc.x(1)
|
|
qc.x(2)
|
|
qc.x(3)
|
|
qc.measure(range(4), range(4)) # 1111
|
|
qc.barrier()
|
|
b05 = expr.bit_xor(
|
|
expr.Var(cr, types.Uint(cr.size)), expr.Var(cr, types.Uint(cr.size))
|
|
) # (uint) 1111 ^ (uint) 1111 -> (uint) 0000
|
|
with qc.if_test(expr.equal(b05, 0b0000000)):
|
|
qc.x(4) # q4 -> 1
|
|
b06 = expr.bit_xor(
|
|
expr.Var(cr0, types.Uint(cr0.size)), expr.Var(cr, types.Uint(cr.size))
|
|
) # (uint) 0000 ^ (uint) 0101 -> (uint) 1111
|
|
with qc.if_test(expr.equal(b06, 0b0001111)):
|
|
qc.x(5) # q5 -> 1
|
|
|
|
qc.measure(range(7), range(7)) # 111111
|
|
|
|
backend = self.backend(method=method)
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0000000 0111111", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_bit_not_operation(self, method):
|
|
"""test bit-not operation"""
|
|
qr = QuantumRegister(7)
|
|
cr = ClassicalRegister(7)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(0)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4)) # 0101
|
|
qc.barrier()
|
|
b01 = expr.bit_not(cr[0]) # !1 -> 0
|
|
with qc.if_test(b01):
|
|
qc.x(4) # q4 -> 0
|
|
|
|
b02 = expr.bit_not(cr[1]) # !0 -> 1
|
|
with qc.if_test(b02):
|
|
qc.x(5) # q5 -> 1
|
|
|
|
qc.measure(range(7), range(7)) # 0100101
|
|
|
|
backend = self.backend(method=method)
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0100101", counts)
|
|
|
|
qr = QuantumRegister(7)
|
|
cr = ClassicalRegister(7)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(0)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4)) # 0101
|
|
qc.barrier()
|
|
b01 = expr.bit_not(expr.Var(cr, types.Uint(cr.size))) # 0b0000101 -> 0b1111010
|
|
with qc.if_test(expr.equal(b01, 0b1111010)):
|
|
qc.x(4) # q4 -> 1
|
|
|
|
qc.measure(range(7), range(7)) # 0010101
|
|
|
|
backend = self.backend(method=method)
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0010101", counts)
|
|
|
|
@data("statevector", "density_matrix", "matrix_product_state", "stabilizer")
|
|
def test_store_simple(self, method):
|
|
"""test store operation"""
|
|
backend = self.backend(method=method)
|
|
|
|
# Check stored values can be sampled
|
|
qr = QuantumRegister(4)
|
|
cr = ClassicalRegister(4)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4))
|
|
qc.store(cr, 0b1000) # measured classical registers are modified
|
|
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("1000", counts)
|
|
|
|
# Check stored values to creg can be evaluated
|
|
qr = QuantumRegister(4)
|
|
cr = ClassicalRegister(4)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4))
|
|
qc.store(cr, 0b1000) # override
|
|
with qc.if_test((2, False)):
|
|
# must reach
|
|
qc.x(1) # 0b1010
|
|
qc.measure(range(4), range(4))
|
|
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0110", counts)
|
|
|
|
# Check stored values to clbit can be evaluated
|
|
qr = QuantumRegister(4)
|
|
cr = ClassicalRegister(4)
|
|
qc = QuantumCircuit(qr, cr)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4))
|
|
qc.store(cr[2], False) # override
|
|
with qc.if_test((2, False)):
|
|
# must reach
|
|
qc.x(1) # 0b1010
|
|
qc.measure(range(4), range(4))
|
|
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("0110", counts)
|
|
|
|
# Check stored values can be stored
|
|
qr = QuantumRegister(4)
|
|
cr0 = ClassicalRegister(4)
|
|
cr1 = ClassicalRegister(4)
|
|
qc = QuantumCircuit(qr, cr0, cr1)
|
|
qc.x(2)
|
|
qc.measure(range(4), range(4))
|
|
qc.store(cr0, 0b1000) # measured classical registers are modified
|
|
qc.store(cr1, cr0) # measured classical registers are modified
|
|
|
|
counts = backend.run(qc).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("1000 1000", counts)
|
|
|
|
def test_bit_mapping_in_compiler(self):
|
|
"""Test different bit mappings are correctly inlined"""
|
|
parent = QuantumCircuit(5, 2)
|
|
parent.x(0)
|
|
parent.measure(0, 0)
|
|
|
|
true_body = QuantumCircuit(1, 0)
|
|
true_body.x(0)
|
|
|
|
parent.append(IfElseOp((parent.clbits[0], 1), true_body), [1], [])
|
|
|
|
parent.measure(1, 1)
|
|
|
|
simulator = self.backend()
|
|
counts = simulator.run(parent).result().get_counts()
|
|
self.assertEqual(len(counts), 1)
|
|
self.assertIn("11", counts)
|