Esempio n. 1
0
def test_reset(forest):
    device = NxDevice(nx.complete_graph(3))
    qc = QuantumComputer(name='testy!',
                         qam=QVM(connection=forest),
                         device=device,
                         compiler=DummyCompiler())
    p = Program(Declare(name='theta', memory_type='REAL'),
                Declare(name='ro', memory_type='BIT'),
                RX(MemoryReference('theta'), 0),
                MEASURE(0, MemoryReference('ro'))).wrap_in_numshots_loop(1000)
    qc.run(executable=p, memory_map={'theta': [np.pi]})

    aref = ParameterAref(name='theta', index=0)
    assert qc.qam._variables_shim[aref] == np.pi
    assert qc.qam._executable == p
    assert qc.qam._memory_results["ro"].shape == (1000, 1)
    assert all([bit == 1 for bit in qc.qam._memory_results["ro"]])
    assert qc.qam.status == 'done'

    qc.reset()

    assert qc.qam._variables_shim == {}
    assert qc.qam._executable is None
    assert qc.qam._memory_results["ro"] is None
    assert qc.qam.status == 'connected'
Esempio n. 2
0
def test_classical_regs_implicit_ro():
    p = Program()
    p.inst(Declare("reg", "BIT", 2), X(0)).measure(0,
                                                   MemoryReference("reg", 1))
    assert p.out() == "DECLARE reg BIT[2]\nX 0\nMEASURE 0 reg[1]\n"
    assert p.declarations == {
        "ro": Declare("ro", "BIT", 1),
        "reg": Declare("reg", "BIT", 2),
    }
Esempio n. 3
0
def test_parsing_raw_capture():
    parse_equals(
        "DECLARE iqs REAL[200000]\n" 'RAW-CAPTURE 0 "ro_rx" 0.001 iqs',
        Declare("iqs", "REAL", 200000),
        RawCapture(Frame([Qubit(0)], "ro_rx"), 0.001, MemoryReference("iqs")),
    )
    parse_equals(
        "DECLARE iqs REAL[200000]\n" 'NONBLOCKING RAW-CAPTURE 0 "ro_rx" 0.001 iqs',
        Declare("iqs", "REAL", 200000),
        RawCapture(Frame([Qubit(0)], "ro_rx"), 0.001, MemoryReference("iqs"), nonblocking=True),
    )
Esempio n. 4
0
def test_unsupported_ops():
    target = Label("target")
    base_prog = Program(Declare("reg1", "BIT"), Declare("reg2", "BIT"), H(0), JumpTarget(target), CNOT(0, 1))

    bad_ops = [WAIT, Jump(target), MOVE(MemoryReference("reg1"), MemoryReference("reg2"))]

    assert to_latex(base_prog)

    for op in bad_ops:
        prog = base_prog + op
        with pytest.raises(ValueError):
            _ = to_latex(prog)
Esempio n. 5
0
def test_parsing_capture():
    wf = FlatWaveform(duration=1.0, iq=1.0)
    parse_equals(
        "DECLARE iq REAL[2]\n" 'CAPTURE 0 "ro_rx" flat(duration: 1.0, iq: 1.0) iq',
        Declare("iq", "REAL", 2),
        Capture(Frame([Qubit(0)], "ro_rx"), wf, MemoryReference("iq")),
    )
    parse_equals(
        "DECLARE iq REAL[2]\n" 'NONBLOCKING CAPTURE 0 "ro_rx" flat(duration: 1.0, iq: 1.0) iq',
        Declare("iq", "REAL", 2),
        Capture(Frame([Qubit(0)], "ro_rx"), wf, MemoryReference("iq"), nonblocking=True),
    )
Esempio n. 6
0
def test_halt():
    prog = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro", 0)))
    prog.inst(HALT)
    prog.inst(X(0), MEASURE(0, MemoryReference("ro", 0)))
    qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator)
    qam.execute(prog)
    # HALT should stop execution; measure should give 1
    assert qam.ram["ro"][0] == 1

    prog = Program(Declare("ro", "BIT"), X(0)).inst(X(0)).inst(MEASURE(0, MemoryReference("ro", 0)))
    qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator)
    qam.execute(prog)
    assert qam.ram["ro"][0] == 0
Esempio n. 7
0
def test_construction_syntax():
    p = (Program().inst(Declare("ro", "BIT", 2), X(0), Y(1),
                        Z(0)).measure(0, MemoryReference("ro", 1)))
    assert p.out() == ("DECLARE ro BIT[2]\nX 0\nY 1\nZ 0\nMEASURE 0 ro[1]\n")
    p = (Program().inst(Declare("ro", "BIT", 3), X(0)).inst(Y(1)).measure(
        0, MemoryReference("ro", 1)).inst(MEASURE(1, MemoryReference("ro",
                                                                     2))))
    assert p.out() == (
        "DECLARE ro BIT[3]\nX 0\nY 1\nMEASURE 0 ro[1]\nMEASURE 1 ro[2]\n")
    p = (Program().inst(Declare("ro", "BIT", 2),
                        X(0)).measure(0, MemoryReference("ro", 1)).inst(
                            Y(1), X(0)).measure(0, MemoryReference("ro", 0)))
    assert p.out() == (
        "DECLARE ro BIT[2]\nX 0\nMEASURE 0 ro[1]\nY 1\nX 0\nMEASURE 0 ro[0]\n")
Esempio n. 8
0
def test_run_with_parameters(forest):
    device = NxDevice(nx.complete_graph(3))
    qc = QuantumComputer(name='testy!',
                         qam=QVM(connection=forest),
                         device=device,
                         compiler=DummyCompiler())
    bitstrings = qc.run(executable=Program(
        Declare(name='theta', memory_type='REAL'),
        Declare(name='ro', memory_type='BIT'), RX(MemoryReference('theta'), 0),
        MEASURE(0, MemoryReference('ro'))).wrap_in_numshots_loop(1000),
                        memory_map={'theta': [np.pi]})

    assert bitstrings.shape == (1000, 1)
    assert all([bit == 1 for bit in bitstrings])
Esempio n. 9
0
def test_indexing():
    program = (Program(Declare("ro", "BIT"), H(0), Y(1), CNOT(0, 1)).measure(
        0, MemoryReference("ro", 0)).if_then(MemoryReference("ro", 0),
                                             Program(X(0)), Program()))
    assert program[1] == H(0)
    for ii, instr in enumerate(program.instructions):
        assert program[ii] == instr
Esempio n. 10
0
def test_readout_symmetrization(client_configuration: QCSClientConfiguration):
    quantum_processor = NxQuantumProcessor(nx.complete_graph(3))
    noise_model = decoherence_noise_with_asymmetric_ro(quantum_processor.to_compiler_isa())
    qc = QuantumComputer(
        name="testy!",
        qam=QVM(client_configuration=client_configuration, noise_model=noise_model),
        compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration),
    )

    prog = Program(
        Declare("ro", "BIT", 2),
        I(0),
        X(1),
        MEASURE(0, MemoryReference("ro", 0)),
        MEASURE(1, MemoryReference("ro", 1)),
    )
    prog.wrap_in_numshots_loop(1000)

    bs1 = qc.run(prog)
    avg0_us = np.mean(bs1[:, 0])
    avg1_us = 1 - np.mean(bs1[:, 1])
    diff_us = avg1_us - avg0_us
    assert diff_us > 0.03

    prog = Program(
        I(0),
        X(1),
    )
    bs2 = qc.run_symmetrized_readout(prog, 1000)
    avg0_s = np.mean(bs2[:, 0])
    avg1_s = 1 - np.mean(bs2[:, 1])
    diff_s = avg1_s - avg0_s
    assert diff_s < 0.05
Esempio n. 11
0
def test_qvm_run_region_declared_not_measured(
        client_configuration: QCSClientConfiguration):
    qvm = QVM(client_configuration=client_configuration)
    p = Program(Declare("reg", "BIT"), X(0))
    result = qvm.run(p.wrap_in_numshots_loop(100))
    bitstrings = result.readout_data.get("reg")
    assert bitstrings.shape == (100, 0)
Esempio n. 12
0
def test_qvm_run_region_declared_not_measured(forest: ForestConnection):
    qvm = QVM(connection=forest)
    p = Program(Declare("reg", "BIT"), X(0))
    nq = PyQuilExecutableResponse(program=p.out(), attributes={"num_shots": 100})
    qvm.load(nq).run().wait()
    bitstrings = qvm.read_memory(region_name="reg")
    assert bitstrings.shape == (100, 0)
def test_qvm_run_region_declared_not_measured(
        client_configuration: QCSClientConfiguration):
    qvm = QVM(client_configuration=client_configuration)
    p = Program(Declare("reg", "BIT"), X(0))
    qvm.load(p.wrap_in_numshots_loop(100)).run().wait()
    bitstrings = qvm.read_memory(region_name="reg")
    assert bitstrings.shape == (100, 0)
Esempio n. 14
0
def test_measurement_calls():
    p = Program()
    p.inst(Declare('ro', 'BIT', 2), MEASURE(0, MemoryReference('ro', 1)),
           MEASURE(0, MemoryReference('ro', 1)))
    assert p.out() == ('DECLARE ro BIT[2]\n'
                       'MEASURE 0 ro[1]\n'
                       'MEASURE 0 ro[1]\n')
Esempio n. 15
0
    def declare(self, name, memory_type='BIT', memory_size=1, shared_region=None, offsets=None):
        """DECLARE a quil variable

        This adds the declaration to the current program and returns a MemoryReference to the
        base (offset = 0) of the declared memory.

        .. note::
            This function returns a MemoryReference and cannot be chained like some
            of the other Program methods. Consider using ``inst(DECLARE(...))`` if you
            would like to chain methods, but please be aware that you must create your
            own MemoryReferences later on.

        :param name: Name of the declared variable
        :param memory_type: Type of the declared memory: 'BIT', 'REAL', 'OCTET' or 'INTEGER'
        :param memory_size: Number of array elements in the declared memory.
        :param shared_region: You can declare a variable that shares its underlying memory
            with another region. This allows aliasing. For example, you can interpret an array
            of measured bits as an integer.
        :param offsets: If you are using ``shared_region``, this allows you to share only
            a part of the parent region. The offset is given by an array type and the number
            of elements of that type. For example,
            ``DECLARE target-bit BIT SHARING real-region OFFSET 1 REAL 4 BIT`` will let you use
            target-bit to poke into the fourth bit of the second real from the leading edge of
            real-region.
        :return: a MemoryReference to the start of the declared memory region, ie a memory
            reference to ``name[0]``.
        """
        self.inst(Declare(name=name, memory_type=memory_type, memory_size=memory_size,
                          shared_region=shared_region, offsets=offsets))
        return MemoryReference(name=name, declared_size=memory_size)
Esempio n. 16
0
def test_memory_commands():
    parse_equals("DECLARE mem OCTET[32] SHARING mem2 OFFSET 16 REAL OFFSET 32 REAL",
                 Declare("mem", "OCTET", 32, shared_region="mem2", offsets=[(16, "REAL"), (32, "REAL")]))
    parse_equals("STORE mem ro[2] ro[0]", STORE("mem", MemoryReference("ro", 2), MemoryReference("ro", 0)))
    parse_equals("LOAD ro[8] mem mem[4]", LOAD(MemoryReference("ro", 8), "mem", MemoryReference("mem", 4)))
    parse_equals("CONVERT ro[1] ro[2]", CONVERT(MemoryReference("ro", 1), MemoryReference("ro", 2)))
    parse_equals("EXCHANGE ro[0] ro[1]", EXCHANGE(MemoryReference("ro", 0), MemoryReference("ro", 1)))
    parse_equals("MOVE mem[2] 4", MOVE(MemoryReference("mem", 2), 4))
Esempio n. 17
0
def test_warn_on_pragma_with_trailing_measures():
    "Check that to_latex warns when measurement alignment conflicts with gate group pragma."
    with pytest.warns(UserWarning):
        _ = to_latex(Program(Declare('ro', 'BIT'),
                             Pragma("LATEX_GATE_GROUP"),
                             MEASURE(0, MemoryReference('ro')),
                             Pragma("END_LATEX_GATE_GROUP"),
                             MEASURE(1, MemoryReference('ro'))))
Esempio n. 18
0
def test_qvm_run_just_program(client_configuration: QCSClientConfiguration):
    qvm = QVM(client_configuration=client_configuration,
              gate_noise=(0.01, 0.01, 0.01))
    p = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro")))
    result = qvm.run(p.wrap_in_numshots_loop(1000))
    bitstrings = result.readout_data.get("ro")
    assert bitstrings.shape == (1000, 1)
    assert np.mean(bitstrings) > 0.8
def test_qvm__default_client(client_configuration: QCSClientConfiguration):
    qvm = QVM(client_configuration=client_configuration)
    p = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro")))
    qvm.load(p.wrap_in_numshots_loop(1000))
    qvm.run()
    qvm.wait()
    bitstrings = qvm.read_memory(region_name="ro")
    assert bitstrings.shape == (1000, 1)
Esempio n. 20
0
def test_run_with_parameters(forest):
    device = NxDevice(nx.complete_graph(3))
    qc = QuantumComputer(
        name="testy!", qam=QVM(connection=forest), device=device, compiler=DummyCompiler()
    )
    bitstrings = qc.run(
        executable=Program(
            Declare(name="theta", memory_type="REAL"),
            Declare(name="ro", memory_type="BIT"),
            RX(MemoryReference("theta"), 0),
            MEASURE(0, MemoryReference("ro")),
        ).wrap_in_numshots_loop(1000),
        memory_map={"theta": [np.pi]},
    )

    assert bitstrings.shape == (1000, 1)
    assert all([bit == 1 for bit in bitstrings])
Esempio n. 21
0
def test_measurement_calls():
    p = Program()
    p.inst(
        Declare("ro", "BIT", 2),
        MEASURE(0, MemoryReference("ro", 1)),
        MEASURE(0, MemoryReference("ro", 1)),
    )
    assert p.out() == ("DECLARE ro BIT[2]\nMEASURE 0 ro[1]\nMEASURE 0 ro[1]\n")
Esempio n. 22
0
def implicitly_declare_ro(
        instructions: List[AbstractInstruction]) -> List[AbstractInstruction]:
    """
    Implicitly declare a register named ``ro`` for backwards compatibility with Quil 1.

    There used to be one un-named hunk of classical memory. Now there are variables with
    declarations. Instead of::

        MEASURE 0 [0]

    You must now measure into a named register, idiomatically::

        MEASURE 0 ro[0]

    The ``MEASURE`` instruction will emit this (with a deprecation warning) if you're still
    using bare integers for classical addresses. However, you must also declare memory in the
    new scheme::

        DECLARE ro BIT[8]
        MEASURE 0 ro[0]

    This method will determine if you are in "backwards compatibility mode" and will declare
    a read-out ``ro`` register for you. If you program contains any DECLARE commands or if it
    does not have any MEASURE x ro[x], this will not do anything.

    This behavior is included for backwards compatibility and will be removed in future releases
    of PyQuil. Please DECLARE all memory including ``ro``.
    """
    ro_addrs: List[int] = []
    for instr in instructions:
        if isinstance(instr, Declare):
            # The user has declared their own memory
            # so they are responsible for all declarations and memory references.
            return instructions

        if isinstance(instr, Measurement):
            if instr.classical_reg is None:
                continue

            if instr.classical_reg.name == "ro":
                ro_addrs += [instr.classical_reg.offset]
            else:
                # The user has used a classical register named something other than "ro"
                # so they are responsible for all declarations and memory references.
                return instructions

    if len(ro_addrs) == 0:
        return instructions

    warnings.warn(
        "Please DECLARE all memory. I'm adding a declaration for the `ro` register, "
        "but I won't do this for you in the future.")

    new_instr = instructions.copy()
    new_instr.insert(
        0, Declare(name="ro", memory_type="BIT",
                   memory_size=max(ro_addrs) + 1))
    return new_instr
Esempio n. 23
0
def test_is_protoquil():
    prog = Program(Declare('ro', 'BIT'), MEASURE(1, MemoryReference("ro", 0)),
                   H(1), RESET())
    validate_protoquil(prog)
    assert prog.is_protoquil()

    prog = Program(Declare('ro', 'BIT'), H(0), Y(1), CNOT(0, 1)) \
        .measure(0, MemoryReference("ro", 0)) \
        .if_then(MemoryReference("ro", 0), Program(X(0)), Program())
    with pytest.raises(ValueError):
        validate_protoquil(prog)
    assert not prog.is_protoquil()

    prog = Program(Declare('ro', 'BIT'), ClassicalNot(MemoryReference("ro",
                                                                      0)))
    with pytest.raises(ValueError):
        validate_protoquil(prog)
    assert not prog.is_protoquil()
def test_run_with_bad_parameters(client_configuration: QCSClientConfiguration,
                                 param):
    quantum_processor = NxQuantumProcessor(nx.complete_graph(3))
    qc = QuantumComputer(
        name="testy!",
        qam=QVM(client_configuration=client_configuration),
        compiler=DummyCompiler(quantum_processor=quantum_processor,
                               client_configuration=client_configuration),
    )
    executable = Program(
        Declare(name="theta", memory_type="REAL"),
        Declare(name="ro", memory_type="BIT"),
        RX(MemoryReference("theta"), 0),
        MEASURE(0, MemoryReference("ro")),
    ).wrap_in_numshots_loop(1000)

    with pytest.raises(TypeError, match=r"Parameter must be"):
        executable.write_memory(region_name="theta", value=param)
Esempio n. 25
0
 def declare(self, name, memory_type, memory_size, *sharing):
     shared, *offsets = sharing
     d = Declare(
         str(name),
         memory_type=str(memory_type),
         memory_size=int(memory_size) if memory_size else 1,
         shared_region=str(shared) if shared else None,
         offsets=offsets if shared else None,
     )
     return d
Esempio n. 26
0
def test_run_with_parameters(client_configuration: QCSClientConfiguration):
    quantum_processor = NxQuantumProcessor(nx.complete_graph(3))
    qc = QuantumComputer(
        name="testy!",
        qam=QVM(client_configuration=client_configuration),
        compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration),
    )
    bitstrings = qc.run(
        executable=Program(
            Declare(name="theta", memory_type="REAL"),
            Declare(name="ro", memory_type="BIT"),
            RX(MemoryReference("theta"), 0),
            MEASURE(0, MemoryReference("ro")),
        ).wrap_in_numshots_loop(1000),
        memory_map={"theta": [np.pi]},
    )

    assert bitstrings.shape == (1000, 1)
    assert all([bit == 1 for bit in bitstrings])
Esempio n. 27
0
def test_noisy(client_configuration: QCSClientConfiguration):
    # https://github.com/rigetti/pyquil/issues/764
    p = Program(
        Declare("ro", "BIT", 1),
        X(0),
        MEASURE(0, ("ro", 0)),
    ).wrap_in_numshots_loop(10000)
    qc = get_qc("1q-qvm", noisy=True, client_configuration=client_configuration)
    result = qc.run(qc.compile(p))
    assert result.mean() < 1.0
def test_qvm_run_just_program(client_configuration: QCSClientConfiguration):
    qvm = QVM(client_configuration=client_configuration,
              gate_noise=(0.01, 0.01, 0.01))
    p = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro")))
    qvm.load(p.wrap_in_numshots_loop(1000))
    qvm.run()
    qvm.wait()
    bitstrings = qvm.read_memory(region_name="ro")
    assert bitstrings.shape == (1000, 1)
    assert np.mean(bitstrings) > 0.8
Esempio n. 29
0
def test_get_qubits():
    pq = Program(Declare('ro', 'BIT'), X(0), CNOT(0, 4), MEASURE(5, MemoryReference("ro", 0)))
    assert pq.get_qubits() == {0, 4, 5}

    q = [QubitPlaceholder() for _ in range(6)]
    pq = Program(Declare('ro', 'BIT'), X(q[0]), CNOT(q[0], q[4]), MEASURE(q[5], MemoryReference("ro", 0)))
    qq = QubitPlaceholder()
    pq.inst(Y(q[2]), X(qq))
    assert address_qubits(pq).get_qubits() == {0, 1, 2, 3, 4}

    qubit_index = 1
    p = Program(("H", qubit_index))
    assert p.get_qubits() == {qubit_index}
    q1 = QubitPlaceholder()
    q2 = QubitPlaceholder()
    p.inst(("CNOT", q1, q2))
    with pytest.raises(ValueError) as e:
        _ = address_qubits(p).get_qubits()
    assert e.match('Your program mixes instantiated qubits with placeholders')
Esempio n. 30
0
def test_qvm_run_just_program(forest: ForestConnection):
    qvm = QVM(connection=forest, gate_noise=[0.01] * 3)
    p = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro")))
    p.wrap_in_numshots_loop(1000)
    qvm.load(p)
    qvm.run()
    qvm.wait()
    bitstrings = qvm.read_memory(region_name="ro")
    assert bitstrings.shape == (1000, 1)
    assert np.mean(bitstrings) > 0.8