.. _qpu_quantum_solvers_intro: =============== Quantum Solvers =============== Ocean's :ref:`dwave-system ` package enables you to use a |dwave_short| quantum computer as a :term:`sampler`. In addition to :class:`~dwave.system.samplers.DWaveSampler`, the package provides an :class:`~dwave.system.composites.EmbeddingComposite` :term:`composite` that maps unstructured problems to the :ref:`graph structure ` of the selected sampler, a process known as :term:`minor-embedding`. Solver Identity and Selection ============================= Optimization problems submitted to quantum computers in the Leap service, as either stand-alone problems small enough to fit onto a :term:`QPU` or subproblems generated by a :term:`hybrid` solver from a large problem, are sent to a QPU solver selected by default or explicitly. The :ref:`qpu_quantum_solvers_example_and` example uses the QPU selected by default by Ocean software's :class:`~dwave.system.samplers.DWaveSampler` class. For research, however, you may prefer to explicitly select a QPU solver. QPU solvers are uniquely referenced by an identity dictionary.\ [#]_ This identity includes a name (e.g., ``Advantage2_system1.6``) and a graph identifier that tracks any changes to the solver's :ref:`working graph `. Ocean software enables solver selection by identity (name alone or with a particular graph ID), topology type, qubit count, and other characteristics, as described in the :meth:`~dwave.cloud.client.Client.get_solvers` method. The :ref:`qpu_quantum_solvers_example_native` example ensures that the selected QPU solver has a :term:`Zephyr` topology and saves the ``graph_id`` of its current working graph for reference. .. [#] Requires :ref:`Ocean SDK ` releases 9.0 or higher. .. _qpu_quantum_solvers_example_and: Example: Simple QPU Usage ========================= .. note:: The :ref:`ocean_sapi_access_basic` steps you through configuring access to |dwave_short| quantum computers. For a :ref:`binary quadratic model ` (BQM) representing a Boolean AND gate (see the :ref:`ocean_workflow_formulating_bqm` section for more details) the problem is defined on alphanumeric variables :math:`in1, in2, out` that must be mapped to the QPU's numerically indexed qubits. >>> from dimod.generators import and_gate >>> bqm = and_gate('in1', 'in2', 'out') Because of the sampler's probabilistic nature, you typically request multiple samples for a problem; this example sets the :ref:`parameter_qpu_num_reads` solver parameter to 1000. >>> from dwave.system import DWaveSampler, EmbeddingComposite >>> sampler = EmbeddingComposite(DWaveSampler()) >>> sampleset = sampler.sample(bqm, num_reads=1000) >>> print(sampleset) # doctest: +SKIP in1 in2 out energy num_oc. chain_. 0 1 0 0 0.0 321 0.0 1 1 1 1 0.0 97 0.0 2 0 0 0 0.0 375 0.0 3 0 1 0 0.0 206 0.0 4 1 0 1 2.0 1 0.33333 ['BINARY', 5 rows, 1000 samples, 3 variables] Note that the first four samples are the valid states of the AND gate and have lower energy than invalid state :math:`in1=1, in2=0, out=1`. For additional beginner examples of submitting problems to |dwave_short| quantum computers, see the :ref:`qpu_index_examples_beginner` section. .. _qpu_quantum_solvers_example_native: Example: Problem on the Native Graph ==================================== This example creates a RAN7 problem (see :func:`~dimod.generators.ran_r`) on a graph of 1000 nodes structured in a Zephyr topology, which can embed directly onto 1000 qubits of an |adv2| QPU. For reproducibility, it saves the :ref:`working graph ` identifier of the selected QPU. >>> from dwave.system import DWaveSampler ... >>> sampler = DWaveSampler(topology__type="zephyr") >>> qpu_identity = sampler.solver.identity # doctest: +SKIP >>> print(sampler.solver.identity.dict()) # doctest: +SKIP {'name': 'Advantage2_system1.6', 'version': {'graph_id': '010e7a62e5'}} In any future experiments, the researcher can explicitly select that QPU with the requirement that the current working graph is unchanged: >>> sampler = DWaveSampler(solver=dict(identity=qpu_identity)) # doctest: +SKIP >>> print(sampler.solver.version) # doctest: +SKIP {'graph_id': '010e7a62e5'} Run the problem on the first 1000 qubits of the working graph: >>> from dimod.generators import ran_r >>> qpu_graph = sampler.to_networkx_graph() >>> problem_graph = qpu_graph.subgraph(list(qpu_graph.nodes)[:1000]) # doctest: +SKIP >>> bqm = ran_r(7, problem_graph) # doctest: +SKIP >>> sampleset = sampler.sample(bqm, num_reads=1000, label="Zephyr RAN7") # doctest: +SKIP