From 5573013be5aaf7dd87f1331429ab2dcf2acc42a7 Mon Sep 17 00:00:00 2001 From: abbycross Date: Wed, 4 Dec 2024 16:35:15 -0500 Subject: [PATCH] Create primitives-examples.ipynb (mdx -> ipynb) (#2423) Subissue of #2094 --- docs/guides/primitives-examples.ipynb | 655 ++++++++++++++++++++++++++ docs/guides/primitives-examples.mdx | 444 ----------------- scripts/config/notebook-testing.toml | 5 +- 3 files changed, 658 insertions(+), 446 deletions(-) create mode 100644 docs/guides/primitives-examples.ipynb delete mode 100644 docs/guides/primitives-examples.mdx diff --git a/docs/guides/primitives-examples.ipynb b/docs/guides/primitives-examples.ipynb new file mode 100644 index 00000000000..20bb3682e2f --- /dev/null +++ b/docs/guides/primitives-examples.ipynb @@ -0,0 +1,655 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "915d2c66-aed3-47f1-a405-144348514dd3", + "metadata": {}, + "source": [ + "# Primitives examples\n", + "\n", + "The examples in this section illustrate some common ways to use primitives. Before running these examples, follow the instructions in [Install and set up.](install-qiskit)\n", + "\n", + "\n", + " These examples all use the primitives from Qiskit Runtime, but you could use the base primitives instead.\n", + "\n", + "\n", + "## Estimator examples\n", + "\n", + "Efficiently calculate and interpret expectation values of the quantum operators required for many algorithms with Estimator. Explore uses in molecular modeling, machine learning, and complex optimization problems.\n", + "\n", + "### Run a single experiment\n", + "\n", + "Use Estimator to determine the expectation value of a single circuit-observable pair." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "88d9d34b-2903-48b9-8f3c-398da05b487b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > Expectation value: 0.6071428571428571\n", + " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import IQP\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n", + "\n", + "n_qubits = 50\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "mat = np.real(random_hermitian(n_qubits, seed=1234))\n", + "circuit = IQP(mat)\n", + "observable = SparsePauliOp(\"Z\" * 50)\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "isa_observable = observable.apply_layout(isa_circuit.layout)\n", + "\n", + "estimator = Estimator(backend)\n", + "job = estimator.run([(isa_circuit, isa_observable)])\n", + "result = job.result()\n", + "\n", + "print(f\" > Expectation value: {result[0].data.evs}\")\n", + "print(f\" > Metadata: {result[0].metadata}\")" + ] + }, + { + "cell_type": "markdown", + "id": "191eb3ee-b0d7-4710-90d6-1839ab51719e", + "metadata": {}, + "source": [ + "### Run multiple experiments in a single job\n", + "\n", + "Use Estimator to determine the expectation values of multiple circuit-observable pairs." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6bd60dea-dde5-48a6-9b35-7d90a48692a1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>> Expectation values for PUB 0: 0.1588235294117647\n", + ">>> Standard errors for PUB 0: 0.18372570722417006\n", + ">>> Expectation values for PUB 1: -0.2426470588235294\n", + ">>> Standard errors for PUB 1: 0.24287181286582873\n", + ">>> Expectation values for PUB 2: 0.01220703125\n", + ">>> Standard errors for PUB 2: 0.015620946358330926\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import IQP\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n", + "\n", + "n_qubits = 50\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng()\n", + "mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]\n", + "\n", + "pubs = []\n", + "circuits = [IQP(mat) for mat in mats]\n", + "observables = [\n", + " SparsePauliOp(\"X\" * 50),\n", + " SparsePauliOp(\"Y\" * 50),\n", + " SparsePauliOp(\"Z\" * 50),\n", + "]\n", + "\n", + "# Get ISA circuits\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "\n", + "for qc, obs in zip(circuits, observables):\n", + " isa_circuit = pm.run(qc)\n", + " isa_obs = obs.apply_layout(isa_circuit.layout)\n", + " pubs.append((isa_circuit, isa_obs))\n", + "\n", + "estimator = Estimator(backend)\n", + "job = estimator.run(pubs)\n", + "job_result = job.result()\n", + "\n", + "for idx in range(len(pubs)):\n", + " pub_result = job_result[idx]\n", + " print(f\">>> Expectation values for PUB {idx}: {pub_result.data.evs}\")\n", + " print(f\">>> Standard errors for PUB {idx}: {pub_result.data.stds}\")" + ] + }, + { + "cell_type": "markdown", + "id": "36995a0d-a912-4a55-8ed5-20525d248237", + "metadata": {}, + "source": [ + "### Run parameterized circuits\n", + "\n", + "Use Estimator to run three experiments in a single job, leveraging parameter values to increase circuit reusability." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "c80000d6-b8fe-419c-9d4c-874190b9b8b7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>> Expectation values: [[ 1.07062932e+00 1.01475593e+00 8.60450256e-01 6.10803180e-01\n", + " 3.38093469e-01 6.89501449e-03 -3.48554870e-01 -6.15796122e-01\n", + " -8.53079724e-01 -1.00477004e+00 -1.05826584e+00 -1.00619660e+00\n", + " -8.46184709e-01 -6.17698195e-01 -3.19786017e-01 7.13277361e-04\n", + " 3.17883944e-01 6.12229735e-01 8.73289249e-01 1.00976298e+00\n", + " 1.06967828e+00]\n", + " [-2.37759120e-03 3.27156550e-01 6.05572479e-01 8.58310424e-01\n", + " 1.00786091e+00 1.06397206e+00 1.00857419e+00 8.48324541e-01\n", + " 6.15796122e-01 3.00527528e-01 -4.27966417e-03 -3.38331228e-01\n", + " -6.31963742e-01 -8.48324541e-01 -1.01118954e+00 -1.06492310e+00\n", + " -1.01166506e+00 -8.38100899e-01 -6.20313545e-01 -3.13366521e-01\n", + " 1.16501969e-02]\n", + " [ 3.09086856e-03 -3.46890557e-01 -6.16271640e-01 -8.30254848e-01\n", + " -9.83371722e-01 -1.03924511e+00 -9.95021918e-01 -8.55457315e-01\n", + " -6.17698195e-01 -3.36191396e-01 4.27966417e-03 3.38093469e-01\n", + " 6.16984917e-01 8.49751096e-01 9.97637269e-01 1.05018203e+00\n", + " 9.89791218e-01 8.47611264e-01 6.05572479e-01 3.31911732e-01\n", + " 1.18879560e-03]\n", + " [ 1.04114719e+00 9.88602422e-01 8.46660227e-01 5.99866260e-01\n", + " 3.06471506e-01 5.23070065e-03 -3.28820863e-01 -6.12229735e-01\n", + " -8.48324541e-01 -9.93833123e-01 -1.03734304e+00 -9.85511554e-01\n", + " -8.35961067e-01 -6.04383684e-01 -3.10275652e-01 2.13983208e-03\n", + " 3.23590163e-01 6.31250464e-01 8.56408351e-01 9.90266736e-01\n", + " 1.04304926e+00]]\n", + ">>> Standard errors: [[0.01618801 0.01557867 0.01491518 0.01370722 0.01337878 0.01249059\n", + " 0.01141063 0.0111626 0.01458212 0.0156359 0.01588 0.01579145\n", + " 0.01455629 0.01483223 0.01001128 0.01614264 0.01159208 0.01426855\n", + " 0.0152322 0.01567182 0.01587757]\n", + " [0.01129517 0.01357565 0.01338229 0.01454656 0.01611228 0.01598502\n", + " 0.01573616 0.01478864 0.01344596 0.01329732 0.01558355 0.01126794\n", + " 0.01224176 0.01484968 0.01561156 0.01624819 0.01585894 0.01505573\n", + " 0.01317252 0.01108891 0.01241243]\n", + " [0.01479991 0.01189969 0.01326872 0.01486499 0.01494948 0.01614659\n", + " 0.01540324 0.01469609 0.01307825 0.01206431 0.01196838 0.0133195\n", + " 0.01544036 0.0147458 0.01584793 0.01578135 0.0153219 0.0143233\n", + " 0.01273291 0.01443303 0.01167013]\n", + " [0.01597196 0.01554472 0.01573553 0.01379349 0.01399025 0.01106787\n", + " 0.01230993 0.01386263 0.01509509 0.0152047 0.01554593 0.01538218\n", + " 0.0138946 0.01399345 0.01167651 0.01102312 0.01145894 0.01197292\n", + " 0.0139742 0.01592061 0.0160792 ]]\n", + ">>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "from qiskit.circuit import QuantumCircuit, Parameter\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(operational=True, simulator=False)\n", + "\n", + "# Step 1: Map classical inputs to a quantum problem\n", + "theta = Parameter(\"θ\")\n", + "\n", + "chsh_circuit = QuantumCircuit(2)\n", + "chsh_circuit.h(0)\n", + "chsh_circuit.cx(0, 1)\n", + "chsh_circuit.ry(theta, 0)\n", + "\n", + "number_of_phases = 21\n", + "phases = np.linspace(0, 2 * np.pi, number_of_phases)\n", + "individual_phases = [[ph] for ph in phases]\n", + "\n", + "ZZ = SparsePauliOp.from_list([(\"ZZ\", 1)])\n", + "ZX = SparsePauliOp.from_list([(\"ZX\", 1)])\n", + "XZ = SparsePauliOp.from_list([(\"XZ\", 1)])\n", + "XX = SparsePauliOp.from_list([(\"XX\", 1)])\n", + "ops = [ZZ, ZX, XZ, XX]\n", + "\n", + "# Step 2: Optimize problem for quantum execution.\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "chsh_isa_circuit = pm.run(chsh_circuit)\n", + "isa_observables = [\n", + " operator.apply_layout(chsh_isa_circuit.layout) for operator in ops\n", + "]\n", + "\n", + "# Step 3: Execute using Qiskit primitives.\n", + "\n", + "# Reshape observable array for broadcasting\n", + "reshaped_ops = np.fromiter(isa_observables, dtype=object)\n", + "reshaped_ops = reshaped_ops.reshape((4, 1))\n", + "\n", + "estimator = Estimator(backend, options={\"default_shots\": int(1e4)})\n", + "job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)])\n", + "# Get results for the first (and only) PUB\n", + "pub_result = job.result()[0]\n", + "print(f\">>> Expectation values: {pub_result.data.evs}\")\n", + "print(f\">>> Standard errors: {pub_result.data.stds}\")\n", + "print(f\">>> Metadata: {pub_result.metadata}\")" + ] + }, + { + "cell_type": "markdown", + "id": "c7978aa5-da67-4f93-927d-277802ae5437", + "metadata": {}, + "source": [ + "### Use sessions and advanced options\n", + "\n", + "Explore sessions and advanced options to optimize circuit performance on QPUs." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "cbe2bed7-e5c1-4264-ac42-1c267ff1af3b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > Expectation value: 0.01123046875\n", + " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n", + " > Another Expectation value: -0.34210526315789475\n", + " > More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import IQP\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n", + "from qiskit_ibm_runtime import (\n", + " QiskitRuntimeService,\n", + " Session,\n", + " EstimatorV2 as Estimator,\n", + ")\n", + "\n", + "n_qubits = 50\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng(1234)\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "circuit = IQP(mat)\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "another_circuit = IQP(mat)\n", + "observable = SparsePauliOp(\"X\" * 50)\n", + "another_observable = SparsePauliOp(\"Y\" * 50)\n", + "\n", + "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n", + "isa_circuit = pm.run(circuit)\n", + "another_isa_circuit = pm.run(another_circuit)\n", + "isa_observable = observable.apply_layout(isa_circuit.layout)\n", + "another_isa_observable = another_observable.apply_layout(\n", + " another_isa_circuit.layout\n", + ")\n", + "\n", + "with Session(backend=backend) as session:\n", + " estimator = Estimator(mode=session)\n", + "\n", + " estimator.options.resilience_level = 1\n", + "\n", + " job = estimator.run([(isa_circuit, isa_observable)])\n", + " another_job = estimator.run(\n", + " [(another_isa_circuit, another_isa_observable)]\n", + " )\n", + " result = job.result()\n", + " another_result = another_job.result()\n", + "\n", + " # first job\n", + " print(f\" > Expectation value: {result[0].data.evs}\")\n", + " print(f\" > Metadata: {result[0].metadata}\")\n", + "\n", + " # second job\n", + " print(f\" > Another Expectation value: {another_result[0].data.evs}\")\n", + " print(f\" > More Metadata: {another_result[0].metadata}\")" + ] + }, + { + "cell_type": "markdown", + "id": "3a60b53b-418a-44fe-92d2-b1ba5d967c84", + "metadata": {}, + "source": [ + "\n", + "## Sampler examples\n", + "\n", + "Generate entire error-mitigated quasi-probability distributions sampled from quantum circuit outputs. Leverage Sampler’s capabilities for search and classification algorithms like Grover’s and QVSM.\n", + "\n", + "### Run a single experiment\n", + "\n", + "Use Sampler to return the measurement outcome as bitstrings or counts of a single circuit." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "012cfeea-3af3-46bb-9e64-15bb052bbcd2", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > First ten results: ['1010001101100000111001101101101001000000001011111000010011000100011001100000000000000110010011000000100010110010001010010000100', '0111010100100001100010011100100001101001001100100001000111000100000000000110110100011110010011010001000111011100001000110100100', '1110111010010010000000100100001100010110000010011000100000000101001000001000000001010010011011001001100000010011001000010100101', '1000011111010011100111001101001000000110001001100000100010000000011000000100001000001110001010000001001111011001001100000100000', '1011001110111111010101010000010100100000001101010100010001000010000001000010001100000110011000000100100111111000001000010000000', '1010110010100110101010001101110001001001001101110001100000000110010010011000011010010100001010000000100110101110001000000000001', '0101011010001111000000110101000100000100001011100001010111001100000100000110000000110000010011000001000101110001000001100100010', '1110000100110001000000111100100010011011001011111001010001100110000001000011010010010010011000100010000101001000001000100000101', '0011111011010100001000000001111110010101000101110000110011000110000001001100010010110000010010000001101100010100000000100000010', '1010111101000001100011011000000001100001001110010000010010000010011100100111100001001100010100101001100010000010001000000100011']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import IQP\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit.quantum_info import random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "mat = np.real(random_hermitian(n_qubits, seed=1234))\n", + "circuit = IQP(mat)\n", + "circuit.measure_all()\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "\n", + "sampler = Sampler(backend)\n", + "job = sampler.run([isa_circuit])\n", + "result = job.result()\n", + "\n", + "# Get results for the first (and only) PUB\n", + "pub_result = result[0]\n", + "\n", + "print(f\" > First ten results: {pub_result.data.meas.get_bitstrings()[:10]}\")" + ] + }, + { + "cell_type": "markdown", + "id": "a5c3d65c-9d14-4b4e-800c-6e3e231e335c", + "metadata": {}, + "source": [ + "### Run multiple experiments in a single job\n", + "\n", + "Use Sampler to return the measurement outcome as bitstrings or counts of multiple circuits in one job." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b5372b7e-8bc2-4f2e-8f65-03dcd368faeb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > First ten results for pub 0: ['0000110100100000111101101000100111000101000010010110100010110100000001100000011010100000001101101000101110100101100000101010000', '1100011010111110001110110001001100101011011101100001100000110100010011000010011000001001000000101000001010001101000000100000000', '0111001110000001000101110111001101100100101110010001000010000010100000010010110010110000100000001001100001000101010100001100000', '0111110001100101100010110110000000011010001011000101000010111000000001010000010000010000101000111000101000000000110000001100000', '1011110011100000111110000000011110111111100101000110001000010010101001000100010011011010000000111000010111000101110000101000000', '1011011010100110000000100000100000101011011010101100100010100001100011101100110000110000010000111000010101001100000000001100100', '1101001000010000011100100000000111111110010000010000100101111000101000010010010010001001000000011000100111000000010000000110000', '0110100001100111000110111100001101110010000110000101011010000001100000010001110010010000100000100000000000100000010001110100000', '0111100000010100100011010100101110100001100111110001001100001000000010100100010010000001001001110000001011000101100100001100010', '1111110010111100001110110110000000111111111000110110101111110100000001000011011010000000101000110001000110001001110000101000000']\n", + " > First ten results for pub 1: ['1011000101100000110000110010111001101110101001010111000000000000000110010000100100001001010001101001000110000010000000000100010', '1111010101001110110110000001010011000000100010110101001010010010100000000001100100011010010101101100101010000000010001010101100', '0000111101110110011111000000000100000001100100110001000000010010000011000100000100100100100111001100001010100001000100010110100', '1010101011111100110100110000000010101001000000110101000001000011100010010000100110001100100011000000101011000000010000010001110', '0111011010110100100011010011001010010001000101010001000101001011010100000001000000100010000100100000100010000000000000010000010', '0001011110100000001000100000101000000111000000110010001001001000000011100101000101001101100010101000100011000000100000110000000', '1100001001010010001000000001001100000110110001110110001000010001100000000001000000101100000010100101101110000001000101010100010', '0101001101110010010110000000101001111011000100010000001101101101000010000101010111000110000000100011110010000001010000000000000', '1011010001111000110111000010101111010101001000110011101011000100000001000101000100100110110010100010001001000000000100010000000', '1101100000001011101010011010011110100000100010010111000010011000000111000100000101001101010010100100100001000000000101000110000']\n", + " > First ten results for pub 2: ['0011100000100101100010111000000011110000110000000010100010000000000100000010101100000011100111010001000010010001100110000001010', '1010010011010101111000011000001100010010001000110000001100000010000010001000100011011010111100000000010100011000000000101001010', '1111001100000100000000010000000000011010111100111100010001000010000111111010000110011000010000010000111100000000000010010000110', '0110011100110101001100000000011110000101011000111000001100010010010000001010000010000111101101010000000010000101100011110011010', '0000011100000000011000011011000100011000010100101000010000000001100000001010110011001011100110011000101000001000100010100000010', '0111110100000000101000000000010000110100110010011000010000000110100111000010100011000011111100000000001110001101000000110010010', '1110101010010100100001110000011110000010011000100100010110010000100001000010000001011100100101000000011100100101000000010010110', '1000101100010101111011010100011000000000101000001000011100000100000110000000000011010011110111010000010100010000100100111001011', '1110101011110111001101000100111000000110010000110101001000010110110101110010100010001011110100010010110010001100000111010000011', '1110011010100100101001000110100001010001010000110100000101000000010101000010100100001010110011110000100100000001000111001000110']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import IQP\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit.quantum_info import random_hermitian\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng()\n", + "mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]\n", + "circuits = [IQP(mat) for mat in mats]\n", + "for circuit in circuits:\n", + " circuit.measure_all()\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuits = pm.run(circuits)\n", + "\n", + "sampler = Sampler(backend)\n", + "job = sampler.run(isa_circuits)\n", + "result = job.result()\n", + "\n", + "for idx, pub_result in enumerate(result):\n", + " print(\n", + " f\" > First ten results for pub {idx}: {pub_result.data.meas.get_bitstrings()[:10]}\"\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "36337791-94ff-4ed5-aa26-808c470eb728", + "metadata": {}, + "source": [ + "### Run parameterized circuits\n", + "\n", + "Run several experiments in a single job, leveraging parameter values to increase circuit reusability." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ea6c113e-15db-47a1-be34-459e68d1db4e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " >> First ten results for the meas output register: ['0110111100010000101100010101001000100000100001000110000011100011111011000001101001111010100111001010010000001011110100100000111', '0110011101010001011001001000001000000000100000101110100000001011101001100010101000010011110100011000010000000000100010101100110', '1100000100010011100010000101101100100100101100011100100001101010111010000010001010011100011001000011011101011100000101100001101', '0100001100010001101000000000000111101100111001010010100001001000100000000000000011010001000100010110111111001011100000000011100', '1110110010010001100000000001000010100000101001010110011111101100101000100010010010001111111000011111000110011111100100000101110', '0100100101010000010100010010001101111100100001011100010101001010110001100100111010001000011010111100101111000001100000000010101', '0100011100010101001001010100011100000110100100010100101101111100111011110000101001000000000111100100110011001010100010110001000', '1101111110010101101000000101011010100100110001011110011011101011101011100011001101101001101111000110010011101010110000101000101', '0100010001010000111000001111001001110000101111101000101001101000000010100010000011001000001100100010101110100000101110000010111', '0101000101000011000010001100100101100100111100000000100000010011100000010010011000100001001111000100101101000101110000111011010']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import RealAmplitudes\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "# Step 1: Map classical inputs to a quantum problem\n", + "circuit = RealAmplitudes(num_qubits=n_qubits, reps=2)\n", + "circuit.measure_all()\n", + "\n", + "# Define three sets of parameters for the circuit\n", + "rng = np.random.default_rng(1234)\n", + "parameter_values = [\n", + " rng.uniform(-np.pi, np.pi, size=circuit.num_parameters) for _ in range(3)\n", + "]\n", + "\n", + "# Step 2: Optimize problem for quantum execution.\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "\n", + "# Step 3: Execute using Qiskit primitives.\n", + "sampler = Sampler(backend)\n", + "job = sampler.run([(isa_circuit, parameter_values)])\n", + "result = job.result()\n", + "# Get results for the first (and only) PUB\n", + "pub_result = result[0]\n", + "# Get counts from the classical register \"meas\".\n", + "print(\n", + " f\" >> First ten results for the meas output register: {pub_result.data.meas.get_bitstrings()[:10]}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "1f144ac9-5f64-4aca-8cc4-8cf9362c5666", + "metadata": {}, + "source": [ + "### Use sessions and advanced options\n", + "\n", + "Explore sessions and advanced options to optimize circuit performance on QPUs." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d6248dcb-2ba9-4a06-a9ef-727db7092093", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > The first ten measurement results of job 1: ['1111001011111011001010101010000110000110101010110111000100011100000111000000010010000101000000101001010011110001100111100101001', '0011011111100010111011000000101000000000011010010111000001001100101111000000000001001101000100001111010010000001100000101001100', '0010101011011100000010000000000110010000100011100101001001001010110001110000110000110001110011101100010001100100110010001101010', '0110000011000000100011101001011001000001000011000110010101000010110110110100100111000011100100101101110010101001111000101100100', '1001011110110000100111000100000101000010100011110110000100000111110111000100100001000011000101100111010011010000110000000100000', '1000111011011110110110101011000100011011110010011101000100000001000011100100110010001000011100100111010011100100111010100001110', '1111110010110000111001001001001010111000100000010101000000000110100101000000111110100111100000001101110001010001110011111001010', '1010101111000111110110010110001101010011100000000101110001001001111001100100010000111000100101000010000001110000100011100101110', '1100101011111011011010110010011000000011110000000110100100000000001001100000001001111000110000001000110010000000000000000011100', '0111101101000001100100001010000100110001100000111100011101000011001000100001100010100100110100001100100010010011110001001101110']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from qiskit.circuit.library import IQP\n", + "from qiskit.quantum_info import random_hermitian\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "from qiskit_ibm_runtime import Session, SamplerV2 as Sampler\n", + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "\n", + "n_qubits = 127\n", + "\n", + "service = QiskitRuntimeService()\n", + "backend = service.least_busy(\n", + " operational=True, simulator=False, min_num_qubits=n_qubits\n", + ")\n", + "\n", + "rng = np.random.default_rng(1234)\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "circuit = IQP(mat)\n", + "circuit.measure_all()\n", + "mat = np.real(random_hermitian(n_qubits, seed=rng))\n", + "another_circuit = IQP(mat)\n", + "another_circuit.measure_all()\n", + "\n", + "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", + "isa_circuit = pm.run(circuit)\n", + "another_isa_circuit = pm.run(another_circuit)\n", + "\n", + "with Session(backend=backend) as session:\n", + " sampler = Sampler(mode=session)\n", + " job = sampler.run([isa_circuit])\n", + " another_job = sampler.run([another_isa_circuit])\n", + " result = job.result()\n", + " another_result = another_job.result()\n", + "\n", + "# first job\n", + "\n", + "print(\n", + " f\" > The first ten measurement results of job 1: {result[0].data.meas.get_bitstrings()[:10]}\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "e81eb3e4-632a-49da-a926-6e79f8640867", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " > The first ten measurement results of job 2: ['1000110010100001110100000101101100000001010010000000000101101101100001000100001001000010111010101010000001010010000010000011010', '0011001000101001101111011101000101001000010010000001000000101000100001001100001000110000110010001001110010110111000010001110111', '0100011100000101110000001001001010000100111000010010100010010101000010000001000001001010100000001001110000010100000000011000001', '0001101001001001110010100111001110011000011010001001000101100100100001000000000001000010100010001000010000100100101010000000101', '1111001110011011010001010010001010000001001010010011010111001011100001011000000000110010100010101001010110001000001000000010101', '0011100011000010010001001000001110111101010100000001100000100111000000010000000000000000010010101101010010011000001110000000011', '0011010001111011110010100110011011010100011000010011011001000100000001000000001010000100100010000010110001000110001000110110001', '0101100010000010011010001000010000000110101010011011100011001111100010100100000001110100100000101000010011011100000010010011000', '0010101011000000100010001001000000100001000110100010001111001100000111000100000011000001110010100001010000011110001010010001001', '0001011100110000110111000011000000101001001010110011101001101001100001001000101011100000100010001000110000010110101100010011111']\n" + ] + } + ], + "source": [ + "# second job\n", + "print(\n", + " \" > The first ten measurement results of job 2:\",\n", + " another_result[0].data.meas.get_bitstrings()[:10],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9484b7b7-e474-4291-b3ee-ace64f7cf126", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "\n", + " - [Specify advanced runtime options.](runtime-options-overview)\n", + " - Practice with primitives by working through the [Cost function lesson](https://learning.quantum.ibm.com/course/variational-algorithm-design/cost-functions#primitives) in IBM Quantum Learning.\n", + " - Learn how to transpile locally in the [Transpile](./transpile/) section.\n", + " - Try the [Submit pre-transpiled circuits](https://learning.quantum.ibm.com/tutorial/submitting-user-transpiled-circuits-using-primitives) tutorial.\n", + " - Read [Migrate to V2 primitives](/migration-guides/v2-primitives).\n", + " - Understand the [Job limits](/guides/job-limits) when sending a job to an IBM® QPU.\n", + "" + ] + } + ], + "metadata": { + "description": "Practical examples of using primitives in Qiskit Runtime.", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3" + }, + "title": "Primitives examples" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/guides/primitives-examples.mdx b/docs/guides/primitives-examples.mdx deleted file mode 100644 index 2d6487196a7..00000000000 --- a/docs/guides/primitives-examples.mdx +++ /dev/null @@ -1,444 +0,0 @@ ---- -title: Primitives examples -description: Practical examples of using primitives in Qiskit Runtime. - ---- - -# Primitives examples - -The examples in this section illustrate some common ways to use primitives. Before running these examples, follow the instructions in [Install and set up.](install-qiskit) - - - These examples all use the primitives from Qiskit Runtime, but you could use the base primitives instead. - - -## Estimator examples - -Efficiently calculate and interpret expectation values of the quantum operators required for many algorithms with Estimator. Explore uses in molecular modeling, machine learning, and complex optimization problems. - -### Run a single experiment - -Use Estimator to determine the expectation value of a single circuit-observable pair. - -```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit.quantum_info import SparsePauliOp, random_hermitian -from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -mat = np.real(random_hermitian(n_qubits, seed=1234)) -circuit = IQP(mat) -observable = SparsePauliOp("Z" * n_qubits) - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuit = pm.run(circuit) -isa_observable = observable.apply_layout(isa_circuit.layout) - -estimator = Estimator(backend) -job = estimator.run([(isa_circuit, isa_observable)]) -result = job.result() - -print(f" > Expectation value: {result[0].data.evs}") -print(f" > Metadata: {result[0].metadata}") -``` -Output: -```text - > Expectation value: 0.123046875 - > Metadata: {'target_precision': 0.015625} -``` - -### Run multiple experiments in a single job - -Use Estimator to determine the expectation values of multiple circuit-observable pairs. - -```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit.quantum_info import SparsePauliOp, random_hermitian -from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -rng = np.random.default_rng() -mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)] - -pubs = [] -circuits = [IQP(mat) for mat in mats] -observables = [ - SparsePauliOp("X" * n_qubits), - SparsePauliOp("Y" * n_qubits), - SparsePauliOp("Z" * n_qubits), -] - -# Get ISA circuits -pm = generate_preset_pass_manager(optimization_level=1, backend=backend) - -for qc, obs in zip(circuits, observables): - isa_circuit = pm.run(qc) - isa_obs = obs.apply_layout(isa_circuit.layout) - pubs.append((isa_circuit, isa_obs)) - -estimator = Estimator(backend) -job = estimator.run(pubs) -job_result = job.result() - -for idx in range(len(pubs)): - pub_result = job_result[idx] - print(f">>> Expectation values for PUB {idx}: {pub_result.data.evs}") - print(f">>> Standard errors for PUB {idx}: {pub_result.data.stds}") -``` -Output: -```text ->>> Expectation values for PUB 0: -0.0263671875 ->>> Standard errors for PUB 0: 0.015619567582387688 ->>> Expectation values for PUB 1: -0.017578125 ->>> Standard errors for PUB 1: 0.015622585825382946 ->>> Expectation values for PUB 2: 0.33349609375 ->>> Standard errors for PUB 2: 0.014730491894982241 -``` - -### Run parameterized circuits - -Use Estimator to run three experiments in a single job, leveraging parameter values to increase circuit reusability. - -```python -import numpy as np - -from qiskit.circuit import QuantumCircuit, Parameter -from qiskit.quantum_info import SparsePauliOp -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False) - -# Step 1: Map classical inputs to a quantum problem -theta = Parameter("θ") - -chsh_circuit = QuantumCircuit(2) -chsh_circuit.h(0) -chsh_circuit.cx(0, 1) -chsh_circuit.ry(theta, 0) - -number_of_phases = 21 -phases = np.linspace(0, 2 * np.pi, number_of_phases) -individual_phases = [[ph] for ph in phases] - -ZZ = SparsePauliOp.from_list([("ZZ", 1)]) -ZX = SparsePauliOp.from_list([("ZX", 1)]) -XZ = SparsePauliOp.from_list([("XZ", 1)]) -XX = SparsePauliOp.from_list([("XX", 1)]) -ops = [ZZ, ZX, XZ, XX] - -# Step 2: Optimize problem for quantum execution. - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -chsh_isa_circuit = pm.run(chsh_circuit) -isa_observables = [operator.apply_layout(chsh_isa_circuit.layout) for operator in ops] - -# Step 3: Execute using Qiskit primitives. - -# Reshape observable array for broadcasting -reshaped_ops = np.fromiter(isa_observables, dtype=object) -reshaped_ops = reshaped_ops.reshape((4, 1)) - -estimator = Estimator(backend, options={"default_shots": int(1e4)}) -job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)]) -# Get results for the first (and only) PUB -pub_result = job.result()[0] -print(f">>> Expectation values: {pub_result.data.evs}") -print(f">>> Standard errors: {pub_result.data.stds}") -print(f">>> Metadata: {pub_result.metadata}") -``` - -Output - -```text ->>> Expectation values: [[ 0.88525391 0.83837891 0.70458984 0.52880859 0.29150391 -0.00146484 - -0.28271484 -0.52587891 -0.71777344 -0.83300781 -0.88916016 -0.83935547 - -0.71826172 -0.53613281 -0.24560547 -0.00830078 0.28320312 0.515625 - 0.72460938 0.83935547 0.89013672] - [-0.00390625 0.25683594 0.515625 0.71337891 0.83691406 0.87548828 - 0.83105469 0.70605469 0.54150391 0.28222656 0.01269531 -0.27636719 - -0.52539062 -0.73388672 -0.83203125 -0.88134766 -0.83984375 -0.71386719 - -0.50390625 -0.25292969 0.02001953] - [-0.01464844 -0.26660156 -0.51757812 -0.72216797 -0.83398438 -0.89013672 - -0.84472656 -0.72070312 -0.52001953 -0.26660156 0.00244141 0.26074219 - 0.51123047 0.7109375 0.83886719 0.86865234 0.86669922 0.71435547 - 0.52587891 0.27636719 -0.01025391] - [ 0.88525391 0.85986328 0.72509766 0.54101562 0.28125 0.00878906 - -0.27539062 -0.52636719 -0.71533203 -0.84130859 -0.8828125 -0.83740234 - -0.72998047 -0.51513672 -0.26171875 0.00537109 0.26660156 0.52636719 - 0.69677734 0.84521484 0.87353516]] ->>> Standard errors: [[0.00726731 0.008517 0.01108773 0.01326158 0.0149464 0.01562498 - 0.01498756 0.01328999 0.01087932 0.00864471 0.00714994 0.00849348 - 0.01087145 0.01318959 0.0151464 0.01562446 0.01498531 0.01338772 - 0.01076812 0.00849348 0.00712021] - [0.01562488 0.01510086 0.01338772 0.01094966 0.0085521 0.00755061 - 0.00869048 0.01106496 0.01313591 0.01498981 0.01562374 0.01501644 - 0.01329471 0.01061362 0.00866764 0.00738232 0.00848169 0.01094189 - 0.01349622 0.01511695 0.01562187] - [0.01562332 0.01505948 0.01336931 0.01080809 0.00862169 0.00712021 - 0.00836247 0.01083193 0.01334616 0.01505948 0.01562495 0.01508451 - 0.01342881 0.01098836 0.00850525 0.00774097 0.00779424 0.01093411 - 0.01328999 0.01501644 0.01562418] - [0.00726731 0.00797694 0.01076009 0.01314082 0.01499429 0.0156244 - 0.01502082 0.01328527 0.01091851 0.00844617 0.00733946 0.00854042 - 0.01067919 0.01339231 0.01508038 0.01562477 0.01505948 0.01328527 - 0.01120762 0.00835042 0.00760564]] ->>> Metadata: {'target_precision': 0.015625} -``` - -### Use sessions and advanced options - -Explore sessions and advanced options to optimize circuit performance on QPUs. - -```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit.quantum_info import SparsePauliOp, random_hermitian -from qiskit_ibm_runtime import QiskitRuntimeService, Session, EstimatorV2 as Estimator - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -rng = np.random.default_rng(1234) -mat = np.real(random_hermitian(n_qubits, seed=rng)) -circuit = IQP(mat) -mat = np.real(random_hermitian(n_qubits, seed=rng)) -another_circuit = IQP(mat) -observable = SparsePauliOp("X" * n_qubits) -another_observable = SparsePauliOp("Y" * n_qubits) - -pm = generate_preset_pass_manager(optimization_level=1, backend=backend) -isa_circuit = pm.run(circuit) -another_isa_circuit = pm.run(another_circuit) -isa_observable = observable.apply_layout(isa_circuit.layout) -another_isa_observable = another_observable.apply_layout(another_isa_circuit.layout) - -with Session(backend=backend) as session: - estimator = Estimator(mode=session) - - estimator.options.resilience_level = 1 - - job = estimator.run([(isa_circuit, isa_observable)]) - another_job = estimator.run([(another_isa_circuit, another_isa_observable)]) - result = job.result() - another_result = another_job.result() - - # first job - print(f" > Expectation value: {result[0].data.evs}") - print(f" > Metadata: {result[0].metadata}") - - # second job - print(f" > Another Expectation value: {another_result[0].data.evs}") - print(f" > More Metadata: {another_result[0].metadata}") -``` -Output: -```text - > Expectation value: 0.0048828125 - > Metadata: {'target_precision': 0.015625} - > Another Expectation value: -0.03857421875 - > More Metadata: {'target_precision': 0.015625} - ``` - - -## Sampler examples - -Generate entire error-mitigated quasi-probability distributions sampled from quantum circuit outputs. Leverage Sampler’s capabilities for search and classification algorithms like Grover’s and QVSM. - -### Run a single experiment - -Use Sampler to return the measurement outcome as bitstrings or counts of a single circuit. - -```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit.quantum_info import random_hermitian -from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -mat = np.real(random_hermitian(n_qubits, seed=1234)) -circuit = IQP(mat) -circuit.measure_all() - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuit = pm.run(circuit) - -sampler = Sampler(backend) -job = sampler.run([isa_circuit]) -result = job.result() - -# Get results for the first (and only) PUB -pub_result = result[0] - -print(f" > Counts: {pub_result.data.meas.get_counts()}") -``` -Output -```text - > Counts: {'0101': 103, '0100': 195, '0011': 142, '0000': 237, '1010': 26, '0001': 92, '0110': 18, '1111': 19, '0010': 36, '1100': 5, '0111': 42, '1110': 31, '1011': 27, '1101': 18, '1001': 13, '1000': 20} - ``` - -### Run multiple experiments in a single job - -Use Sampler to return the measurement outcome as bitstrings or counts of multiple circuits in one job. - -```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit.quantum_info import random_hermitian -from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -rng = np.random.default_rng() -mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)] -circuits = [IQP(mat) for mat in mats] -for circuit in circuits: - circuit.measure_all() - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuits = pm.run(circuits) - -sampler = Sampler(backend) -job = sampler.run(isa_circuits) -result = job.result() - -for idx, pub_result in enumerate(result): - print(f" > Counts for pub {idx}: {pub_result.data.meas.get_counts()}") -``` -Output -```text - > Counts for pub 0: {'0001': 120, '0000': 671, '0101': 21, '0011': 18, '0010': 91, '1001': 7, '1000': 23, '0100': 29, '1110': 2, '0110': 28, '1010': 3, '1111': 2, '1100': 4, '1011': 3, '0111': 2} - > Counts for pub 1: {'1001': 31, '1100': 122, '0100': 263, '0101': 86, '1101': 69, '1000': 96, '0001': 51, '1011': 7, '0110': 21, '0000': 163, '0011': 17, '1010': 26, '0010': 48, '1110': 13, '0111': 10, '1111': 1} - > Counts for pub 2: {'0000': 694, '0010': 78, '0100': 61, '0011': 21, '0001': 58, '0111': 6, '1000': 26, '0110': 50, '1001': 9, '1010': 3, '1100': 10, '1011': 2, '0101': 4, '1110': 1, '1111': 1} -``` - -### Run parameterized circuits - -Run several experiments in a single job, leveraging parameter values to increase circuit reusability. - -```python -import numpy as np -from qiskit.circuit.library import RealAmplitudes -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -# Step 1: Map classical inputs to a quantum problem -circuit = RealAmplitudes(num_qubits=n_qubits, reps=2) -circuit.measure_all() - -# Define three sets of parameters for the circuit -rng = np.random.default_rng(1234) -parameter_values = [ - rng.uniform(-np.pi, np.pi, size=circuit.num_parameters) for _ in range(3) -] - -# Step 2: Optimize problem for quantum execution. - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuit = pm.run(circuit) - -# Step 3: Execute using Qiskit primitives. -sampler = Sampler(backend) -job = sampler.run([(isa_circuit, parameter_values)]) -result = job.result() -# Get results for the first (and only) PUB -pub_result = result[0] -# Get counts from the classical register "meas". -print(f" >> Counts for the meas output register: {pub_result.data.meas.get_counts()}") -``` -Output -```text ->> Counts for the meas output register: {'1000': 449, '0100': 183, '0110': 475, '1110': 249, '0101': 167, '0111': 116, '1100': 227, '0011': 111, '1101': 123, '1001': 252, '1010': 229, '0001': 37, '0010': 123, '1011': 120, '1111': 156, '0000': 55} -``` - -### Use sessions and advanced options - -Explore sessions and advanced options to optimize circuit performance on QPUs. - -```python -import numpy as np -from qiskit.circuit.library import IQP -from qiskit.quantum_info import random_hermitian -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit_ibm_runtime import Session, SamplerV2 as Sampler -from qiskit_ibm_runtime import QiskitRuntimeService - -n_qubits = 127 - -service = QiskitRuntimeService() -backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) - -rng = np.random.default_rng(1234) -mat = np.real(random_hermitian(n_qubits, seed=rng)) -circuit = IQP(mat) -circuit.measure_all() -mat = np.real(random_hermitian(n_qubits, seed=rng)) -another_circuit = IQP(mat) -another_circuit.measure_all() - -pm = generate_preset_pass_manager(backend=backend, optimization_level=1) -isa_circuit = pm.run(circuit) -another_isa_circuit = pm.run(another_circuit) - -with Session(backend=backend) as session: - sampler = Sampler(mode=session) - job = sampler.run([isa_circuit]) - another_job = sampler.run([another_isa_circuit]) - result = job.result() - another_result = another_job.result() - -# first job -print(f" > Counts for job 1: {result[0].data.meas.get_counts()}") -``` -Output -```text - > Counts for job 1: {'1110': 39, '0100': 164, '0000': 274, '0010': 40, '0001': 101, '0011': 138, '1101': 20, '1010': 26, '1100': 7, '0101': 83, '0111': 43, '1011': 15, '1001': 14, '1000': 34, '0110': 12, '1111': 14} -``` -```python -# second job -print(f" > Counts for job 2: {another_result[0].data.meas.get_counts()}") -``` -Output -```text - > Counts for job 2: {'0000': 285, '0100': 128, '0111': 29, '0110': 147, '0011': 15, '0010': 277, '1110': 10, '1010': 25, '1011': 15, '1000': 32, '0001': 21, '1111': 6, '1100': 10, '1101': 5, '1001': 15, '0101': 4} -``` - -## Next steps - - - - [Specify advanced runtime options.](runtime-options-overview) - - Practice with primitives by working through the [Cost function lesson](https://learning.quantum.ibm.com/course/variational-algorithm-design/cost-functions#primitives) in IBM Quantum Learning. - - Learn how to transpile locally in the [Transpile](./transpile/) section. - - Try the [Submit pre-transpiled circuits](https://learning.quantum.ibm.com/tutorial/submitting-user-transpiled-circuits-using-primitives) tutorial. - - Read [Migrate to V2 primitives](/migration-guides/v2-primitives). - - Understand the [Job limits](/guides/job-limits) when sending a job to an IBM® QPU. - diff --git a/scripts/config/notebook-testing.toml b/scripts/config/notebook-testing.toml index a97b354d5eb..07540bb66b5 100644 --- a/scripts/config/notebook-testing.toml +++ b/scripts/config/notebook-testing.toml @@ -51,13 +51,13 @@ notebooks_exclude = [ "docs/guides/fractional-gates.ipynb", ] -# The following notebooks submit jobs that can be mocked with a simulator +# The following notebooks submit jobs that can be mocked with a 5Q simulator notebooks_that_submit_jobs = [ "docs/guides/primitive-input-output.ipynb", "docs/guides/debug-qiskit-runtime-jobs.ipynb", ] -# The following notebooks submit jobs that are too big to mock with a simulator (or use functions that aren't supported on sims) +# The following notebooks submit jobs that are too big to mock with a 5Q simulator (or use functions that aren't supported on sims) # A job is "too big" if a cell can't run in under 5 mins, or we run out of # memory on a reasonable device. notebooks_no_mock = [ @@ -65,4 +65,5 @@ notebooks_no_mock = [ "docs/guides/hello-world.ipynb", "docs/guides/noise-learning.ipynb", "docs/guides/qiskit-addons-obp-get-started.ipynb", + "docs/guides/primitives-examples.ipynb", ]