def test_controlled_by_swap(backend): """Check controlled SWAP using controlled by for ``nqubits=4``.""" original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(4) c.add(gates.RX(2, theta=0.1234)) c.add(gates.RY(3, theta=0.4321)) c.add(gates.SWAP(2, 3).controlled_by(0)) final_state = c.execute().numpy() c = Circuit(4) c.add(gates.RX(2, theta=0.1234)) c.add(gates.RY(3, theta=0.4321)) target_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) c = Circuit(4) c.add(gates.X(0)) c.add(gates.RX(2, theta=0.1234)) c.add(gates.RY(3, theta=0.4321)) c.add(gates.SWAP(2, 3).controlled_by(0)) c.add(gates.X(0)) final_state = c.execute().numpy() c = Circuit(4) c.add(gates.RX(2, theta=0.1234)) c.add(gates.RY(3, theta=0.4321)) c.add(gates.SWAP(2, 3)) target_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_doubly_controlled_by_swap(backend, accelerators): """Check controlled SWAP using controlled by two qubits.""" original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(4, accelerators) c.add(gates.X(0)) c.add(gates.RX(1, theta=0.1234)) c.add(gates.RY(2, theta=0.4321)) c.add(gates.SWAP(1, 2).controlled_by(0, 3)) c.add(gates.X(0)) final_state = c.execute().numpy() c = Circuit(4) c.add(gates.RX(1, theta=0.1234)) c.add(gates.RY(2, theta=0.4321)) target_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) c = Circuit(4, accelerators) c.add(gates.X(0)) c.add(gates.X(3)) c.add(gates.RX(1, theta=0.1234)) c.add(gates.RY(2, theta=0.4321)) c.add(gates.SWAP(1, 2).controlled_by(0, 3)) c.add(gates.X(0)) c.add(gates.X(3)) final_state = c.execute().numpy() c = Circuit(4) c.add(gates.RX(1, theta=0.1234)) c.add(gates.RY(2, theta=0.4321)) c.add(gates.SWAP(1, 2)) target_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_multiple_swap(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) gatelist = [gates.X(0), gates.X(2), gates.SWAP(0, 1), gates.SWAP(2, 3)] final_state = apply_gates(gatelist, nqubits=4) gatelist = [gates.X(1), gates.X(3)] target_state = apply_gates(gatelist, nqubits=4) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_two_qubit_gate_multiplication(backend): theta, phi = 0.1234, 0.5432 gate1 = gates.fSim(0, 1, theta=theta, phi=phi) gate2 = gates.SWAP(0, 1) final_gate = gate1 @ gate2 target_matrix = ( np.array([[1, 0, 0, 0], [0, np.cos(theta), -1j * np.sin(theta), 0], [0, -1j * np.sin(theta), np.cos(theta), 0], [0, 0, 0, np.exp(-1j * phi)]]) @ np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])) K.assert_allclose(final_gate.matrix, target_matrix) # Check that error is raised when target qubits do not agree with pytest.raises(NotImplementedError): final_gate = gate1 @ gates.SWAP(0, 2)
def test_distributed_circuit_execution_with_swap(backend, accelerators): dist_c = DistributedCircuit(6, accelerators) dist_c.add((gates.H(i) for i in range(6))) dist_c.add((gates.SWAP(i, i + 1) for i in range(5))) dist_c.global_qubits = [0, 1] c = Circuit(6) c.add((gates.H(i) for i in range(6))) c.add((gates.SWAP(i, i + 1) for i in range(5))) initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) np.testing.assert_allclose(target_state, final_state)
def test_distributed_circuit_execution_pretransformed(backend, accelerators): dist_c = DistributedCircuit(4, accelerators) dist_c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) dist_c.add(gates.SWAP(0, 2)) dist_c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) c = Circuit(4) c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) c.add(gates.SWAP(0, 2)) c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) np.testing.assert_allclose(target_state, final_state)
def _DistributedQFT(nqubits, accelerators=None): """QFT with the order of gates optimized for reduced multi-device communication.""" from qibo import gates circuit = Circuit(nqubits, accelerators) icrit = nqubits // 2 + nqubits % 2 if accelerators is not None: circuit.global_qubits = range(circuit.nlocal, nqubits) # pylint: disable=E1101 if icrit < circuit.nglobal: # pylint: disable=E1101 raise_error(NotImplementedError, "Cannot implement QFT for {} qubits " "using {} global qubits." "".format(nqubits, circuit.nglobal)) # pylint: disable=E1101 for i1 in range(nqubits): if i1 < icrit: i1eff = i1 else: i1eff = nqubits - i1 - 1 circuit.add(gates.SWAP(i1, i1eff)) circuit.add(gates.H(i1eff)) for i2 in range(i1 + 1, nqubits): theta = math.pi / 2 ** (i2 - i1) circuit.add(gates.CU1(i2, i1eff, theta)) return circuit
def _DistributedQFT(nqubits: int, accelerators: Optional[Dict[str, int]] = None, memory_device: str = "/CPU:0") -> DistributedCircuit: """QFT with the order of gates optimized for reduced multi-device communication.""" import numpy as np from qibo import gates circuit = Circuit(nqubits, accelerators, memory_device) icrit = nqubits // 2 + nqubits % 2 if accelerators is not None: circuit.global_qubits = range(circuit.nlocal, nqubits) if icrit < circuit.nglobal: raise_error( NotImplementedError, "Cannot implement QFT for {} qubits " "using {} global qubits." "".format(nqubits, circuit.nglobal)) for i1 in range(nqubits): if i1 < icrit: i1eff = i1 else: i1eff = nqubits - i1 - 1 circuit.add(gates.SWAP(i1, i1eff)) circuit.add(gates.H(i1eff)) for i2 in range(i1 + 1, nqubits): theta = np.pi / 2**(i2 - i1) circuit.add(gates.CU1(i2, i1eff, theta)) return circuit
def test_controlled_swap(backend, applyx, free_qubit): f = int(free_qubit) c = Circuit(3 + f) if applyx: c.add(gates.X(0)) c.add(gates.RX(1 + f, theta=0.1234)) c.add(gates.RY(2 + f, theta=0.4321)) c.add(gates.SWAP(1 + f, 2 + f).controlled_by(0)) final_state = c.execute() c = Circuit(3 + f) c.add(gates.RX(1 + f, theta=0.1234)) c.add(gates.RY(2 + f, theta=0.4321)) if applyx: c.add(gates.X(0)) c.add(gates.SWAP(1 + f, 2 + f)) target_state = c.execute() K.assert_allclose(final_state, target_state)
def test_swap(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) final_state = apply_gates([gates.X(1), gates.SWAP(0, 1)], nqubits=2) target_state = np.zeros_like(final_state) target_state[2] = 1.0 np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_distributed_circuit_add_gate(backend): # Attempt to add gate so that available global qubits are not enough c = DistributedCircuit(2, {"/GPU:0": 2}) with pytest.raises(ValueError): c.add(gates.SWAP(0, 1)) # Attempt adding noise channel with pytest.raises(NotImplementedError): c.add(gates.PauliNoiseChannel(0, px=0.1, pz=0.1))
def test_multiple_swap(backend): """Check SWAP gate is working properly when called multiple times.""" original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(4) c.add(gates.X(0)) c.add(gates.X(2)) c.add(gates.SWAP(0, 1)) c.add(gates.SWAP(2, 3)) final_state = c.execute().numpy() c = Circuit(4) c.add(gates.X(1)) c.add(gates.X(3)) target_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_controlled_swap_double(backend, applyx): c = Circuit(4) c.add(gates.X(0)) if applyx: c.add(gates.X(3)) c.add(gates.RX(1, theta=0.1234)) c.add(gates.RY(2, theta=0.4321)) c.add(gates.SWAP(1, 2).controlled_by(0, 3)) c.add(gates.X(0)) final_state = c.execute() c = Circuit(4) c.add(gates.RX(1, theta=0.1234)) c.add(gates.RY(2, theta=0.4321)) if applyx: c.add(gates.X(3)) c.add(gates.SWAP(1, 2)) target_state = c.execute() K.assert_allclose(final_state, target_state)
def test_controlled_with_effect(backend): """Check controlled_by SWAP that should be applied.""" from qibo.models import Circuit initial_rho = np.zeros((16, 16)) initial_rho[0, 0] = 1 c = Circuit(4, density_matrix=True) c.add(gates.X(0)) c.add(gates.X(2)) c.add(gates.SWAP(1, 3).controlled_by(0, 2)) final_rho = c(np.copy(initial_rho)).numpy() c = Circuit(4, density_matrix=True) c.add(gates.X(0)) c.add(gates.X(2)) c.add(gates.SWAP(1, 3)) target_rho = c(np.copy(initial_rho)).numpy() K.assert_allclose(final_rho, target_rho)
def test_fuse_circuit_two_qubit_gates(backend): """Check circuit fusion in circuit with two-qubit gates only.""" c = Circuit(2) c.add(gates.CNOT(0, 1)) c.add(gates.RX(0, theta=0.1234).controlled_by(1)) c.add(gates.SWAP(0, 1)) c.add(gates.fSim(1, 0, theta=0.1234, phi=0.324)) c.add(gates.RY(1, theta=0.1234).controlled_by(0)) fused_c = c.fuse() K.assert_allclose(fused_c(), c())
def test_execution_with_global_swap(): original_backend = qibo.get_backend() qibo.set_backend("custom") devices = {"/GPU:0": 2, "/GPU:1": 1, "/GPU:2": 1} dist_c = models.DistributedCircuit(6, devices) dist_c.add((gates.H(i) for i in range(6))) dist_c.add((gates.SWAP(i, i + 1) for i in range(5))) dist_c.global_qubits = [0, 1] c = models.Circuit(6) c.add((gates.H(i) for i in range(6))) c.add((gates.SWAP(i, i + 1) for i in range(5))) initial_state = utils.random_numpy_state(c.nqubits) final_state = dist_c(np.copy(initial_state)).numpy() target_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def test_execution_pretransformed_circuit(ndevices): original_backend = qibo.get_backend() qibo.set_backend("custom") devices = {"/GPU:0": ndevices // 2, "/GPU:1": ndevices // 2} dist_c = models.DistributedCircuit(4, devices) dist_c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) dist_c.add(gates.SWAP(0, 2)) dist_c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) c = models.Circuit(4) c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) c.add(gates.SWAP(0, 2)) c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) initial_state = utils.random_numpy_state(c.nqubits) final_state = dist_c(np.copy(initial_state)).numpy() target_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def QFT(nqubits: int, with_swaps: bool = True, accelerators: Optional[Dict[str, int]] = None, memory_device: str = "/CPU:0") -> Circuit: """Creates a circuit that implements the Quantum Fourier Transform. Args: nqubits (int): Number of qubits in the circuit. with_swaps (bool): Use SWAP gates at the end of the circuit so that the qubit order in the final state is the same as the initial state. accelerators (dict): Accelerator device dictionary in order to use a distributed circuit If ``None`` a simple (non-distributed) circuit will be used. memory_device (str): Device to use for memory in case a distributed circuit is used. Ignored for non-distributed circuits. Returns: A qibo.models.Circuit that implements the Quantum Fourier Transform. Example: :: import numpy as np from qibo.models import QFT nqubits = 6 c = QFT(nqubits) # Random normalized initial state vector init_state = np.random.random(2 ** nqubits) + 1j * np.random.random(2 ** nqubits) init_state = init_state / np.sqrt((np.abs(init_state)**2).sum()) # Execute the circuit final_state = c(init_state) """ if accelerators is not None: if not with_swaps: raise_error(NotImplementedError, "Distributed QFT is only implemented " "with SWAPs.") return _DistributedQFT(nqubits, accelerators, memory_device) import numpy as np from qibo import gates circuit = Circuit(nqubits) for i1 in range(nqubits): circuit.add(gates.H(i1)) for i2 in range(i1 + 1, nqubits): theta = np.pi / 2**(i2 - i1) circuit.add(gates.CU1(i2, i1, theta)) if with_swaps: for i in range(nqubits // 2): circuit.add(gates.SWAP(i, nqubits - i - 1)) return circuit
def test_distributed_circuit_execution_controlled_by_gates( backend, accelerators): dist_c = DistributedCircuit(6, accelerators) dist_c.add([gates.H(0), gates.H(2), gates.H(3)]) dist_c.add(gates.CNOT(4, 5)) dist_c.add(gates.Z(1).controlled_by(0)) dist_c.add(gates.SWAP(2, 3)) dist_c.add([gates.X(2), gates.X(3), gates.X(4)]) c = Circuit(6) c.add([gates.H(0), gates.H(2), gates.H(3)]) c.add(gates.CNOT(4, 5)) c.add(gates.Z(1).controlled_by(0)) c.add(gates.SWAP(2, 3)) c.add([gates.X(2), gates.X(3), gates.X(4)]) initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) np.testing.assert_allclose(target_state, final_state)
def test_controlled_execution_large(ndevices): devices = {"/GPU:0": ndevices // 2, "/GPU:1": ndevices // 2} dist_c = models.DistributedCircuit(6, devices) dist_c.add([gates.H(0), gates.H(2), gates.H(3)]) dist_c.add(gates.CNOT(4, 5)) dist_c.add(gates.Z(1).controlled_by(0)) dist_c.add(gates.SWAP(2, 3)) dist_c.add([gates.X(2), gates.X(3), gates.X(4)]) c = models.Circuit(6) c.add([gates.H(0), gates.H(2), gates.H(3)]) c.add(gates.CNOT(4, 5)) c.add(gates.Z(1).controlled_by(0)) c.add(gates.SWAP(2, 3)) c.add([gates.X(2), gates.X(3), gates.X(4)]) initial_state = utils.random_numpy_state(c.nqubits) final_state = dist_c(np.copy(initial_state)).numpy() target_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(target_state, final_state)
def test_swap(backend): """Check SWAP gate is working properly on |01>.""" original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(2) c.add(gates.X(1)) c.add(gates.SWAP(0, 1)) final_state = c.execute().numpy() target_state = np.zeros_like(final_state) target_state[2] = 1.0 np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_two_qubit_gate_multiplication(backend): """Check gate multiplication for two-qubit gates.""" import qibo original_backend = qibo.get_backend() qibo.set_backend(backend) theta, phi = 0.1234, 0.5432 gate1 = gates.fSim(0, 1, theta=theta, phi=phi) gate2 = gates.SWAP(0, 1) final_gate = gate1 @ gate2 target_matrix = ( np.array([[1, 0, 0, 0], [0, np.cos(theta), -1j * np.sin(theta), 0], [0, -1j * np.sin(theta), np.cos(theta), 0], [0, 0, 0, np.exp(-1j * phi)]]) @ np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])) np.testing.assert_allclose(final_gate.unitary, target_matrix) # Check that error is raised when target qubits do not agree with pytest.raises(NotImplementedError): final_gate = gate1 @ gates.SWAP(0, 2) # Reset backend for other tests qibo.set_backend(original_backend)
def test_construct_unitary(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) target_matrix = np.array([[1, 1], [1, -1]]) / np.sqrt(2) np.testing.assert_allclose(gates.H(0).unitary, target_matrix) target_matrix = np.array([[0, 1], [1, 0]]) np.testing.assert_allclose(gates.X(0).unitary, target_matrix) target_matrix = np.array([[0, -1j], [1j, 0]]) np.testing.assert_allclose(gates.Y(0).unitary, target_matrix) target_matrix = np.array([[1, 0], [0, -1]]) np.testing.assert_allclose(gates.Z(1).unitary, target_matrix) target_matrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) np.testing.assert_allclose(gates.CNOT(0, 1).unitary, target_matrix) target_matrix = np.diag([1, 1, 1, -1]) np.testing.assert_allclose(gates.CZ(1, 3).unitary, target_matrix) target_matrix = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) np.testing.assert_allclose(gates.SWAP(2, 4).unitary, target_matrix) target_matrix = np.array([[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 1, 0]]) np.testing.assert_allclose(gates.TOFFOLI(1, 2, 3).unitary, target_matrix) theta = 0.1234 target_matrix = np.array([[np.cos(theta / 2.0), -1j * np.sin(theta / 2.0)], [-1j * np.sin(theta / 2.0), np.cos(theta / 2.0)]]) np.testing.assert_allclose(gates.RX(0, theta).unitary, target_matrix) target_matrix = np.array([[np.cos(theta / 2.0), -np.sin(theta / 2.0)], [np.sin(theta / 2.0), np.cos(theta / 2.0)]]) np.testing.assert_allclose(gates.RY(0, theta).unitary, target_matrix) target_matrix = np.diag( [np.exp(-1j * theta / 2.0), np.exp(1j * theta / 2.0)]) np.testing.assert_allclose(gates.RZ(0, theta).unitary, target_matrix) target_matrix = np.diag([1, np.exp(1j * theta)]) np.testing.assert_allclose(gates.U1(0, theta).unitary, target_matrix) target_matrix = np.diag([1, 1, 1, np.exp(1j * theta)]) np.testing.assert_allclose(gates.CU1(0, 1, theta).unitary, target_matrix) from qibo import matrices target_matrix = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) np.testing.assert_allclose(matrices.SWAP, target_matrix) qibo.set_backend(original_backend)
def test_create_queue_errors(backend): c = DistributedCircuit(4, {"/GPU:0": 2}) c.add(gates.H(0)) c.add(gates.H(1)) c.queues.qubits = DistributedQubits([0], c.nqubits) with pytest.raises(ValueError): c.queues.create(c.queue) c = DistributedCircuit(4, {"/GPU:0": 4}) c.add(gates.SWAP(0, 1)) c.queues.qubits = DistributedQubits([0, 1], c.nqubits) with pytest.raises(ValueError): c.queues.create(c.queue)
def test_unsupported_gates_errors(): c = models.Circuit(4, {"/GPU:0": 2}) c.add(gates.H(0)) c.add(gates.H(1)) c.queues.qubits = distutils.DistributedQubits([0], c.nqubits) with pytest.raises(ValueError): c.queues.create(c.queue) c = models.Circuit(4, {"/GPU:0": 4}) c.add(gates.SWAP(0, 1)) c.queues.qubits = distutils.DistributedQubits([0, 1], c.nqubits) with pytest.raises(ValueError): c.queues.create(c.queue)
def test_fuse_circuit_three_qubit_gate(backend, max_qubits): """Check circuit fusion in circuit with three-qubit gate.""" c = Circuit(4) c.add((gates.H(i) for i in range(4))) c.add(gates.CZ(0, 1)) c.add(gates.CZ(2, 3)) c.add(gates.TOFFOLI(0, 1, 2)) c.add(gates.SWAP(1, 2)) c.add((gates.H(i) for i in range(4))) c.add(gates.CNOT(0, 1)) c.add(gates.CZ(2, 3)) fused_c = c.fuse(max_qubits=max_qubits) K.assert_allclose(fused_c(), c(), atol=1e-12)
def test_controlled_with_effect(backend): """Check controlled_by SWAP that should be applied.""" original_backend = qibo.get_backend() qibo.set_backend(backend) psi = np.zeros(2**4) psi[0] = 1 initial_rho = np.outer(psi, psi.conj()) c = models.Circuit(4, density_matrix=True) c.add(gates.X(0)) c.add(gates.X(2)) c.add(gates.SWAP(1, 3).controlled_by(0, 2)) final_rho = c(np.copy(initial_rho)).numpy() c = models.Circuit(4, density_matrix=True) c.add(gates.X(0)) c.add(gates.X(2)) c.add(gates.SWAP(1, 3)) target_rho = c(np.copy(initial_rho)).numpy() np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_fuse_circuit_two_qubit_only(): """Check gate fusion in circuit with two-qubit gates only.""" c = Circuit(2) c.add(gates.CNOT(0, 1)) c.add(gates.RX(0, theta=0.1234).controlled_by(1)) c.add(gates.SWAP(0, 1)) c.add(gates.fSim(1, 0, theta=0.1234, phi=0.324)) c.add(gates.RY(1, theta=0.1234).controlled_by(0)) fused_c = c.fuse() target_state = c() final_state = fused_c() np.testing.assert_allclose(final_state, target_state)
def i_qft(q): """(Inverse) Quantum Fourier Transform on a quantum register. Args: q (list): quantum register where the QFT is applied. Returns: generator with the required quantum gates applied on the quantum circuit. """ for i in range(len(q) // 2): yield gates.SWAP(i, len(q) - i - 1) for i1 in reversed(range(len(q))): for i2 in reversed(range(i1 + 1, len(q))): theta = np.pi / 2 ** (i2 - i1) yield gates.CU1(q[i2], q[i1], -theta) yield gates.H(q[i1])
def test_two_qubit_gates_controlled_by(backend, nqubits, ndevices): """Check ``SWAP`` and ``fSim`` gates controlled on arbitrary number of qubits.""" all_qubits = np.arange(nqubits) for _ in range(5): activeq = random_active_qubits(nqubits, nmin=2) qibo_gate = gates.SWAP(*activeq[-2:]).controlled_by(*activeq[:-2]) cirq_gate = [(cirq.SWAP.controlled(len(activeq) - 2), activeq)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits, ndevices) theta = np.random.random() phi = np.random.random() qibo_gate = gates.fSim(*activeq[-2:], theta, phi).controlled_by(*activeq[:-2]) cirq_gate = [(cirq.FSimGate(theta, phi).controlled(len(activeq) - 2), activeq)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits, ndevices)