def test_correctness_2(self) -> None: circuit = Circuit(2) circuit.append_gate(HGate(), [0]) circuit.append_gate(CNOTGate(), [0, 1]) assert circuit.get_operation((0, 0)).gate == HGate() assert circuit.get_operation((1, 0)).gate == CNOTGate() assert circuit.get_operation((1, 1)).gate == CNOTGate()
def swap_circuit() -> Circuit: """Provides a swap implemented with 3 cnots as a circuit fixture.""" circuit = Circuit(2) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(CNOTGate(), [1, 0]) circuit.append_gate(CNOTGate(), [0, 1]) return circuit
def simple_circuit() -> Circuit: """Provides a simple circuit fixture.""" circuit = Circuit(2) circuit.append_gate(XGate(), [0]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(XGate(), [1]) circuit.append_gate(CNOTGate(), [1, 0]) return circuit
def test_append_gate(self) -> None: circuit = Circuit(4) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(CNOTGate(), [2, 3]) circuit.append_qudit() circuit.append_gate(CNOTGate(), [3, 4]) assert circuit.get_size() == 5 assert circuit[3, 4].gate == CNOTGate()
def test_r1(self, r3_qubit_circuit: Circuit) -> None: assert r3_qubit_circuit.get_num_operations() == 10 r3_qubit_circuit.append_gate(U3Gate(), [0]) assert r3_qubit_circuit.get_num_operations() == 11 r3_qubit_circuit.insert_gate(0, U3Gate(), [1]) assert r3_qubit_circuit.get_num_operations() == 12 r3_qubit_circuit.insert_gate(0, CNOTGate(), [0, 2]) assert r3_qubit_circuit.get_num_operations() == 13 r3_qubit_circuit.remove(U3Gate()) assert r3_qubit_circuit.get_num_operations() == 12 r3_qubit_circuit.remove(CNOTGate()) assert r3_qubit_circuit.get_num_operations() == 11
def test_correctness_2(self) -> None: circuit = Circuit(2) circuit.append_gate(HGate(), [0]) circuit.append_gate(CNOTGate(), [0, 1]) assert circuit.point(HGate()) == (0, 0) assert circuit.point(CNOTGate()) == (1, 0) assert circuit.point(Operation(HGate(), [0])) == (0, 0) assert circuit.point(Operation(CNOTGate(), [0, 1])) == (1, 0) try: circuit.point(Operation(CNOTGate(), [1, 0])) except ValueError: return assert False, 'Should not have reached here.'
def test_append_gate_3(self, qudit_index: int) -> None: circuit = Circuit(4) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(CNOTGate(), [2, 3]) circuit.pop_qudit(qudit_index) assert circuit.get_size() == 3 assert len(circuit.get_radixes()) == 3 assert circuit.get_radixes().count(2) == 3 assert circuit.get_num_operations() == 1 assert circuit[0, 0].gate == CNOTGate() assert circuit[0, 0].location == (0, 1) assert circuit[0, 1].gate == CNOTGate() assert circuit[0, 1].location == (0, 1)
def test_two_qubit_2(self) -> None: circuit = Circuit(4) assert len(circuit.get_coupling_graph()) == 0 circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(CNOTGate(), [2, 3]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 3 assert (0, 1) in cgraph assert (1, 2) in cgraph assert (2, 3) in cgraph circuit.append_gate(CNOTGate(), [2, 3]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(CNOTGate(), [0, 1]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 3 assert (0, 1) in cgraph assert (1, 2) in cgraph assert (2, 3) in cgraph circuit.append_gate(CNOTGate(), [0, 2]) circuit.append_gate(CNOTGate(), [3, 0]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 5 assert (0, 1) in cgraph assert (1, 2) in cgraph assert (2, 3) in cgraph assert (0, 2) in cgraph assert (0, 3) in cgraph
def test_removing_gate2(self) -> None: circuit = Circuit(2) circuit.append_gate(U3Gate(), [0]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(U3Gate(), [0]) circuit.append_gate(U3Gate(), [1]) assert circuit.get_depth() == 3 circuit.remove(U3Gate()) assert circuit.get_depth() == 2 circuit.remove(CNOTGate()) assert circuit.get_depth() == 1 circuit.remove(U3Gate()) assert circuit.get_depth() == 1 circuit.remove(U3Gate()) assert circuit.get_depth() == 0
def test_multi_qudit_2(self, gen_random_utry_np: Any) -> None: circuit = Circuit(6, [2, 2, 2, 3, 3, 3]) assert len(circuit.get_coupling_graph()) == 0 three_qubit_gate = ConstantUnitaryGate( gen_random_utry_np(12), [2, 2, 3], ) circuit.append_gate(three_qubit_gate, [0, 1, 3]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 3 assert (0, 1) in cgraph assert (1, 3) in cgraph assert (0, 3) in cgraph circuit.append_gate(CNOTGate(), [1, 2]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 4 assert (0, 1) in cgraph assert (1, 3) in cgraph assert (0, 3) in cgraph assert (1, 2) in cgraph circuit.append_gate(CSUMGate(), [4, 5]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 5 assert (0, 1) in cgraph assert (1, 3) in cgraph assert (0, 3) in cgraph assert (1, 2) in cgraph assert (4, 5) in cgraph
def test(self) -> None: circuit = Circuit(4, [2, 2, 3, 3]) circuit.append_gate(CNOTGate(), [0, 1]) assert circuit.find_available_cycle([2, 3]) == 0 circuit.append_gate( ConstantUnitaryGate(np.identity(36), [2, 2, 3, 3]), [0, 1, 2, 3], ) circuit.append_gate(CNOTGate(), [0, 1]) assert circuit.find_available_cycle([2, 3]) == 2 circuit.append_gate( ConstantUnitaryGate(np.identity(36), [2, 2, 3, 3]), [0, 1, 2, 3], ) circuit.append_gate(CPIGate(), [2, 3]) assert circuit.find_available_cycle([0, 1]) == 4
def test_get_gate_set(self, toffoli_circuit: Circuit) -> None: gate_set = toffoli_circuit.get_gate_set() assert isinstance(gate_set, set) assert len(gate_set) == 4 assert CNOTGate() in gate_set assert HGate() in gate_set assert TdgGate() in gate_set assert TGate() in gate_set
def test_two_qubit_1(self) -> None: circuit = Circuit(2) assert len(circuit.get_coupling_graph()) == 0 circuit.append_gate(CNOTGate(), [0, 1]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 1 assert (0, 1) in cgraph circuit.append_gate(CNOTGate(), [1, 0]) cgraph = circuit.get_coupling_graph() assert len(cgraph) == 1 assert (0, 1) in cgraph circuit.remove(CNOTGate()) circuit.remove(CNOTGate()) assert len(circuit.get_coupling_graph()) == 0
def test_run(self) -> None: """Test run with a linear topology.""" # 0 1 2 3 4 ######### # 0 --o-----o--P--P-- --#-o---o-#-----#######-- # 1 --x--o--x--o----- --#-x-o-x-#######-o---#-- # 2 -----x--o--x--o-- => --#---x---#---o-#-x-o-#-- # 3 --o--P--x--P--x-- --#########-o-x-#---x-#-- # 4 --x-----------P-- ----------#-x---#######-- # ####### num_q = 5 circ = Circuit(num_q) circ.append_gate(CNOTGate(), [0, 1]) circ.append_gate(CNOTGate(), [3, 4]) circ.append_gate(CNOTGate(), [1, 2]) circ.append_gate(CNOTGate(), [0, 1]) circ.append_gate(CNOTGate(), [2, 3]) circ.append_gate(CNOTGate(), [1, 2]) circ.append_gate(CNOTGate(), [2, 3]) utry = circ.get_unitary() ScanPartitioner(3).run(circ, {}) assert len(circ) == 3 assert all(isinstance(op.gate, CircuitGate) for op in circ) placeholder_gate = TaggedGate(IdentityGate(1), '__fold_placeholder__') assert all( op.gate._circuit.count(placeholder_gate) == 0 for op in circ) # type: ignore # noqa assert circ.get_unitary() == utry for cycle_index in range(circ.get_num_cycles()): assert not circ._is_cycle_idle(cycle_index)
def test_false( self, cycle_index: int, location: Sequence[int], ) -> None: circuit = Circuit(4, [2, 2, 3, 3]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate( ConstantUnitaryGate(np.identity(36), [2, 2, 3, 3]), [0, 1, 2, 3], ) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate( ConstantUnitaryGate(np.identity(36), [2, 2, 3, 3]), [0, 1, 2, 3], ) circuit.append_gate(CPIGate(), [2, 3]) assert not circuit.is_cycle_unoccupied(cycle_index, location)
def test_adding_gate_3(self) -> None: circuit = Circuit(2) assert circuit.get_parallelism() == 0 circuit.append_gate(U3Gate(), [0]) assert circuit.get_parallelism() == 1 circuit.append_gate(U3Gate(), [1]) assert circuit.get_parallelism() == 2 circuit.append_gate(CNOTGate(), [0, 1]) assert circuit.get_parallelism() == 2
def test_return_type_2( self, valid_int: int, location: Sequence[int], ) -> None: circuit = Circuit(4, [2, 2, 3, 3]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate( ConstantUnitaryGate(np.identity(36), [2, 2, 3, 3]), [0, 1, 2, 3], ) circuit.append_gate(CNOTGate(), [0, 1]) assert isinstance( circuit.is_cycle_unoccupied( valid_int, location, ), (bool, np.bool_), )
def test_r1(self, r3_qubit_circuit: Circuit) -> None: start = r3_qubit_circuit.get_num_params() r3_qubit_circuit.append_gate(U3Gate(), [0]) assert r3_qubit_circuit.get_num_params() == start + 3 r3_qubit_circuit.insert_gate(0, U3Gate(), [1]) assert r3_qubit_circuit.get_num_params() == start + 6 r3_qubit_circuit.insert_gate(0, CNOTGate(), [0, 2]) assert r3_qubit_circuit.get_num_params() == start + 6 r3_qubit_circuit.remove(U3Gate()) assert r3_qubit_circuit.get_num_params() == start + 3
def test_invalid_value_2(self) -> None: circuit = Circuit(2) circuit.append_gate(HGate(), [0]) circuit.append_gate(CNOTGate(), [0, 1]) try: circuit.point(XGate()) except ValueError: return assert False, 'Should not have reached here.'
def test_append_gate_8(self) -> None: circuit = Circuit(4) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(CNOTGate(), [2, 3]) circuit.insert_qudit(25) circuit.append_gate(CNOTGate(), [0, 3]) assert circuit.get_size() == 5 assert len(circuit.get_radixes()) == 5 assert circuit.get_radixes().count(2) == 5 assert circuit[3, 0].gate == CNOTGate() assert circuit[3, 0].location == (0, 3) assert circuit[0, 1].gate == CNOTGate() assert circuit[0, 1].location == (0, 1) assert circuit[1, 2].gate == CNOTGate() assert circuit[1, 2].location == (1, 2) assert circuit[2, 3].gate == CNOTGate() assert circuit[2, 3].location == (2, 3)
def toffoli_circuit() -> Circuit: """Provides a standard toffoli implemention.""" circuit = Circuit(3) circuit.append_gate(HGate(), [2]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(TdgGate(), [2]) circuit.append_gate(CNOTGate(), [0, 2]) circuit.append_gate(TGate(), [2]) circuit.append_gate(CNOTGate(), [1, 2]) circuit.append_gate(TdgGate(), [2]) circuit.append_gate(CNOTGate(), [0, 2]) circuit.append_gate(TGate(), [1]) circuit.append_gate(TGate(), [2]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(HGate(), [2]) circuit.append_gate(TGate(), [0]) circuit.append_gate(TdgGate(), [1]) circuit.append_gate(CNOTGate(), [0, 1]) return circuit
def __init__( self, two_qudit_gate: Gate = CNOTGate(), single_qudit_gate_1: Gate = U3Gate(), single_qudit_gate_2: Gate | None = None, initial_layer_gate: Gate | None = None, ) -> None: """ Construct a SimpleLayerGenerator. Args: two_qudit_gate (Gate): A two-qudit gate that starts this layer generator's building block. (Default: CNOTGate()) single_qudit_gate_1 (Gate): A single-qudit gate that follows `two_qudit_gate` in the building block. (Default: U3Gate()) single_qudit_gate_2 (Gate | None): An alternate single-qudit gate to be used as the second single-qudit gate in the building block. If left as None, defaults to `single_qudit_gate_1`. (Default: None) initial_layer_gate (Gate | None): An alternate single-qudit gate that creates the initial layer. If left as None, defaults to `single_qudit_gate_1`. (Default: None) Raises: ValueError: If `two_qudit_gate`'s size is not 2, or if any of the single-qudit gates' size is not 1. ValueError: If `single_qudit_gate_1`'s radix does not match the radix of `two_qudit_gate`'s first qudit, or if `single_qudit_gate_2`'s radix does not match the radix of `two_qudit_gate`'s second qudit. """ if not isinstance(two_qudit_gate, Gate): raise TypeError( 'Expected gate for two_qudit_gate, got %s.' % type(two_qudit_gate), ) if two_qudit_gate.get_size() != 2: raise ValueError( 'Expected two-qudit gate' ', got a gate that acts on %d qudits.' % two_qudit_gate.get_size(), ) if not isinstance(single_qudit_gate_1, Gate): raise TypeError( 'Expected gate for single_qudit_gate_1, got %s.' % type(single_qudit_gate_1), ) if single_qudit_gate_1.get_size() != 1: raise ValueError( 'Expected single-qudit gate' ', got a gate that acts on %d qudits.' % single_qudit_gate_1.get_size(), ) if single_qudit_gate_2 is None: single_qudit_gate_2 = single_qudit_gate_1 if initial_layer_gate is None: initial_layer_gate = single_qudit_gate_1 if not isinstance(single_qudit_gate_2, Gate): raise TypeError( 'Expected gate for single_qudit_gate_2, got %s.' % type(single_qudit_gate_2), ) if single_qudit_gate_2.get_size() != 1: raise ValueError( 'Expected single-qudit gate' ', got a gate that acts on %d qudits.' % single_qudit_gate_2.get_size(), ) if not isinstance(initial_layer_gate, Gate): raise TypeError( 'Expected gate for initial_layer_gate, got %s.' % type(initial_layer_gate), ) if initial_layer_gate.get_size() != 1: raise ValueError( 'Expected single-qudit gate' ', got a gate that acts on %d qudits.' % initial_layer_gate.get_size(), ) two_radix_1 = two_qudit_gate.get_radixes()[0] two_radix_2 = two_qudit_gate.get_radixes()[1] if two_radix_1 != single_qudit_gate_1.get_radixes()[0]: raise ValueError( 'Radix mismatch between two_qudit_gate and single_qudit_gate_1' ': %d != %d.' % (two_radix_1, single_qudit_gate_1.get_radixes()[0]), ) if two_radix_2 != single_qudit_gate_2.get_radixes()[0]: raise ValueError( 'Radix mismatch between two_qudit_gate and single_qudit_gate_2' ': %d != %d.' % (two_radix_2, single_qudit_gate_2.get_radixes()[0]), ) self.two_qudit_gate = two_qudit_gate self.single_qudit_gate_1 = single_qudit_gate_1 self.single_qudit_gate_2 = single_qudit_gate_2 self.initial_layer_gate = initial_layer_gate
def test_one_gate_4(self) -> None: circuit = Circuit(3) circuit.append_gate(CNOTGate(), (1, 2)) ops = [op for op in CircuitIterator(circuit)] assert len(ops) == 1 assert ops[0].gate == CNOTGate() # type: ignore
@pytest.fixture def gen_invalid_utry_np() -> Callable[[int | Sequence[int]], np.ndarray]: """Provide a method to generate random invalid unitaries.""" return invalid_utry_gen # endregion # region Gates BQSKIT_GATES = [ CXGate(), CPIGate(), CSUMGate(), CNOTGate(), CYGate(), CZGate(), HGate(), IdentityGate(1), IdentityGate(2), IdentityGate(3), IdentityGate(4), ISwapGate(), # PermutationGate(), # TODO SGate(), SdgGate(), SqrtCNOTGate(), SwapGate(), SXGate(), SqrtXGate(),
def test_get_gate_set(self, simple_circuit: Circuit) -> None: gate_set = simple_circuit.get_gate_set() assert isinstance(gate_set, set) assert len(gate_set) == 2 assert XGate() in gate_set assert CNOTGate() in gate_set
def test_get_gate_set(self, swap_circuit: Circuit) -> None: gate_set = swap_circuit.get_gate_set() assert isinstance(gate_set, set) assert len(gate_set) == 1 assert CNOTGate() in gate_set
def test_example(self) -> None: circuit = Circuit(2) circuit.append_gate(HGate(), [0]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.get_operation((1, 0)).__repr__() == 'CNOTGate@(0,1)'
class TestCheckValidOperation: """This tests `circuit.check_valid_operation`.""" @pytest.mark.parametrize( ('circuit', 'op'), [ (Circuit(1), Operation(HGate(), [0])), (Circuit(1), Operation(CNOTGate(), [0, 1])), (Circuit(1), Operation(CPIGate(), [2, 3])), (Circuit(4, [2, 2, 3, 3]), Operation(HGate(), [0])), (Circuit(4, [2, 2, 3, 3]), Operation(CNOTGate(), [0, 1])), (Circuit(4, [2, 2, 3, 3]), Operation(CPIGate(), [2, 3])), ], ) def test_type_valid(self, circuit: Circuit, op: Operation) -> None: try: circuit.check_valid_operation(op) except TypeError: assert False, 'Unexpected Exception.' except BaseException: return @pytest.mark.parametrize( ('circuit', 'op'), [ (Circuit(1), 'A'), (Circuit(1), 0), (Circuit(1), np.int64(1234)), (Circuit(4, [2, 2, 3, 3]), 'A'), (Circuit(4, [2, 2, 3, 3]), 0), (Circuit(4, [2, 2, 3, 3]), np.int64(1234)), ], ) def test_type_invalid(self, circuit: Circuit, op: Operation) -> None: try: circuit.check_valid_operation(op) except TypeError: return except BaseException: assert False, 'Unexpected Exception.' def test_location_mismatch_1(self, qubit_gate: Gate) -> None: circuit = Circuit(qubit_gate.get_size()) location = list(range(qubit_gate.get_size())) location[-1] += 1 params = [0] * qubit_gate.get_num_params() op = Operation(qubit_gate, location, params) try: circuit.check_valid_operation(op) except ValueError: return except BaseException: assert False, 'Unexpected Exception' assert False def test_location_mismatch_2(self, qutrit_gate: Gate) -> None: circuit = Circuit(qutrit_gate.get_size(), qutrit_gate.get_radixes()) location = list(range(qutrit_gate.get_size())) location[-1] += 1 params = [0] * qutrit_gate.get_num_params() op = Operation(qutrit_gate, location, params) try: circuit.check_valid_operation(op) except ValueError: return except BaseException: assert False, 'Unexpected Exception' assert False def test_radix_mismatch_1(self, qubit_gate: Gate) -> None: circuit = Circuit(qubit_gate.get_size(), [3] * qubit_gate.get_size()) location = list(range(qubit_gate.get_size())) params = [0] * qubit_gate.get_num_params() op = Operation(qubit_gate, location, params) try: circuit.check_valid_operation(op) except ValueError: return except BaseException: assert False, 'Unexpected Exception' assert False def test_radix_mismatch_2(self, qutrit_gate: Gate) -> None: circuit = Circuit(qutrit_gate.get_size()) location = list(range(qutrit_gate.get_size())) params = [0] * qutrit_gate.get_num_params() op = Operation(qutrit_gate, location, params) try: circuit.check_valid_operation(op) except ValueError: return except BaseException: assert False, 'Unexpected Exception' assert False def test_valid_1(self, gate: Gate) -> None: circuit = Circuit(gate.get_size(), gate.get_radixes()) location = list(range(gate.get_size())) params = [0] * gate.get_num_params() circuit.check_valid_operation(Operation(gate, location, params)) def test_valid_2(self, gate: Gate) -> None: circuit = Circuit(gate.get_size() + 2, (2, 2) + gate.get_radixes()) location = [x + 2 for x in list(range(gate.get_size()))] params = [0] * gate.get_num_params() circuit.check_valid_operation(Operation(gate, location, params)) def test_valid_3(self) -> None: circuit = Circuit(2, [3, 2]) gate = ConstantUnitaryGate(np.identity(6), [2, 3]) circuit.check_valid_operation(Operation(gate, [1, 0]))
from bqskit.compiler.passes.partitioning.scan import ScanPartitioner from bqskit.compiler.passes.synthesis import LEAPSynthesisPass from bqskit.compiler.passes.util.variabletou3 import VariableToU3Pass from bqskit.compiler.search.generators.simple import SimpleLayerGenerator from bqskit.ir import Circuit from bqskit.ir.gates import CNOTGate from bqskit.ir.gates.parameterized.u3 import U3Gate from bqskit.ir.gates.parameterized.unitary import VariableUnitaryGate # Enable logging logging.getLogger('bqskit.compiler').setLevel(logging.DEBUG) circuit = Circuit(3) circuit.append_gate(U3Gate(), [0], [pi, pi / 2, pi / 2]) circuit.append_gate(U3Gate(), [1], [pi, pi / 2, pi / 2]) circuit.append_gate(CNOTGate(), [0, 1]) circuit.append_gate(U3Gate(), [2], [pi, pi / 2, pi / 2]) circuit.append_gate(U3Gate(), [0], [pi, pi / 2, pi / 2]) instantiate_options = { 'min_iters': 0, 'diff_tol_r': 1e-5, 'dist_tol': 1e-11, 'max_iters': 2500, } layer_generator = SimpleLayerGenerator( single_qudit_gate_1=VariableUnitaryGate(1), ) synthesizer = LEAPSynthesisPass( layer_generator=layer_generator, instantiate_options=instantiate_options, )