def test_set_parameters_with_gate_fusion(backend, accelerators):
    """Check updating parameters of fused circuit."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)

    params = np.random.random(9)
    c = Circuit(5, accelerators)
    c.add(gates.RX(0, theta=params[0]))
    c.add(gates.RY(1, theta=params[1]))
    c.add(gates.CZ(0, 1))
    c.add(gates.RX(2, theta=params[2]))
    c.add(gates.RY(3, theta=params[3]))
    c.add(gates.fSim(2, 3, theta=params[4], phi=params[5]))
    c.add(gates.RX(4, theta=params[6]))
    c.add(gates.RZ(0, theta=params[7]))
    c.add(gates.RZ(1, theta=params[8]))

    fused_c = c.fuse()
    np.testing.assert_allclose(c(), fused_c())

    new_params = np.random.random(9)
    new_params_list = list(new_params[:4])
    new_params_list.append((new_params[4], new_params[5]))
    new_params_list.extend(new_params[6:])
    c.set_parameters(new_params_list)
    fused_c.set_parameters(new_params_list)
    np.testing.assert_allclose(c(), fused_c())

    qibo.set_backend(original_backend)
Exemple #2
0
def test_set_parameters_with_gate_fusion(backend, trainable):
    """Check updating parameters of fused circuit."""
    params = np.random.random(9)
    c = Circuit(5)
    c.add(gates.RX(0, theta=params[0], trainable=trainable))
    c.add(gates.RY(1, theta=params[1]))
    c.add(gates.CZ(0, 1))
    c.add(gates.RX(2, theta=params[2]))
    c.add(gates.RY(3, theta=params[3], trainable=trainable))
    c.add(gates.fSim(2, 3, theta=params[4], phi=params[5]))
    c.add(gates.RX(4, theta=params[6]))
    c.add(gates.RZ(0, theta=params[7], trainable=trainable))
    c.add(gates.RZ(1, theta=params[8]))

    fused_c = c.fuse()
    final_state = fused_c()
    target_state = c()
    K.assert_allclose(final_state, target_state)

    if trainable:
        new_params = np.random.random(9)
        new_params_list = list(new_params[:4])
        new_params_list.append((new_params[4], new_params[5]))
        new_params_list.extend(new_params[6:])
    else:
        new_params = np.random.random(9)
        new_params_list = list(new_params[1:3])
        new_params_list.append((new_params[4], new_params[5]))
        new_params_list.append(new_params[6])
        new_params_list.append(new_params[8])

    c.set_parameters(new_params_list)
    fused_c.set_parameters(new_params_list)
    K.assert_allclose(c(), fused_c())
Exemple #3
0
def test_single_fusion_gate():
    """Check circuit fusion that creates a single ``FusedGate``."""
    queue = [gates.H(0), gates.X(1), gates.CZ(0, 1)]
    c = Circuit(2)
    c.add(queue)
    c = c.fuse()
    assert len(c.queue) == 1
    gate = c.queue[0]
    for gate, target in zip(gate.gates, queue):
        assert gate == target
Exemple #4
0
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())
Exemple #5
0
def test_inverse_circuit_execution(backend, accelerators, fuse):
    c = Circuit(4, accelerators)
    c.add(gates.RX(0, theta=0.1))
    c.add(gates.U2(1, phi=0.2, lam=0.3))
    c.add(gates.U3(2, theta=0.1, phi=0.3, lam=0.2))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CZ(1, 2))
    c.add(gates.fSim(0, 2, theta=0.1, phi=0.3))
    c.add(gates.CU2(0, 1, phi=0.1, lam=0.1))
    if fuse:
        if accelerators:
            with pytest.raises(NotImplementedError):
                c = c.fuse()
        else:
            c = c.fuse()
    invc = c.invert()
    target_state = np.ones(2**4) / 4
    final_state = invc(c(np.copy(target_state)))
    K.assert_allclose(final_state, target_state)
Exemple #6
0
def test_single_fusion_gate():
    """Check circuit fusion that creates a single ``FusedGate``."""
    queue = [gates.H(0), gates.X(1), gates.CZ(0, 1)]
    c = Circuit(2)
    c.add(queue)
    c = c.fuse()
    assert len(c.queue) == 1
    fgate = c.queue[0]
    assert fgate.gates[0] == queue[1]
    assert fgate.gates[1] == queue[0]
    assert fgate.gates[2] == queue[2]
Exemple #7
0
def test_controlled_by_gates_fusion(backend):
    """Check circuit fusion that contains ``controlled_by`` gates."""
    c = Circuit(4)
    c.add((gates.H(i) for i in range(4)))
    c.add(gates.RX(1, theta=0.1234).controlled_by(0))
    c.add(gates.RX(3, theta=0.4321).controlled_by(2))
    c.add((gates.RY(i, theta=0.5678) for i in range(4)))
    c.add(gates.RX(1, theta=0.1234).controlled_by(0))
    c.add(gates.RX(3, theta=0.4321).controlled_by(2))
    fused_c = c.fuse()
    K.assert_allclose(fused_c(), c())
Exemple #8
0
def test_fusedgate_matrix_calculation(backend):
    queue = [gates.H(0), gates.H(1), gates.CNOT(0, 1), gates.X(0), gates.X(1)]
    circuit = Circuit(2)
    circuit.add(queue)
    circuit = circuit.fuse()
    assert len(circuit.queue) == 1
    fused_gate = circuit.queue[0]

    x = np.array([[0, 1], [1, 0]])
    h = np.array([[1, 1], [1, -1]]) / np.sqrt(2)
    cnot = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
    target_matrix = np.kron(x, x) @ cnot @ np.kron(h, h)
    K.assert_allclose(fused_gate.matrix, target_matrix)
Exemple #9
0
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)
Exemple #10
0
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)
Exemple #11
0
def test_two_fusion_gate():
    """Check fusion that creates two ``FusedGate``s."""
    queue = [gates.X(0), gates.H(1),
             gates.RX(2, theta=0.1234).controlled_by(1),
             gates.H(2), gates.Y(1),
             gates.H(0)]
    c = Circuit(3)
    c.add(queue)
    c = c.fuse()
    assert len(c.queue) == 2
    fgate1, fgate2 = c.queue
    assert fgate2.gates[0] == queue[0]
    assert fgate2.gates[1] == queue[-1]
    assert fgate1.gates == [queue[1], queue[2], queue[4], queue[3]]
Exemple #12
0
def test_callbacks_fusion(backend):
    """Check entropy calculation in fused circuit."""
    from qibo import callbacks
    entropy = callbacks.EntanglementEntropy([0])
    c = Circuit(5)
    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()
    K.assert_allclose(fused_c(), c())
    target_entropy = [0.0, 1.0, 0.0, 1.0]
    K.assert_allclose(entropy[:], target_entropy, atol=1e-7)
Exemple #13
0
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())
Exemple #14
0
def test_fuse_circuit_with_controlled_by_gates():
    """Check gate fusion in circuit that contains ``controlled_by`` gates."""
    c = Circuit(4)
    c.add((gates.H(i) for i in range(4)))
    c.add(gates.RX(1, theta=0.1234).controlled_by(0))
    c.add(gates.RX(3, theta=0.4321).controlled_by(2))
    c.add((gates.RY(i, theta=0.5678) for i in range(4)))
    c.add(gates.RX(1, theta=0.1234).controlled_by(0))
    c.add(gates.RX(3, theta=0.4321).controlled_by(2))

    fused_c = c.fuse()
    target_state = c()
    final_state = fused_c()
    np.testing.assert_allclose(final_state, target_state)
Exemple #15
0
def test_variational_layer_fusion(backend, nqubits, nlayers, max_qubits):
    """Check fused variational layer execution."""
    theta = 2 * np.pi * np.random.random((2 * nlayers * nqubits,))
    theta_iter = iter(theta)

    c = Circuit(nqubits)
    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 - 1, 2)))
        c.add(gates.CZ(0, nqubits - 1))

    fused_c = c.fuse(max_qubits=max_qubits)
    K.assert_allclose(fused_c(), c())
Exemple #16
0
def test_random_circuit_fusion(backend, nqubits, ngates, max_qubits):
    """Check gate fusion in randomly generated circuits."""
    one_qubit_gates = [gates.RX, gates.RY, gates.RZ]
    two_qubit_gates = [gates.CNOT, gates.CZ, gates.SWAP]
    thetas = np.pi * np.random.random((ngates,))
    c = Circuit(nqubits)
    for i in range(ngates):
        gate = one_qubit_gates[int(np.random.randint(0, 3))]
        q0 = np.random.randint(0, nqubits)
        c.add(gate(q0, thetas[i]))
        gate = two_qubit_gates[int(np.random.randint(0, 3))]
        q0, q1 = np.random.randint(0, nqubits, (2,))
        while q0 == q1:
            q0, q1 = np.random.randint(0, nqubits, (2,))
        c.add(gate(q0, q1))
    fused_c = c.fuse(max_qubits=max_qubits)
    K.assert_allclose(fused_c(), c(), atol=1e-7)
Exemple #17
0
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)
Exemple #18
0
def test_fusion_errors():
    group = fusion.FusionGroup()
    with pytest.raises(ValueError):
        group.first_gate(2)

    group = fusion.FusionGroup()
    group.add(gates.Flatten(np.ones(4)))
    group.can_add(gates.H(0))
    with pytest.raises(RuntimeError):
        group.add(gates.H(0))

    group = fusion.FusionGroup()
    group.can_add(gates.H(0))
    group.add(gates.H(0))
    group.can_add(gates.RX(0, theta=0.1234).controlled_by(1))
    with pytest.raises(ValueError):
        group.add(gates.Flatten(np.ones(4)))

    group = fusion.FusionGroup()
    group.add(gates.RX(0, theta=0.1234).controlled_by(1))
    with pytest.raises(ValueError):
        group.add(gates.H(2))

    group = fusion.FusionGroup()
    group.add(gates.RX(0, theta=0.1234).controlled_by(1))
    with pytest.raises(ValueError):
        group.add(gates.CZ(1, 2))

    group = fusion.FusionGroup()
    with pytest.raises(ValueError):
        group.add(gates.TOFFOLI(0, 1, 2))

    group = fusion.FusionGroup()
    with pytest.raises(RuntimeError):
        group.calculate()

    # Fuse distributed circuit after gates are set
    import qibo
    if qibo.get_backend() == "custom":
        c = Circuit(4, accelerators={"/GPU:0": 2})
        c.add((gates.H(i) for i in range(4)))
        final_state = c()
        with pytest.raises(RuntimeError):
            fused_c = c.fuse()
def test_inverse_circuit_execution(backend, accelerators, fuse):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)

    c = Circuit(4, accelerators)
    c.add(gates.RX(0, theta=0.1))
    c.add(gates.U2(1, phi=0.2, lam=0.3))
    c.add(gates.U3(2, theta=0.1, phi=0.3, lam=0.2))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CZ(1, 2))
    c.add(gates.fSim(0, 2, theta=0.1, phi=0.3))
    c.add(gates.CU2(0, 1, phi=0.1, lam=0.1))
    if fuse:
        c = c.fuse()
    invc = c.invert()
    target_state = np.ones(2 ** 4) / 4
    final_state = invc(c(np.copy(target_state)))
    np.testing.assert_allclose(final_state, target_state)
    qibo.set_backend(original_backend)
Exemple #20
0
def test_two_fusion_gate():
    """Check fusion that creates two ``FusedGate``s."""
    queue = [
        gates.X(0),
        gates.H(1),
        gates.RX(2, theta=0.1234).controlled_by(1),
        gates.H(2),
        gates.Y(1),
        gates.H(0)
    ]
    c = Circuit(3)
    c.add(queue)
    c = c.fuse()
    assert len(c.queue) == 2
    gate1, gate2 = c.queue
    if len(gate1.gates) > len(gate2.gates):  # pragma: no cover
        # disabling coverage as this may not always happen
        gate1, gate2 = gate2, gate1
    assert gate1.gates == [queue[0], queue[-1]]
    assert gate2.gates == queue[1:-1]
def test_circuit_set_parameters_errors():
    """Check updating parameters errors."""
    c = Circuit(2)
    c.add(gates.RX(0, theta=0.789))
    c.add(gates.RX(1, theta=0.789))
    c.add(gates.fSim(0, 1, theta=0.123, phi=0.456))

    with pytest.raises(ValueError):
        c.set_parameters({gates.RX(0, theta=1.0): 0.568})
    with pytest.raises(ValueError):
        c.set_parameters([0.12586])
    with pytest.raises(ValueError):
        c.set_parameters(np.random.random(5))
    with pytest.raises(ValueError):
        import tensorflow as tf
        c.set_parameters(tf.random.uniform((6,), dtype=tf.float64))
    with pytest.raises(TypeError):
        c.set_parameters({0.3568})
    fused_c = c.fuse()
    with pytest.raises(TypeError):
        fused_c.set_parameters({gates.RX(0, theta=1.0): 0.568})
Exemple #22
0
def test_fuse_random_circuits(nqubits, ngates, accelerators):
    """Check gate fusion in randomly generated circuits."""
    one_qubit_gates = [gates.RX, gates.RY, gates.RZ]
    two_qubit_gates = [gates.CNOT, gates.CZ, gates.SWAP]

    for _ in range(10):
        thetas = np.pi * np.random.random((ngates, ))
        c = Circuit(nqubits, accelerators)
        for i in range(ngates):
            gate = one_qubit_gates[int(np.random.randint(0, 3))]
            q0 = np.random.randint(0, nqubits)
            c.add(gate(q0, thetas[i]))
            gate = two_qubit_gates[int(np.random.randint(0, 3))]
            q0, q1 = np.random.randint(0, nqubits, (2, ))
            while q0 == q1:
                q0, q1 = np.random.randint(0, nqubits, (2, ))
            c.add(gate(q0, q1))

        fused_c = c.fuse()
        target_state = c()
        final_state = fused_c()
        np.testing.assert_allclose(final_state, target_state)
Exemple #23
0
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)