def test_circuit_fuse_variational_layer(backend, nqubits, nlayers, accelerators): """Check fused variational layer execution.""" import qibo if accelerators: backend = "custom" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random((2 * nlayers * nqubits, )) theta_iter = iter(theta) c = Circuit(nqubits, accelerators=accelerators) for _ in range(nlayers): c.add((gates.RY(i, next(theta_iter)) for i in range(nqubits))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) c.add((gates.RY(i, next(theta_iter)) for i in range(nqubits))) c.add((gates.CZ(i, i + 1) for i in range(1, nqubits - 2, 2))) c.add(gates.CZ(0, nqubits - 1)) fused_c = c.fuse() target_state = c() final_state = fused_c() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_fuse_with_callback(accelerators): """Check entropy calculation in fused circuit.""" from qibo import callbacks entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add(gates.H(0)) c.add(gates.X(1)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) fused_c = c.fuse() target_state = c() final_state = fused_c() np.testing.assert_allclose(final_state, target_state) target_entropy = [0.0, 1.0, 0.0, 1.0] np.testing.assert_allclose(entropy[:], target_entropy, atol=1e-7)
def test_measurement_collapse_distributed(backend, accelerators, nqubits, targets): initial_state = random_state(nqubits) c = Circuit(nqubits, accelerators) output = c.add(gates.M(*targets, collapse=True)) result = c(np.copy(initial_state)) slicer = nqubits * [slice(None)] for t, r in zip(targets, output.samples()[0]): slicer[t] = int(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) K.assert_allclose(result.state(), target_state)
def test_rx_parameter_setter(backend): """Check that the parameter setter of RX gate is working properly.""" def exact_state(theta): phase = np.exp(1j * theta / 2.0) gate = np.array([[phase.real, -1j * phase.imag], [-1j * phase.imag, phase.real]]) return gate.dot(np.ones(2)) / np.sqrt(2) original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(1) c.add(gates.H(0)) c.add(gates.RX(0, theta=theta)) final_state = c().numpy() target_state = exact_state(theta) np.testing.assert_allclose(final_state, target_state) theta = 0.4321 c.queue[-1].parameters = theta final_state = c().numpy() target_state = exact_state(theta) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_reset_channel_repeated(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) initial_state = random_state(5) c = Circuit(5) c.add(gates.ResetChannel(2, p0=0.3, p1=0.3, seed=123)) final_state = c(np.copy(initial_state), nshots=30) np.random.seed(123) target_state = [] collapse = gates.M(2, collapse=True) collapse.nqubits = 5 xgate = gates.X(2) for _ in range(30): state = np.copy(initial_state) if np.random.random() < 0.3: state = K.state_vector_collapse(collapse, state, [0]) if np.random.random() < 0.3: state = K.state_vector_collapse(collapse, state, [0]) state = xgate(state) target_state.append(np.copy(state)) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_controlled_by_fsim(backend, accelerators): """Check ``controlled_by`` for fSim gate.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 phi = 0.4321 c = Circuit(6, accelerators) c.add((gates.H(i) for i in range(6))) c.add(gates.fSim(5, 3, theta, phi).controlled_by(0, 2, 1)) final_state = c.execute().numpy() target_state = np.ones_like(final_state) / np.sqrt(2 ** 6) rotation = np.array([[np.cos(theta), -1j * np.sin(theta)], [-1j * np.sin(theta), np.cos(theta)]]) matrix = np.eye(4, dtype=target_state.dtype) matrix[1:3, 1:3] = rotation matrix[3, 3] = np.exp(-1j * phi) ids = [56, 57, 60, 61] target_state[ids] = matrix.dot(target_state[ids]) ids = [58, 59, 62, 63] target_state[ids] = matrix.dot(target_state[ids]) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_controlled_by_random(backend, nqubits): """Check controlled_by method on gate.""" from qibo.models import Circuit from qibo.tests.utils import random_state initial_psi = random_state(nqubits) initial_rho = np.outer(initial_psi, initial_psi.conj()) c = 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)) c = 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)) target_rho = np.outer(target_psi, np.conj(target_psi)) K.assert_allclose(final_rho, target_rho)
def test_entropy_in_distributed_circuit(backend, accelerators, gateconf, target_entropy): """Check that various entropy configurations work in distributed circuit.""" target_c = Circuit(4) target_c.add([gates.H(0), gates.CNOT(0, 1)]) target_state = target_c() entropy = callbacks.EntanglementEntropy([0]) c = Circuit(4, accelerators) for gate in gateconf: if gate == "H": c.add(gates.H(0)) elif gate == "CNOT": c.add(gates.CNOT(0, 1)) elif gate == "entropy": c.add(gates.CallbackGate(entropy)) final_state = c() K.assert_allclose(final_state, target_state) K.assert_allclose(entropy[:], target_entropy, atol=_atol)
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_controlled_u1(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(3) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.X(2)) c.add(gates.U1(2, theta).controlled_by(0, 1)) c.add(gates.X(0)) c.add(gates.X(1)) final_state = c.execute() target_state = np.zeros_like(final_state) target_state[1] = np.exp(1j * theta) np.testing.assert_allclose(final_state, target_state) gate = gates.U1(0, theta).controlled_by(1) assert gate.__class__.__name__ == "CU1" qibo.set_backend(original_backend)
def test_circuit_unitary(backend): from qibo import matrices c = Circuit(2) c.add(gates.H(0)) c.add(gates.H(1)) c.add(gates.CNOT(0, 1)) c.add(gates.X(0)) c.add(gates.Y(1)) h = np.kron(matrices.H, matrices.H) target_matrix = np.kron(matrices.X, matrices.Y) @ matrices.CNOT @ h K.assert_allclose(c.unitary(), target_matrix)
def test_doubly_controlled_by_rx(backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(3, accelerators) c.add(gates.RX(2, theta)) target_state = c.execute().numpy() c = Circuit(3) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.RX(2, theta).controlled_by(0, 1)) c.add(gates.X(0)) c.add(gates.X(1)) final_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_getitem_bad_indexing(backend): entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.RY(0, 0.1234)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) final_state = c() entropy[0] with pytest.raises(IndexError): entropy[1] with pytest.raises(IndexError): entropy["a"]
def test_state_callback(backend, density_matrix, copy): statec = callbacks.State(copy=copy) c = Circuit(2, density_matrix=density_matrix) c.add(gates.H(0)) c.add(gates.CallbackGate(statec)) c.add(gates.H(1)) c.add(gates.CallbackGate(statec)) final_state = c() target_state0 = np.array([1, 0, 1, 0]) / np.sqrt(2) target_state1 = np.ones(4) / 2.0 if not copy and K.name == "qibojit": # when copy is disabled in the callback and in-place updates are used target_state0 = target_state1 if density_matrix: target_state0 = np.tensordot(target_state0, target_state0, axes=0) target_state1 = np.tensordot(target_state1, target_state1, axes=0) K.assert_allclose(statec[0], target_state0) K.assert_allclose(statec[1], target_state1)
def test_controlled_unitary(backend, accelerators): matrix = np.random.random((2, 2)) c = Circuit(2) c.add(gates.H(0)) c.add(gates.H(1)) c.add(gates.Unitary(matrix, 1).controlled_by(0)) final_state = c.execute() target_state = np.ones_like(final_state) / 2.0 target_state[2:] = matrix.dot(target_state[2:]) K.assert_allclose(final_state, target_state) matrix = np.random.random((4, 4)) c = Circuit(4, accelerators) c.add((gates.H(i) for i in range(4))) c.add(gates.Unitary(matrix, 1, 3).controlled_by(0, 2)) final_state = c.execute() target_state = np.ones_like(final_state) / 4.0 ids = [10, 11, 14, 15] target_state[ids] = matrix.dot(target_state[ids]) K.assert_allclose(final_state, target_state)
def test_circuit_addition_result(backend, accelerators): """Check if circuit addition works properly on Tensorflow circuit.""" original_backend = qibo.get_backend() qibo.set_backend(backend) c1 = Circuit(2, accelerators) c1.add(gates.H(0)) c1.add(gates.H(1)) c2 = Circuit(2, accelerators) c2.add(gates.CNOT(0, 1)) c3 = c1 + c2 c = Circuit(2, accelerators) c.add(gates.H(0)) c.add(gates.H(1)) c.add(gates.CNOT(0, 1)) np.testing.assert_allclose(c3.execute().numpy(), c.execute().numpy()) qibo.set_backend(original_backend)
def test_crotations(): c = Circuit(3) c.add(gates.RX(0, 0.1)) c.add(gates.RZ(1, 0.4)) c.add(gates.CRX(0, 2, 0.5)) c.add(gates.RY(1, 0.3).controlled_by(2)) target = f"""// Generated by QIBO {__version__} OPENQASM 2.0; include "qelib1.inc"; qreg q[3]; rx(0.1) q[0]; rz(0.4) q[1]; crx(0.5) q[0],q[2]; cry(0.3) q[2],q[1];""" assert_strings_equal(c.to_qasm(), target) c = Circuit(2) c.add(gates.CU2(0, 1, 0.1, 0.2)) with pytest.raises(ValueError): target = c.to_qasm()
def sum_circuit(qubits): sum_qubits = int(np.ceil(np.log2(qubits))) + 1 sum_circuit = Circuit(qubits + sum_qubits) sum_circuit.add(gates.X(qubits).controlled_by(0)) sum_circuit.add(gates.X(qubits).controlled_by(1)) sum_circuit.add(gates.X(qubits + 1).controlled_by(*[0, 1])) for qub in range(2, qubits): sum_circuit.add( one_sum(sum_qubits).on_qubits( *([qub] + list(range(qubits, qubits + sum_qubits))))) return sum_circuit
def test_reset_channel_repeated(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) initial_state = random_state(5) c = Circuit(5) c.add(gates.ResetChannel(2, p0=0.3, p1=0.3, seed=123)) final_state = c(np.copy(initial_state), nshots=30) np.random.seed(123) target_state = [] for _ in range(30): noiseless_c = Circuit(5) if np.random.random() < 0.3: noiseless_c.add(gates.Collapse(2)) if np.random.random() < 0.3: noiseless_c.add(gates.Collapse(2)) noiseless_c.add(gates.X(2)) target_state.append(noiseless_c(np.copy(initial_state))) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_controlled_zpow(backend): """Check controlled ZPow and fallback to CZPow.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(3) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.X(2)) c.add(gates.ZPow(2, theta).controlled_by(0, 1)) c.add(gates.X(0)) c.add(gates.X(1)) final_state = c.execute().numpy() target_state = np.zeros_like(final_state) target_state[1] = np.exp(1j * theta) np.testing.assert_allclose(final_state, target_state) gate = gates.ZPow(0, theta).controlled_by(1) assert gate.__class__.__name__ == "CZPow" qibo.set_backend(original_backend)
def test_repeated_execute_with_noise(backend): thetas = np.random.random(4) c = Circuit(4) c.add((gates.RY(i, t) for i, t in enumerate(thetas))) noisy_c = c.with_noise((0.2, 0.0, 0.1)) np.random.seed(1234) final_state = noisy_c(nshots=20) np.random.seed(1234) target_state = [] for _ in range(20): noiseless_c = Circuit(4) for i, t in enumerate(thetas): noiseless_c.add(gates.RY(i, theta=t)) if np.random.random() < 0.2: noiseless_c.add(gates.X(i)) if np.random.random() < 0.1: noiseless_c.add(gates.Z(i)) target_state.append(noiseless_c()) target_state = np.stack(target_state) K.assert_allclose(final_state, target_state)
def test_entropy_bad_indexing(): """Check exceptions in ``Callback.__getitem__``.""" entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.RY(0, 0.1234)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() entropy[0] with pytest.raises(IndexError): entropy[1] with pytest.raises(IndexError): entropy["a"]
def test_set_parameters_fusion(backend): """Check gate fusion when ``circuit.set_parameters`` is used.""" c = Circuit(2) c.add(gates.RX(0, theta=0.1234)) c.add(gates.RX(1, theta=0.1234)) c.add(gates.CNOT(0, 1)) c.add(gates.RY(0, theta=0.1234)) c.add(gates.RY(1, theta=0.1234)) fused_c = c.fuse() K.assert_allclose(fused_c(), c()) c.set_parameters(4 * [0.4321]) fused_c.set_parameters(4 * [0.4321]) K.assert_allclose(fused_c(), c())
def test_noise_channel_repeated(backend): thetas = np.random.random(4) probs = 0.1 * np.random.random([4, 3]) + 0.2 gatelist = [gates.X, gates.Y, gates.Z] c = Circuit(4) c.add((gates.RY(i, t) for i, t in enumerate(thetas))) c.add((gates.PauliNoiseChannel(i, px, py, pz, seed=123) for i, (px, py, pz) in enumerate(probs))) final_state = c(nshots=40) np.random.seed(123) target_state = [] for _ in range(40): noiseless_c = Circuit(4) noiseless_c.add((gates.RY(i, t) for i, t in enumerate(thetas))) for i, ps in enumerate(probs): for p, gate in zip(ps, gatelist): if np.random.random() < p: noiseless_c.add(gate(i)) target_state.append(noiseless_c()) K.assert_allclose(final_state, target_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 test_measurement_collapse_distributed(backend, accelerators, nqubits, targets): # TODO: Add accelerators in this test once you fix `gates.M` collapse for # distributed circuit original_backend = qibo.get_backend() qibo.set_backend(backend) initial_state = random_state(nqubits) c = Circuit(nqubits, accelerators) output = c.add(gates.M(*targets, collapse=True)) result = c(np.copy(initial_state)) slicer = nqubits * [slice(None)] for t, r in zip(targets, output.samples()[0]): 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(result.state(), target_state) qibo.set_backend(original_backend)
def test_doubly_controlled_by_rx_no_effect(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(3) c.add(gates.X(0)) c.add(gates.RX(2, theta).controlled_by(0, 1)) c.add(gates.X(0)) final_state = c.execute().numpy() target_state = np.zeros_like(final_state) target_state[0] = 1.0 np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_variational_one_layer(backend, accelerators, nqubits): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random(nqubits) c = Circuit(nqubits) c.add((gates.RY(i, t) for i, t in enumerate(theta))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) target_state = c().numpy() c = Circuit(nqubits, accelerators) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) c.add(gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta)) final_state = c().numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def test_unitary_controlled_by(backend, accelerators): """Check that `controlled_by` works as expected with `Unitary`.""" original_backend = qibo.get_backend() qibo.set_backend(backend) matrix = np.random.random([2, 2]) c = Circuit(2, accelerators) c.add(gates.H(0)) c.add(gates.H(1)) c.add(gates.Unitary(matrix, 1).controlled_by(0)) final_state = c.execute().numpy() target_state = np.ones_like(final_state) / 2.0 target_state[2:] = matrix.dot(target_state[2:]) np.testing.assert_allclose(final_state, target_state) matrix = np.random.random([4, 4]) c = Circuit(4, accelerators) c.add((gates.H(i) for i in range(4))) c.add(gates.Unitary(matrix, 1, 3).controlled_by(0, 2)) final_state = c.execute().numpy() target_state = np.ones_like(final_state) / 4.0 ids = [10, 11, 14, 15] target_state[ids] = matrix.dot(target_state[ids]) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_unitary_random_twoqubit_gate(backend): """Check that ``Unitary`` gate can apply random 4x4 matrices.""" original_backend = qibo.get_backend() qibo.set_backend(backend) init_state = np.ones(8) / np.sqrt(8) matrix = np.random.random([4, 4]) target_state = np.kron(np.eye(2), matrix).dot(init_state) c = Circuit(3) c.add(gates.H(0)) c.add(gates.H(1)) c.add(gates.H(2)) c.add(gates.Unitary(matrix, 1, 2, name="random")) final_state = c.execute().numpy() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)