def test_decomposition(self, tol):
        """Test decomposition onto a device's supported gate set"""
        dev = qml.device("default.qubit", wires=1)

        with QuantumTape() as tape:
            qml.U3(0.1, 0.2, 0.3, wires=[0])
            qml.expval(qml.PauliZ(0))

        tape = tape.expand(stop_at=lambda obj: obj.name in dev.operations)
        res = tape.execute(dev)
        assert np.allclose(res, np.cos(0.1), atol=tol, rtol=0)
Beispiel #2
0
def test_no_decomposition_defined():
    """Test that a controlled gate that has no control transform defined,
    as well as no decomposition transformed defined, still works correctly"""

    with QuantumTape() as tape:
        ctrl(qml.CZ, 0)(wires=[1, 2])

    tape = expand_tape(tape)

    assert len(tape.operations) == 1
    assert tape.operations[0].name == "ControlledQubitUnitary"
Beispiel #3
0
def test_nested_control():
    """Test nested use of control"""
    with QuantumTape() as tape:
        CCX = ctrl(ctrl(qml.PauliX, 7), 3)
        CCX(wires=0)
    assert len(tape.operations) == 1
    op = tape.operations[0]
    assert isinstance(op, ControlledOperation)
    new_tape = expand_tape(tape, 2)
    assert_equal_operations(new_tape.operations,
                            [qml.Toffoli(wires=[7, 3, 0])])
Beispiel #4
0
def test_multi_control():
    """Test control with a list of wires."""
    with QuantumTape() as tape:
        CCX = ctrl(qml.PauliX, control=[3, 7])
        CCX(wires=0)
    assert len(tape.operations) == 1
    op = tape.operations[0]
    assert isinstance(op, ControlledOperation)
    new_tape = expand_tape(tape, 1)
    assert_equal_operations(new_tape.operations,
                            [qml.Toffoli(wires=[7, 3, 0])])
Beispiel #5
0
    def test_CRX_decimals(self):
        """Test a controlled parametric operation with specified decimals."""

        with QuantumTape() as tape:
            qml.CRX(1.234, wires=(0, 1))

        _, ax = tape_mpl(tape, decimals=2)

        # two wire labels, so CRX is third text object
        assert ax.texts[2].get_text() == "RX\n(1.23)"
        plt.close()
Beispiel #6
0
def test_no_control_defined():
    """Test a custom operation with no control transform defined."""
    # QFT has no control rule defined.
    with QuantumTape() as tape:
        ctrl(qml.QFT, 2)(wires=[0, 1])
    tape = expand_tape(tape)
    assert len(tape.operations) == 12
    # Check that all operations are updated to their controlled version.
    for op in tape.operations:
        assert type(op) in {
            qml.ControlledPhaseShift, qml.Toffoli, qml.CRX, qml.CSWAP
        }
Beispiel #7
0
    def make_tape(self):
        params = [0.432, 0.123, 0.546, 0.32, 0.76]

        with QuantumTape() as tape:
            qml.RX(params[0], wires=0)
            qml.Rot(*params[1:4], wires=0)
            qml.CNOT(wires=[0, "a"])
            qml.RX(params[4], wires=4)
            qml.expval(qml.PauliX(wires="a"))
            qml.probs(wires=[0, "a"])

        return tape, params
Beispiel #8
0
    def test_stopping_criterion(self):
        """Test that gates specified in the stop_at
        argument are not expanded."""
        with QuantumTape() as tape:
            qml.U3(0, 1, 2, wires=0)
            qml.Rot(3, 4, 5, wires=0)
            qml.probs(wires=0), qml.probs(wires="a")

        new_tape = tape.expand(stop_at=lambda obj: obj.name in ["Rot"])
        assert len(new_tape.operations) == 4
        assert "Rot" in [i.name for i in new_tape.operations]
        assert not "U3" in [i.name for i in new_tape.operations]
Beispiel #9
0
    def test_expand_tape_multiple_wires_non_commuting(self, ret):
        """Test if a QuantumFunctionError is raised during tape expansion if non-commuting
        observables are on the same wire"""
        with QuantumTape() as tape:
            qml.RX(0.3, wires=0)
            qml.RY(0.4, wires=1)
            qml.expval(qml.PauliX(0))
            ret(qml.PauliZ(0))

        with pytest.raises(qml.QuantumFunctionError,
                           match="Only observables that are qubit-wise"):
            tape.expand(expand_measurements=True)
Beispiel #10
0
    def test_general_operations_decimals(self, op):
        """Check that the decimals argument affects text strings when applicable."""

        with QuantumTape() as tape:
            qml.apply(op)

        _, ax = tape_mpl(tape, decimals=2)

        num_wires = len(op.wires)
        assert ax.texts[num_wires].get_text() == op.label(decimals=2)

        plt.close()
Beispiel #11
0
    def test_state_preparation(self):
        """Test that state preparations are correctly processed"""
        params = [np.array([1, 0, 1, 0]) / np.sqrt(2), 1]

        with QuantumTape() as tape:
            A = qml.QubitStateVector(params[0], wires=[0, 1])
            B = qml.RX(params[1], wires=0)
            qml.expval(qml.PauliZ(wires=1))

        assert tape.operations == [A, B]
        assert tape._prep == [A]
        assert tape.get_parameters() == params
Beispiel #12
0
 def wrapper(*args, **kwargs):
     with get_active_tape().stop_recording(), QuantumTape() as tape:
         fn(*args, **kwargs)
     for op in reversed(tape.queue):
         try:
             op.adjoint()
         except NotImplementedError:
             # Expand the operation and adjoint the result.
             # We do not do anything with the output since
             # calling adjoint on the expansion will automatically
             # queue the new operations.
             adjoint(op.expand)()
Beispiel #13
0
def test_controlled_template():
    """Test that a controlled template correctly expands
    on a device that doesn't support it"""

    weights = np.ones([3, 2])

    with QuantumTape() as tape:
        ctrl(qml.templates.BasicEntanglerLayers, 0)(weights, wires=[1, 2])

    tape = expand_tape(tape)
    assert len(tape.operations) == 9
    assert all(o.name in {"CRX", "Toffoli"} for o in tape.operations)
Beispiel #14
0
    def test_active_wire_notches_False(self):
        """Test active wire notches are disable with active_wire_notches=False."""

        with QuantumTape() as tape:
            qml.QFT(wires=(0, 3))

        _, ax = tape_mpl(tape,
                         show_all_wires=True,
                         wire_order=[0, 1, 2, 3],
                         active_wire_notches=False)

        assert len(ax.patches) == 1
Beispiel #15
0
def test_batch_execute_partial_fail_parallel_tracker(mock_run_batch):
    """Asserts tracker updates during a partial failure of parallel execution"""

    FAIL_TASK = Mock()
    FAIL_TASK.result.return_value = None
    type(FAIL_TASK).id = PropertyMock(return_value="failed_task_arn")
    FAIL_TASK.state.return_value = "FAILED"
    FAIL_BATCH = Mock()
    FAIL_BATCH.results.side_effect = RuntimeError("tasks failed to complete")
    type(FAIL_BATCH).tasks = PropertyMock(return_value=[SIM_TASK, FAIL_TASK])
    type(FAIL_BATCH).unsuccessful = PropertyMock(
        return_value={"failed_task_arn"})

    mock_run_batch.return_value = FAIL_BATCH
    dev = _aws_device(wires=1, foo="bar", parallel=True)

    with QuantumTape() as circuit:
        qml.Hadamard(wires=0)
        qml.probs(wires=(0, ))

    circuits = [circuit, circuit]

    callback = Mock()
    try:
        with qml.Tracker(dev, callback=callback) as tracker:
            dev.batch_execute(circuits)
        dev.batch_execute(circuits)
    except RuntimeError:
        pass

    latest = {"batches": 1, "executions": 1, "shots": 1 * SHOTS}
    history = {
        "batches": [1],
        "executions": [1],
        "shots": [1 * SHOTS],
        "braket_task_id": ["task_arn"],
        "braket_failed_task_id": ["failed_task_arn"],
        "braket_simulator_ms": [1234],
        "braket_simulator_billed_ms": [3000],
    }
    totals = {
        "batches": 1,
        "executions": 1,
        "shots": 1 * SHOTS,
        "braket_simulator_ms": 1234,
        "braket_simulator_billed_ms": 3000,
    }
    assert tracker.latest == latest
    assert tracker.history == history
    assert tracker.totals == totals

    callback.assert_called_with(latest=latest, history=history, totals=totals)
Beispiel #16
0
    def test_Barrier(self):
        """Test Barrier gets correct special call."""

        with QuantumTape() as tape:
            qml.Barrier(wires=(0, 1, 2))

        _, ax = tape_mpl(tape)
        layer = 0

        assert len(ax.lines) == 3
        assert len(ax.collections) == 2

        plt.close()
Beispiel #17
0
    def test_no_output_execute(self):
        """Test that tapes with no measurement process return
        an empty list."""
        dev = qml.device("default.qubit", wires=2)
        params = [0.1, 0.2]

        with QuantumTape() as tape:
            qml.RX(params[0], wires=[0])
            qml.RY(params[1], wires=[1])

        res = tape.execute(dev)
        assert res.size == 0
        assert np.all(res == np.array([]))
Beispiel #18
0
    def adjoint(self):
        """Returns a new ControlledOperation that is equal to the adjoint of `self`"""

        active_tape = get_active_tape()

        if active_tape is not None:
            with get_active_tape().stop_recording(), QuantumTape() as new_tape:
                # Execute all ops adjointed.
                adjoint(requeue_ops_in_tape)(self.subtape)

        else:
            # Not within a queuing context
            with QuantumTape() as new_tape:
                # Execute all ops adjointed.
                ops = adjoint(requeue_ops_in_tape)(self.subtape)

            if not new_tape.operations:
                with qml.tape.QuantumTape() as new_tape:
                    for op in ops:
                        op.queue()

        return ControlledOperation(new_tape, self.control_wires)
Beispiel #19
0
    def test_expand_tape_multiple_wires(self):
        """Test the expand() method when measurements with more than one observable on the same
        wire are used"""
        with QuantumTape() as tape1:
            qml.RX(0.3, wires=0)
            qml.RY(0.4, wires=1)
            qml.expval(qml.PauliX(0))
            qml.var(qml.PauliX(0) @ qml.PauliX(1))
            qml.expval(qml.PauliX(2))

        with QuantumTape() as tape2:
            qml.RX(0.3, wires=0)
            qml.RY(0.4, wires=1)
            qml.RY(-np.pi / 2, wires=0)
            qml.RY(-np.pi / 2, wires=1)
            qml.expval(qml.PauliZ(0))
            qml.var(qml.PauliZ(0) @ qml.PauliZ(1))
            qml.expval(qml.PauliX(2))

        tape1_exp = tape1.expand()

        assert tape1_exp.graph.hash == tape2.graph.hash
Beispiel #20
0
    def test_WireCut(self):
        """Test WireCut gets correct special call."""

        with QuantumTape() as tape:
            qml.WireCut(wires=(0, 1))

        _, ax = tape_mpl(tape)
        layer = 0

        assert len(ax.lines) == 2
        assert len(ax.collections) == 2

        plt.close()
Beispiel #21
0
    def test_tensor_process_queuing(self):
        """Test that tensors are correctly queued"""
        with QuantumTape() as tape:
            A = qml.PauliX(wires=0)
            B = qml.PauliZ(wires=1)
            C = A @ B
            D = qml.expval(C)

        assert len(tape.queue) == 4
        assert not tape.operations
        assert tape.measurements == [D]
        assert tape.observables == [C]
        assert tape.output_dim == 1
Beispiel #22
0
def expand_with_control(tape, control_wire):
    """Expand a tape to include a control wire on all queued operations.

    Args:
        tape (.QuantumTape): quantum tape to be controlled
        control_wire (int): a single wire to use as the control wire

    Returns:
        .QuantumTape: A new QuantumTape with the controlled operations.
    """
    with QuantumTape(do_queue=False) as new_tape:
        for op in tape.operations:
            if hasattr(op, "_controlled"):
                # Execute the controlled version of the operation
                # and add that the to the tape context.
                # pylint: disable=protected-access
                op._controlled(control_wire)
            else:
                # Attempt to decompose the operation and apply
                # controls to each gate in the decomposition.
                with new_tape.stop_recording():
                    try:
                        tmp_tape = op.expand()

                    except NotImplementedError:
                        # No decomposition is defined. Create a
                        # ControlledQubitUnitary gate using the operation
                        # matrix representation.
                        with QuantumTape() as tmp_tape:
                            qml.ControlledQubitUnitary(
                                op.matrix,
                                control_wires=control_wire,
                                wires=op.wires)

                tmp_tape = expand_with_control(tmp_tape, control_wire)
                requeue_ops_in_tape(tmp_tape)

    return new_tape
Beispiel #23
0
    def test_sampling(self):
        """Test sampling works as expected"""
        dev = qml.device("default.qubit", wires=2, shots=10)

        with TorchInterface.apply(QuantumTape()) as tape:
            qml.Hadamard(wires=[0])
            qml.CNOT(wires=[0, 1])
            qml.sample(qml.PauliZ(0))
            qml.sample(qml.PauliX(1))

        res = tape.execute(dev)

        assert res.shape == (2, 10)
        assert isinstance(res, torch.Tensor)
Beispiel #24
0
    def test_tensor_observables_matmul(self):
        """Test that tensor observables are correctly processed from the annotated
        queue. Here, we test multiple tensor observables constructed via matmul."""

        with QuantumTape() as tape:
            op = qml.RX(1.0, wires=0)
            t_obs1 = qml.PauliZ(0) @ qml.PauliX(1)
            t_obs2 = t_obs1 @ qml.PauliZ(3)
            m = qml.expval(t_obs2)

        assert tape.operations == [op]
        assert tape.observables == [t_obs2]
        assert tape.measurements[0].return_type is qml.operation.Expectation
        assert tape.measurements[0].obs is t_obs2
Beispiel #25
0
    def make_tape(self):
        ops = []
        obs = []

        with QuantumTape() as tape:
            ops += [qml.RX(0.432, wires=0)]
            ops += [qml.Rot(0.543, 0, 0.23, wires=0)]
            ops += [qml.CNOT(wires=[0, "a"])]
            ops += [qml.RX(0.133, wires=4)]
            obs += [qml.PauliX(wires="a")]
            qml.expval(obs[0])
            obs += [qml.probs(wires=[0, "a"])]

        return tape, ops, obs
Beispiel #26
0
    def test_multiple_observables_same_wire(self):
        """Test if an error is raised when multiple observables are evaluated on the same wire
        without first running tape.expand()."""
        dev = qml.device("default.qubit", wires=2)

        with QuantumTape() as tape:
            qml.expval(qml.PauliX(0) @ qml.PauliZ(1))
            qml.expval(qml.PauliX(0))

        with pytest.raises(qml.QuantumFunctionError, match="Multiple observables are being"):
            tape.execute(dev)

        new_tape = tape.expand()
        new_tape.execute(dev)
Beispiel #27
0
    def test_empty_tape_wire_order(self):
        """Test situation with empty tape but specified wires and show_all_wires
        still draws wires."""

        _, ax = tape_mpl(QuantumTape(),
                         wire_order=[0, 1, 2],
                         show_all_wires=True)

        assert len(ax.lines) == 3
        for wire, line in enumerate(ax.lines):
            assert line.get_xdata() == (-1, 1)  # from -1 to number of layers
            assert line.get_ydata() == (wire, wire)

        plt.close()
Beispiel #28
0
    def test_decomposition_removing_parameters(self):
        """Test that decompositions which reduce the number of parameters
        on the tape retain tape consistency."""
        with QuantumTape() as tape:
            qml.BasisState(np.array([1]), wires=0)

        new_tape = tape.expand()

        assert len(new_tape.operations) == 1
        assert new_tape.operations[0].name == "PauliX"
        assert new_tape.operations[0].wires.tolist() == [0]
        assert new_tape.num_params == 0
        assert new_tape.get_parameters() == []

        assert isinstance(new_tape.operations[0], qml.PauliX)
Beispiel #29
0
    def test_single_mode_sample(self):
        """Test that there is only one array of values returned
        for a single wire qml.sample"""
        dev = qml.device("default.qubit", wires=2, shots=10)
        x = 0.543
        y = -0.654

        with QuantumTape() as tape:
            qml.RX(x, wires=[0])
            qml.RY(y, wires=[1])
            qml.CNOT(wires=[0, 1])
            qml.sample(qml.PauliZ(0) @ qml.PauliX(1))

        res = tape.execute(dev)
        assert res.shape == (1, 10)
    def test_same_hash(self):
        """Test that executing the same tape twice produces the same circuit
        hash."""
        dev = qml.device("default.qubit", wires=2)

        with QuantumTape() as tape0:
            qml.RZ(0.3, wires=[0])
            qml.expval(qml.PauliX(0))

        tape0.execute(dev)
        orig_hash = dev.circuit_hash

        tape0.execute(dev)
        new_hash = dev.circuit_hash
        assert orig_hash == new_hash