def test_collapse_gate(backend, nqubits, targets, results, oncircuit): original_backend = qibo.get_backend() qibo.set_backend(backend) initial_state = utils.random_numpy_state(nqubits) if oncircuit: c = Circuit(nqubits) c.add(gates.Collapse(*targets, result=results)) final_state = c(np.copy(initial_state)).numpy() else: collapse = gates.Collapse(*targets, result=results) if backend == "custom": final_state = collapse(np.copy(initial_state)).numpy() else: original_shape = initial_state.shape new_shape = nqubits * (2, ) final_state = collapse(np.copy(initial_state).reshape(new_shape)) final_state = final_state.numpy().reshape(original_shape) if isinstance(results, int): results = nqubits * [results] slicer = nqubits * [slice(None)] for t, r in zip(targets, results): slicer[t] = r slicer = tuple(slicer) initial_state = initial_state.reshape(nqubits * (2, )) target_state = np.zeros_like(initial_state) target_state[slicer] = initial_state[slicer] norm = (np.abs(target_state)**2).sum() target_state = target_state.ravel() / np.sqrt(norm) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_qaoa_execution(solver, trotter, accelerators): h = hamiltonians.TFIM(4, h=1.0, trotter=trotter) m = hamiltonians.X(4, trotter=trotter) # Trotter and RK require small p's! params = 0.01 * (1 - 2 * np.random.random(4)) state = utils.random_numpy_state(4) # set absolute test tolerance according to solver if "rk" in solver: atol = 1e-2 elif trotter: atol = 1e-5 else: atol = 0 target_state = np.copy(state) h_matrix = h.matrix.numpy() m_matrix = m.matrix.numpy() for i, p in enumerate(params): if i % 2: u = expm(-1j * p * m_matrix) else: u = expm(-1j * p * h_matrix) target_state = u @ target_state qaoa = models.QAOA(h, mixer=m, solver=solver, accelerators=accelerators) qaoa.set_parameters(params) final_state = qaoa(np.copy(state)) np.testing.assert_allclose(final_state, target_state, atol=atol)
def assert_gates_equivalent(qibo_gate, cirq_gates, nqubits, ndevices=None, atol=1e-7): """Asserts that QIBO and Cirq gates have equivalent action on a random state. Args: qibo_gate: QIBO gate. cirq_gates: List of tuples (cirq gate, target qubit IDs). nqubits: Total number of qubits in the circuit. atol: Absolute tolerance in state vector comparsion. """ initial_state = utils.random_numpy_state(nqubits) target_state = execute_cirq(cirq_gates, nqubits, np.copy(initial_state)) accelerators = None if ndevices is None else {"/GPU:0": ndevices} if isinstance(qibo_gate, native_gates.TensorflowGate) and accelerators: with pytest.raises(NotImplementedError): c = models.Circuit(nqubits, accelerators) c.add(qibo_gate) else: c = models.Circuit(nqubits, accelerators) c.add(qibo_gate) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(target_state, final_state, atol=atol)
def test_qaoa_callbacks(accelerators): from qibo import callbacks # use ``Y`` Hamiltonian so that there are no errors # in the Trotter decomposition h = hamiltonians.Y(3) energy = callbacks.Energy(h) params = 0.1 * np.random.random(4) state = utils.random_numpy_state(3) ham = hamiltonians.Y(3, trotter=True) qaoa = models.QAOA(ham, callbacks=[energy], accelerators=accelerators) qaoa.set_parameters(params) final_state = qaoa(np.copy(state)) h_matrix = h.matrix.numpy() m_matrix = qaoa.mixer.matrix.numpy() calc_energy = lambda s: (s.conj() * h_matrix.dot(s)).sum() target_state = np.copy(state) target_energy = [calc_energy(target_state)] for i, p in enumerate(params): if i % 2: u = expm(-1j * p * m_matrix) else: u = expm(-1j * p * h_matrix) target_state = u @ target_state target_energy.append(calc_energy(target_state)) np.testing.assert_allclose(energy[:], target_energy)
def test_controlled_by_unitary_action(backend): qibo.set_backend(backend) init_state = utils.random_numpy_state(2) gate = gates.RX(1, theta=0.1234).controlled_by(0) c = Circuit(2) c.add(gate) target_state = c(np.copy(init_state)).numpy() final_state = gate.unitary.numpy().dot(init_state) np.testing.assert_allclose(final_state, target_state)
def test_distributed_qft_agreement(nqubits): """Check ``_DistributedQFT`` agrees with normal ``QFT``.""" initial_state = utils.random_numpy_state(nqubits) exact_state = exact_qft(initial_state) c = models._DistributedQFT(nqubits) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, exact_state, atol=_atol)
def test_qft(backend, nqubits, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) initial_state = utils.random_numpy_state(nqubits) c = models.QFT(nqubits, accelerators=accelerators) final_state = c(np.copy(initial_state)).numpy() cirq_gates = [(cirq.QFT, list(range(nqubits)))] target_state = execute_cirq(cirq_gates, nqubits, np.copy(initial_state)) np.testing.assert_allclose(target_state, final_state, atol=1e-6) qibo.set_backend(original_backend)
def test_distributed_qft_execution(nqubits, accelerators): original_backend = qibo.get_backend() qibo.set_backend("custom") dist_c = models.QFT(nqubits, accelerators=accelerators) c = models.QFT(nqubits) initial_state = utils.random_numpy_state(nqubits) final_state = dist_c(initial_state).numpy() target_state = c(initial_state).numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def test_controlled_rotations_from_un(backend, name, params): original_backend = qibo.get_backend() qibo.set_backend(backend) init_state = utils.random_numpy_state(2) gate = getattr(gates, name)(0, 1, **params) c = Circuit(2) c.add(gate) target_state = c(np.copy(init_state)).numpy() final_state = gate.unitary.numpy().dot(init_state) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_qft_transformation_random(nqubits): """Check QFT transformation for random initial state.""" initial_state = utils.random_numpy_state(nqubits) exact_state = exact_qft(initial_state) c_init = models.Circuit(nqubits) c_init.add(gates.Flatten(initial_state)) c = c_init + models.QFT(nqubits) final_state = c.execute().numpy() np.testing.assert_allclose(final_state, exact_state, atol=_atol)
def test_controlled_by_unitary_action(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) init_state = utils.random_numpy_state(2) matrix = utils.random_numpy_complex((2, 2)) gate = gates.Unitary(matrix, 1).controlled_by(0) c = Circuit(2) c.add(gate) target_state = c(np.copy(init_state)).numpy() final_state = gate.unitary.numpy().dot(init_state) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_dagger_controlled_by(backend, gate, params): original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(4) gate = getattr(gates, gate)(3, **params).controlled_by(0, 1, 2) c.add((gate, gate.dagger())) initial_state = utils.random_numpy_state(4) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, initial_state) qibo.set_backend(original_backend)
def test_dagger_one_qubit(backend, gate, params): original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(1) gate = getattr(gates, gate)(0, **params) c.add((gate, gate.dagger())) initial_state = utils.random_numpy_state(1) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, initial_state) qibo.set_backend(original_backend)
def test_variational_layer_dagger(backend, nqubits): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random((2, nqubits)) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta[0], theta[1]) c = Circuit(nqubits) c.add((gate, gate.dagger())) initial_state = utils.random_numpy_state(nqubits) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, initial_state) qibo.set_backend(original_backend)
def test_unitary_controlled_by_dagger(backend): from scipy.linalg import expm original_backend = qibo.get_backend() qibo.set_backend(backend) matrix = np.random.random((2, 2)) matrix = expm(1j * (matrix + matrix.T)) gate = gates.Unitary(matrix, 0).controlled_by(1, 2, 3, 4) c = Circuit(5) c.add((gate, gate.dagger())) initial_state = utils.random_numpy_state(5) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, initial_state) qibo.set_backend(original_backend)
def test_density_matrix_circuit_initial_state(backend): """Check that circuit transforms state vector initial state to density matrix.""" import tensorflow as tf original_backend = qibo.get_backend() qibo.set_backend(backend) initial_psi = utils.random_numpy_state(3) c = models.Circuit(3, density_matrix=True) final_rho = c(np.copy(initial_psi)) target_rho = np.outer(initial_psi, initial_psi.conj()) np.testing.assert_allclose(final_rho, target_rho) initial_psi = tf.cast(initial_psi, dtype=final_rho.dtype) final_rho = c(initial_psi) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_user_initialization(nqubits): import itertools target_state = utils.random_numpy_state(nqubits) devices = {"/GPU:0": 2, "/GPU:1": 2} c = models.DistributedCircuit(nqubits, devices) c.queues.qubits = distutils.DistributedQubits(range(c.nglobal), c.nqubits) state = c.get_initial_state(target_state) np.testing.assert_allclose(state.numpy(), target_state) target_state = target_state.reshape(nqubits * (2, )) for i, s in enumerate(itertools.product([0, 1], repeat=c.nglobal)): piece = state.pieces[i].numpy() target_piece = target_state[s] np.testing.assert_allclose(target_piece.ravel(), piece)
def test_collapse_gate(backend, nqubits, targets, results): original_backend = qibo.get_backend() qibo.set_backend(backend) initial_psi = utils.random_numpy_state(nqubits) initial_rho = np.outer(initial_psi, initial_psi.conj()) c = models.Circuit(nqubits, density_matrix=True) c.add(gates.Collapse(*targets, result=results)) final_rho = c(np.copy(initial_rho)) c = models.Circuit(nqubits) c.add(gates.Collapse(*targets, result=results)) target_psi = c(np.copy(initial_psi)).numpy() target_rho = np.outer(target_psi, target_psi.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_x_decomposition_execution(target, controls, free, use_toffolis): """Check that applying the decomposition is equivalent to applying the multi-control gate.""" gate = gates.X(target).controlled_by(*controls) nqubits = max((target, ) + controls + free) + 1 init_state = utils.random_numpy_state(nqubits) targetc = Circuit(nqubits) targetc.add(gate) target_state = targetc(np.copy(init_state)).numpy() c = Circuit(nqubits) c.add(gate.decompose(*free, use_toffolis=use_toffolis)) final_state = c(np.copy(init_state)).numpy() np.testing.assert_allclose(final_state, target_state, atol=_ATOL)
def test_collapse_gate_distributed(accelerators, nqubits, targets): initial_state = utils.random_numpy_state(nqubits) c = Circuit(nqubits, accelerators) c.add(gates.Collapse(*targets)) final_state = c(np.copy(initial_state)).numpy() slicer = nqubits * [slice(None)] for t in targets: slicer[t] = 0 slicer = tuple(slicer) initial_state = initial_state.reshape(nqubits * (2, )) target_state = np.zeros_like(initial_state) target_state[slicer] = initial_state[slicer] norm = (np.abs(target_state)**2).sum() target_state = target_state.ravel() / np.sqrt(norm) np.testing.assert_allclose(final_state, target_state)
def test_simple_execution_global(ndevices): original_backend = qibo.get_backend() qibo.set_backend("custom") devices = {"/GPU:0": ndevices // 2, "/GPU:1": ndevices // 2} dist_c = models.DistributedCircuit(6, devices) dist_c.add((gates.H(i) for i in range(6))) c = models.Circuit(6) c.add((gates.H(i) for i in range(6))) 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_toffoli_gate(backend): """Check applying Toffoli to three qubit density matrix.""" original_backend = qibo.get_backend() qibo.set_backend(backend) initial_psi = utils.random_numpy_state(3) initial_rho = np.outer(initial_psi, initial_psi.conj()) circuit = models.Circuit(3, density_matrix=True) circuit.add(gates.TOFFOLI(0, 2, 1)) final_rho = circuit(np.copy(initial_rho)).numpy() circuit = models.Circuit(3) circuit.add(gates.TOFFOLI(0, 2, 1)) target_psi = circuit(np.copy(initial_psi)).numpy() target_rho = np.outer(target_psi, target_psi.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_one_qubit_gates(backend, gatename, gatekwargs): """Check applying one qubit gates to one qubit density matrix.""" original_backend = qibo.get_backend() qibo.set_backend(backend) initial_psi = utils.random_numpy_state(1) initial_rho = np.outer(initial_psi, initial_psi.conj()) circuit = models.Circuit(1, density_matrix=True) circuit.add(getattr(gates, gatename)(0, **gatekwargs)) final_rho = circuit(np.copy(initial_rho)).numpy() circuit = models.Circuit(1) circuit.add(getattr(gates, gatename)(0, **gatekwargs)) target_psi = circuit(np.copy(initial_psi)).numpy() target_rho = np.outer(target_psi, target_psi.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_u2(backend): """Check U2 gate on random state.""" original_backend = qibo.get_backend() qibo.set_backend(backend) phi = 0.1234 lam = 0.4321 initial_state = utils.random_numpy_state(1) c = Circuit(1) c.add(gates.U2(0, phi, lam)) final_state = c(np.copy(initial_state)) matrix = np.array([[np.exp(-1j * (phi + lam) / 2), -np.exp(-1j * (phi - lam) / 2)], [np.exp(1j * (phi - lam) / 2), np.exp(1j * (phi + lam) / 2)]]) target_state = matrix.dot(initial_state) / np.sqrt(2) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_controlled_execution(ndevices): original_backend = qibo.get_backend() qibo.set_backend("custom") devices = {"/GPU:0": ndevices} dist_c = models.DistributedCircuit(4, devices) dist_c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) dist_c.add(gates.CNOT(0, 2)) c = models.Circuit(4) c.add((gates.H(i) for i in range(dist_c.nglobal, 4))) c.add(gates.CNOT(0, 2)) 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_controlled_by_random(backend, nqubits): """Check controlled_by method on gate.""" original_backend = qibo.get_backend() qibo.set_backend(backend) initial_psi = utils.random_numpy_state(nqubits) initial_rho = np.outer(initial_psi, initial_psi.conj()) c = models.Circuit(nqubits, density_matrix=True) c.add(gates.RX(1, theta=0.789).controlled_by(2)) c.add(gates.fSim(0, 2, theta=0.123, phi=0.321).controlled_by(1, 3)) final_rho = c(np.copy(initial_rho)).numpy() c = models.Circuit(nqubits) c.add(gates.RX(1, theta=0.789).controlled_by(2)) c.add(gates.fSim(0, 2, theta=0.123, phi=0.321).controlled_by(1, 3)) target_psi = c(np.copy(initial_psi)).numpy() target_rho = np.outer(target_psi, target_psi.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_cz(backend): """Check CZ gate is working properly on random state.""" original_backend = qibo.get_backend() qibo.set_backend(backend) init_state = utils.random_numpy_state(2) matrix = np.eye(4) matrix[3, 3] = -1 target_state = matrix.dot(init_state) c = Circuit(2) c.add(gates.CZ(0, 1)) final_state = c.execute(np.copy(init_state)).numpy() np.testing.assert_allclose(final_state, target_state) c = Circuit(2) c.add(gates.Z(1).controlled_by(0)) final_state = c.execute(np.copy(init_state)).numpy() assert c.queue[0].name == "cz" np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
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_generalizedfsim_dagger(backend, tfmatrix): from scipy.linalg import expm original_backend = qibo.get_backend() qibo.set_backend(backend) phi = 0.2 matrix = np.random.random((2, 2)) matrix = expm(1j * (matrix + matrix.T)) if tfmatrix: import tensorflow as tf from qibo.config import DTYPES matrix = tf.cast(matrix, dtype=DTYPES.get('DTYPECPX')) gate = gates.GeneralizedfSim(0, 1, matrix, phi) c = Circuit(2) c.add((gate, gate.dagger())) initial_state = utils.random_numpy_state(2) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, initial_state) qibo.set_backend(original_backend)
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)