Beispiel #1
0
def forest():
    try:
        connection = ForestConnection()
        connection._wavefunction(Program(I(0)), 52)
        return connection
    except (RequestException, UnknownApiError) as e:
        return pytest.skip("This test requires a Forest connection: {}".format(e))
def test_expectation_async(forest: ForestConnection):
    # This tests the private _expectation_async method.
    # Users shouldn't use this, but lets make sure we're returning the right data type
    bell = Program(
        H(0),
        CNOT(0, 1),
    )
    job_id = forest._expectation_async(
        bell, [Program(X(0)), Program(X(1))], random_seed=52)
    job = forest._wait_for_job(job_id, machine='QVM')
    raw_coefs = job.result()
    assert raw_coefs.shape == (2, )
def test_qc():
    from pyquil.api import ForestConnection, QuantumComputer
    from pyquil.api._compiler import _extract_attribute_dictionary_from_program
    from pyquil.api._qac import AbstractCompiler
    from pyquil.device import NxDevice
    from pyquil.gates import I

    class BasicQVMCompiler(AbstractCompiler):
        def quil_to_native_quil(self, program: Program):
            return basic_compile(program)

        def native_quil_to_executable(self, nq_program: Program):
            return PyQuilExecutableResponse(
                program=nq_program.out(),
                attributes=_extract_attribute_dictionary_from_program(nq_program))
    try:
        qc = QuantumComputer(
            name='testing-qc',
            qam=QVM(connection=ForestConnection(), random_seed=52),
            device=NxDevice(nx.complete_graph(2)),
            compiler=BasicQVMCompiler(),
        )
        qc.run_and_measure(Program(I(0)), trials=1)
        return qc
    except (RequestException, TimeoutError) as e:
        return pytest.skip("This test requires a running local QVM: {}".format(e))
Beispiel #4
0
def list_quantum_computers(connection: ForestConnection = None,
                           qpus=True,
                           qvms=True) -> List[str]:
    """
    List the names of available quantum computers

    :param connection: An optional :py:class:ForestConnection` object. If not specified,
        the default values for URL endpoints will be used, and your API key
        will be read from ~/.pyquil_config. If you deign to change any
        of these parameters, pass your own :py:class:`ForestConnection` object.
    :param qpus: Whether to include QPU's in the list.
    :param qvms: Whether to include QVM's in the list.
    """
    if connection is None:
        # TODO: Use this to list devices?
        connection = ForestConnection()

    qc_names = []
    if qpus:
        for qpu_name in ['8Q-Agave', '19Q-Acorn']:
            qc_names += [qpu_name]
            if qvms:
                qc_names += [
                    "{}-qvm".format(qpu_name), "{}-noisy-qvm".format(qpu_name)
                ]

    if qvms:
        qc_names += ['9q-generic-qvm', '9q-generic-noisy-qvm']

    return qc_names
Beispiel #5
0
def compile_rigetti(num_qubits, topology, program):
    if topology.lower() == 'ring':
        edge_list = []
        for i in range(0, num_qubits):
            edge_list.append((i, (i + 1) % num_qubits))

        topology = nx.from_edgelist(edge_list)
        device = NxDevice(topology)

        compiler = LocalQVMCompiler("http://localhost:6000", device)
        my_qc = QuantumComputer(name='my_qc',
                                qam=QVM(connection=ForestConnection()),
                                device=device,
                                compiler=compiler)
        executable = compiler.quil_to_native_quil(
            program)  #create QC compatible specification
        depth = compute_depth_rigetti(executable)
        volume = len(executable) - 3  #subtract extra directives
        print(executable)
        q2_count = two_qubit_count(executable)
        out_str = str(executable)
        out_str = out_str + ("#DEPTH: %s |VOL.: %s |2Q GATE COUNT: %s\n" %
                             (depth, volume, q2_count))
        print("DEPTH: %s |VOL.: %s |2Q GATE COUNT: %s" %
              (depth, volume, q2_count))
        print()
        print()
        return out_str
Beispiel #6
0
def init_qvm_and_quilc(qvm_executable="qvm", quilc_executable="quilc"):
    qvm_port = get_free_port()
    quilc_port = get_free_port()
    qvm_server = subprocess.Popen([qvm_executable, "-S", "-p", str(qvm_port)])
    quilc_server = subprocess.Popen([quilc_executable, "-S", "-p", str(quilc_port)])
    fc = ForestConnection(sync_endpoint='http://127.0.0.1:' + str(qvm_port),
                          compiler_endpoint='http://127.0.0.1:' + str(quilc_port))
    return qvm_server, quilc_server, fc
Beispiel #7
0
def init_qvm_and_quilc(qvm_executable="qvm", quilc_executable="quilc"):
    qvm_port = get_free_port()
    quilc_port = get_free_port()
    qvm_server = subprocess.Popen([qvm_executable, "-S", "-p", str(qvm_port)])
    quilc_server = subprocess.Popen([quilc_executable, "-R", "-p", str(quilc_port)])
    fc = ForestConnection(sync_endpoint='http://127.0.0.1:' + str(qvm_port), 
                          compiler_endpoint='tcp://127.0.0.1:' + str(quilc_port))
    time.sleep(1)  #Temporary solution to prevent notebook racing ahead of server initilisation
    return qvm_server, quilc_server, fc
Beispiel #8
0
def get_backend(provider, qpu):
    """
    Get the backend instance by name
    :param provider:
    :param qpu:
    :return:
    """

    if provider.lower() == "ibmq":
        try:
            return IBMQBackend(qpu)
        except NoIBMQAccountError:
            return None

    if provider.lower() == "rigetti":
        # Create a connection to the forest SDK
        connection = ForestConnection(
            sync_endpoint=f"http://{qvm_hostname}:{qvm_port}",
            compiler_endpoint=f"tcp://{quilc_hostname}:{quilc_port}")

        return ForestBackend(qpu, simulator=True, connection=connection)

    # Default if no provider matched
    return None
Beispiel #9
0
topology = nx.from_edgelist([
    (10, 2),
    (10, 4),
    (10, 6),
    (10, 8),
])

device = NxDevice(topology)


class MyLazyCompiler(AbstractCompiler):
    def quil_to_native_quil(self, program, *, protoquil=None):
        return program

    def native_quil_to_executable(self, nq_program):
        return nq_program


my_qc = QuantumComputer(
    name='my-qvm',
    qam=QVM(connection=ForestConnection()),
    device=device,
    compiler=MyLazyCompiler(),
)

nx.draw(my_qc.qubit_topology())
plt.title('5qcm', fontsize=18)
plt.show()

my_qc.run_and_measure(Program(X(10)), trials=5)
Beispiel #10
0
def get_qc(name: str,
           *,
           as_qvm: bool = None,
           noisy: bool = None,
           connection: ForestConnection = None):
    """
    Get a quantum computer.

    A quantum computer is an object of type :py:class:`QuantumComputer` and can be backed
    either by a QVM simulator ("Quantum/Quil Virtual Machine") or a physical Rigetti QPU ("Quantum
    Processing Unit") made of superconducting qubits.

    You can choose the quantum computer to target through a combination of its name and optional
    flags. There are multiple ways to get the same quantum computer. The following are equivalent::

        >>> qc = get_qc("8Q-Agave-noisy-qvm")
        >>> qc = get_qc("8Q-Agave", as_qvm=True, noisy=True)

    and will construct a simulator of the 8q-agave chip with a noise model based on device
    characteristics. We also provide a means for constructing generic quantum simulators that
    are not related to a given piece of Rigetti hardware::

        >>> qc = get_qc("9q-generic-qvm")
        >>> qc = get_qc("9q-generic", as_qvm=True)

    Redundant flags are acceptable, but conflicting flags will raise an exception::

        >>> qc = get_qc("9q-generic-qvm") # qc is fully specified by its name
        >>> qc = get_qc("9q-generic-qvm", as_qvm=True) # redundant, but ok
        >>> qc = get_qc("9q-generic-qvm", as_qvm=False) # Error!

    Use :py:func:`list_quantum_computers` to retrieve a list of known qc names.

    This method is provided as a convenience to quickly construct and use QVM's and QPU's.
    Power users may wish to have more control over the specification of a quantum computer
    (e.g. custom noise models, bespoke topologies, etc.). This is possible by constructing
    a :py:class:`QuantumComputer` object by hand. Please refer to the documentation on
    :py:class:`QuantumComputer` for more information.

    :param name: The name of the desired quantum computer. This should correspond to a name
        returned by :py:func:`list_quantum_computers`. Names ending in "-qvm" will return
        a QVM. Names ending in "-noisy-qvm" will return a QVM with a noise model. Otherwise,
        we will return a QPU with the given name.
    :param as_qvm: An optional flag to force construction of a QVM (instead of a QPU). If
        specified and set to ``True``, a QVM-backed quantum computer will be returned regardless
        of the name's suffix
    :param noisy: An optional flag to force inclusion of a noise model. If
        specified and set to ``True``, a quantum computer with a noise model will be returned
        regardless of the name's suffix. The noise model for QVM's based on a real QPU
        is an empirically parameterized model based on real device noise characteristics.
        The generic QVM noise model is simple T1 and T2 noise plus readout error. See
        :py:func:`decoherance_noise_with_asymmetric_ro`.
    :param connection: An optional :py:class:ForestConnection` object. If not specified,
        the default values for URL endpoints, ping time, and status time will be used. Your
        user id and API key will be read from ~/.pyquil_config. If you deign to change any
        of these parameters, pass your own :py:class:`ForestConnection` object.
    :return:
    """
    if connection is None:
        connection = ForestConnection()

    name, as_qvm, noisy = _parse_name(name, as_qvm, noisy)

    if name == '9q-generic':
        if not as_qvm:
            raise ValueError(
                "The device '9q-generic' is only available as a QVM")

        nineq_square = nx.convert_node_labels_to_integers(
            nx.grid_2d_graph(3, 3))
        nineq_device = NxDevice(topology=nineq_square)
        if noisy:
            noise_model = decoherance_noise_with_asymmetric_ro(
                nineq_device.get_isa())
        else:
            noise_model = None

        return QuantumComputer(name='9q-generic-qvm',
                               qam=QVM(connection=connection,
                                       noise_model=noise_model),
                               device=nineq_device)

    # At least based off a real device.
    device = get_devices(as_dict=True)[name]

    if not as_qvm:
        if noisy is not None and noisy:
            warnings.warn(
                "You have specified `noisy=True`, but you're getting a QPU. This flag "
                "is meant for controling noise models on QVMs.")
        return QuantumComputer(name=name,
                               qam=QPU(device_name=name,
                                       connection=connection),
                               device=device)

    if noisy:
        noise_model = device.noise_model
        name = "{name}-noisy-qvm".format(name=name)
    else:
        noise_model = None
        name = "{name}-qvm".format(name=name)

    return QuantumComputer(name=name,
                           qam=QVM(connection=connection,
                                   noise_model=noise_model),
                           device=device)