Ejemplo n.º 1
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:
        # TODO: add deployed QPUs from web endpoint
        pass

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

    return qc_names
Ejemplo n.º 2
0
def _get_qvm_qc(name: str,
                qvm_type: str,
                device: AbstractDevice,
                noise_model: NoiseModel = None,
                requires_executable: bool = False,
                connection: ForestConnection = None) -> QuantumComputer:
    """Construct a QuantumComputer backed by a QVM.

    This is a minimal wrapper over the QuantumComputer, QVM, and QVMCompiler constructors.

    :param name: A string identifying this particular quantum computer.
    :param qvm_type: The type of QVM. Either qvm or pyqvm.
    :param device: A device following the AbstractDevice interface.
    :param noise_model: An optional noise model
    :param requires_executable: Whether this QVM will refuse to run a :py:class:`Program` and
        only accept the result of :py:func:`compiler.native_quil_to_executable`. Setting this
        to True better emulates the behavior of a QPU.
    :param connection: An optional :py:class:`ForestConnection` object. If not specified,
        the default values for URL endpoints will be used.
    :return: A QuantumComputer backed by a QVM with the above options.
    """
    if connection is None:
        connection = ForestConnection()

    return QuantumComputer(
        name=name,
        qam=_get_qvm_or_pyqvm(qvm_type=qvm_type,
                              connection=connection,
                              noise_model=noise_model,
                              device=device,
                              requires_executable=requires_executable),
        device=device,
        compiler=QVMCompiler(device=device,
                             endpoint=connection.compiler_endpoint))
Ejemplo n.º 3
0
def list_quantum_computers(connection: ForestConnection = None,
                           qpus: bool = True,
                           qvms: bool = 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:
        connection = ForestConnection()

    qc_names: List[str] = []
    if qpus:
        qc_names += list(list_lattices(connection=connection).keys())

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

    return qc_names
Ejemplo n.º 4
0
def get_qc(name: str,
           *,
           as_qvm: bool = None,
           noisy: bool = None,
           connection: ForestConnection = None) -> QuantumComputer:
    """
    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("Aspen-0-12Q-A-noisy-qvm")
        >>> qc = get_qc("Aspen-0-12Q-A", 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-square-qvm")
        >>> qc = get_qc("9q-square", as_qvm=True)

    Finally, you can get request a QVM with "no" topology of a given number of qubits
    (technically, it's a fully connected graph among the given number of qubits) with::

        >>> qc = get_qc("5q-qvm") # or "6q-qvm", or "34q-qvm", ...

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

        >>> qc = get_qc("9q-square-qvm") # qc is fully specified by its name
        >>> qc = get_qc("9q-square-qvm", as_qvm=True) # redundant, but ok
        >>> qc = get_qc("9q-square-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()

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

    ma = re.fullmatch(r'(\d+)q', name)
    if ma is not None:
        n_qubits = int(ma.group(1))
        if not as_qvm:
            raise ValueError("Please name a valid device or run as a QVM")
        return _get_unrestricted_qvm(connection=connection,
                                     noisy=noisy,
                                     n_qubits=n_qubits)

    if name == '9q-generic' or name == '9q-square':
        if name == '9q-generic':
            warnings.warn("Please prefer '9q-square' instead of '9q-generic'",
                          DeprecationWarning)

        if not as_qvm:
            raise ValueError(
                "The device '9q-square' is only available as a QVM")
        return _get_9q_square_qvm(connection=connection, noisy=noisy)

    device = get_lattice(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 controlling noise models on QVMs.")
        return QuantumComputer(name=full_name,
                               qam=QPU(endpoint=pyquil_config.qpu_url,
                                       user=pyquil_config.user_id),
                               device=device,
                               compiler=QPUCompiler(
                                   endpoint=pyquil_config.compiler_url,
                                   device=device))

    if noisy:
        noise_model = device.noise_model
    else:
        noise_model = None

    return QuantumComputer(name=full_name,
                           qam=QVM(connection=connection,
                                   noise_model=noise_model),
                           device=device,
                           compiler=_get_qvm_compiler_based_on_endpoint(
                               device=device,
                               endpoint=connection.compiler_endpoint))
Ejemplo n.º 5
0
    def __init__(self,
                 clauses,
                 m=None,
                 steps=1,
                 grid_size=None,
                 tol=1e-5,
                 gate_noise=None,
                 verbose=False,
                 visualize=False):
        self.clauses = clauses
        self.m = m
        self.verbose = verbose
        self.visualize = visualize
        self.step_by_step_results = None
        self.optimization_history = None
        self.gate_noise = gate_noise
        if grid_size is None:
            self.grid_size = len(clauses) + len(qubits)
        else:
            self.grid_size = grid_size

        cost_operators, mapping = self.create_operators_from_clauses()
        self.mapping = mapping
        driver_operators = self.create_driver_operators()
        # minimizer_kwargs = {'method': 'BFGS',
        #                         'options': {'gtol': tol, 'disp': False}}

        # bounds = [(0, np.pi)]*steps + [(0, 2*np.pi)]*steps
        # minimizer_kwargs = {'method': 'L-BFGS-B',
        #                         'options': {'gtol': tol, 'disp': False},
        #                         'bounds': bounds}
        minimizer_kwargs = {
            'method': 'Nelder-Mead',
            'options': {
                'ftol': tol,
                'tol': tol,
                'disp': False
            }
        }

        if self.verbose:
            print_fun = print
        else:
            print_fun = pass_fun

        qubits = list(range(len(mapping)))

        if gate_noise:
            self.samples = int(1e3)
            pauli_channel = [gate_noise] * 3
        else:
            self.samples = None
            pauli_channel = None
        connection = ForestConnection()
        qvm = QVM(connection=connection, gate_noise=pauli_channel)
        topology = nx.complete_graph(len(qubits))
        device = NxDevice(topology=topology)
        qc = QuantumComputer(name="my_qvm",
                             qam=qvm,
                             device=device,
                             compiler=QVMCompiler(
                                 device=device,
                                 endpoint=connection.compiler_endpoint))

        vqe_option = {
            'disp': print_fun,
            'return_all': True,
            'samples': self.samples
        }

        self.qaoa_inst = QAOA(qc,
                              qubits,
                              steps=steps,
                              init_betas=None,
                              init_gammas=None,
                              cost_ham=cost_operators,
                              ref_ham=driver_operators,
                              minimizer=scipy.optimize.minimize,
                              minimizer_kwargs=minimizer_kwargs,
                              rand_seed=None,
                              vqe_options=vqe_option,
                              store_basis=True)

        self.ax = None