{ "cells": [ { "cell_type": "markdown", "id": "957190c9-5e0c-46f3-9e7c-108feacae5c1", "metadata": {}, "source": [ "# SamplerV2 Sample Programs\n", "### Modified for Quantum Rings toolkit for Qiskit 2.x\n", "#### See here: https://qiskit.qotlabs.org/docs/guides/primitives-examples" ] }, { "cell_type": "code", "execution_count": 1, "id": "2385b14b-978b-477a-9caf-1cef833e8205", "metadata": {}, "outputs": [], "source": [ "#\n", "# Setup your account\n", "# You can also save your account locally using the class method QrRuntimeService.save_account(...) and\n", "# invoke the QrRuntimeService class constructor without any arguments.\n", "#\n", "import os\n", "my_token = os.environ[\"QR_TOKEN\"]\n", "my_name = os.environ[\"QR_ACCOUNT\"]\n", "\n", "#\n", "# Set the backend of your choice, depending upon the task and your hardware configuration.\n", "# See SDK documentation for additional help.\n", "#\n", "\n", "my_backend = \"scarlet_quantum_rings\"" ] }, { "cell_type": "markdown", "id": "f9d8418e-c920-4103-a483-7b27f48fb161", "metadata": {}, "source": [ "## Run a single experiment" ] }, { "cell_type": "code", "execution_count": 2, "id": "4b6b2d6f-65af-41be-a53f-f145e4859804", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['scarlet_quantum_rings']\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\vkasi\\AppData\\Local\\Temp\\ipykernel_47772\\881852986.py:24: DeprecationWarning: The class ``qiskit.circuit.library.iqp.IQP`` is deprecated as of Qiskit 2.1. It will be removed in Qiskit 3.0. Use the qiskit.circuit.library.iqp function instead.\n", " circuit = IQP(mat)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " > First ten results: ['000000000000', '000000000001', '010000001001', '000000000001', '000000000001', '000001001001', '000000000001', '000010101000', '110000000001', '010010100001']\n" ] } ], "source": [ "import numpy as np\n", "from qiskit.circuit.library import IQP\n", "from qiskit.quantum_info import random_hermitian\n", "#from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", " \n", "#service = QiskitRuntimeService()\n", " \n", "#backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)\n", "\n", "from quantumrings.toolkit.qiskit import QrRuntimeService\n", "from quantumrings.toolkit.qiskit import QrSamplerV2 as Sampler\n", "\n", "service = QrRuntimeService( token = my_token, name = my_name)\n", "avaiable_backends = service.backends()\n", "print(avaiable_backends)\n", "#backend = service.least_busy(operational=True, simulator=False)\n", "\n", "n_qubits = 12#7\n", "\n", "backend = service.backend(name = my_backend, precision = \"single\", gpu = 0, num_qubits = n_qubits)\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 = backend)\n", "job = sampler.run([isa_circuit])\n", "result = job.result()\n", "\n", "pub_result = result[0]\n", " \n", "print(f\" > First ten results: {pub_result.data.meas.get_bitstrings()[:10]}\")" ] }, { "cell_type": "markdown", "id": "cf6d3a44-7edf-4454-a7fc-40c8b95cec70", "metadata": {}, "source": [ "## Run multiple experiments in a single job" ] }, { "cell_type": "code", "execution_count": 3, "id": "42d62027-d226-4d0d-a18c-4a3c5dcdd116", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BitArray()\n" ] } ], "source": [ "print(pub_result.data.meas)" ] }, { "cell_type": "code", "execution_count": 4, "id": "725365f7-0a93-4a97-ba53-84e2cfa7113d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['scarlet_quantum_rings']\n", " > First ten results for pub 0: ['000000000000', '000000000010', '111000000010', '101000100000', '100100100000', '110000000000', '000000000000', '010000000010', '100000000000', '000000000000']\n", " > First ten results for pub 1: ['100100000010', '011000010010', '001000000000', '001000000100', '001000000000', '101000000000', '000000000010', '010000000000', '001000010000', '000000000110']\n", " > First ten results for pub 2: ['000000000010', '000000000000', '010000000010', '000000000010', '000000000010', '000000000010', '000000000000', '000000100000', '100000000010', '000000100000']\n" ] } ], "source": [ "import numpy as np\n", "from qiskit.circuit.library import iqp\n", "from qiskit.transpiler 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", "from quantumrings.toolkit.qiskit import QrRuntimeService\n", "from quantumrings.toolkit.qiskit import QrSamplerV2 as Sampler\n", "\n", "n_qubits = 12 #7\n", " \n", "#service = QiskitRuntimeService()\n", "#backend = service.least_busy(\n", "# operational=True, simulator=False, min_num_qubits=n_qubits\n", "#)\n", "\n", "service = QrRuntimeService( token = my_token, name = my_name)\n", "avaiable_backends = service.backends()\n", "print(avaiable_backends)\n", "\n", "backend = service.backend(name = my_backend, precision = \"single\", gpu = 0, num_qubits = n_qubits)\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 = 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": "5b3508fc-1084-4d58-9a2f-9c80ed5d87da", "metadata": {}, "source": [ "## Run parameterized circuits" ] }, { "cell_type": "code", "execution_count": 5, "id": "858a83eb-8555-4d11-bf27-031e44f37c22", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " >> First ten results for the meas output register: ['101000100111', '000100000101', '101000000111', '110100100011', '110001101101', '010100101111', '000000011111', '100101000011', '001100100101', '110011000011']\n" ] } ], "source": [ "import numpy as np\n", "from qiskit.circuit.library import real_amplitudes\n", "from qiskit.transpiler import generate_preset_pass_manager\n", "#from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", "\n", "\n", "from quantumrings.toolkit.qiskit import QrRuntimeService\n", "from quantumrings.toolkit.qiskit import QrSamplerV2 as Sampler\n", "\n", "n_qubits = 12#7\n", " \n", "#service = QiskitRuntimeService()\n", "#backend = service.least_busy(\n", "# operational=True, simulator=False, min_num_qubits=n_qubits\n", "#)\n", "\n", "service = QrRuntimeService( token = my_token, name = my_name)\n", "backend = service.backend(name = my_backend, precision = \"single\", gpu = 0, num_qubits = n_qubits)\n", "\n", "# Step 1: Map classical inputs to a quantum problem\n", "circuit = real_amplitudes(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 = backend)\n", "\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": "da01fc67-9d48-463d-afdf-e4b3449145cf", "metadata": {}, "source": [ "## Use sessions and advanced options" ] }, { "cell_type": "code", "execution_count": 6, "id": "5926ba70-4ec4-4187-9545-02ba95ace58a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " > The first ten measurement results of job 1: ['000110101001', '000000000001', '000100100000', '000000100000', '000101000001', '000000000000', '000000000001', '000000000001', '010000100000', '100010001001']\n", " > The first ten measurement results of job 2: ['011011010110', '010001010011', '000110000001', '000010010010', '000011000000', '011000000110', '001000000100', '000110010001', '000111000101', '010100001010']\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 import generate_preset_pass_manager\n", "#from qiskit_ibm_runtime import Session, SamplerV2 as Sampler\n", "#from qiskit_ibm_runtime import QiskitRuntimeService\n", "\n", "from quantumrings.toolkit.qiskit import QrRuntimeService\n", "from quantumrings.toolkit.qiskit import QrSamplerV2 as Sampler\n", "from quantumrings.toolkit.qiskit import QrSession as Session\n", "\n", "n_qubits = 12 #7\n", " \n", "#service = QiskitRuntimeService()\n", "#backend = service.least_busy(\n", "# operational=True, simulator=False, min_num_qubits=n_qubits\n", "#)\n", "\n", "service = QrRuntimeService( token = my_token, name = my_name)\n", "backend = service.backend(name = my_backend, precision = \"single\", gpu = 0, 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", ")\n", "\n", "# 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": "0e27cd46-6306-45ec-8557-c38869664131", "metadata": {}, "source": [ "## Multiple Classical Register Usage" ] }, { "cell_type": "code", "execution_count": 7, "id": "41d52ab9-1211-499c-b1e0-d5cc84191085", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'10': 152, '00': 104}\n", "['10', '00', '10', '10', '10', '10', '10', '10', '00', '10', '10', '00', '00', '00', '10', '00', '00', '10', '10', '10', '10', '10', '00', '10', '10', '00', '10', '00', '00', '00', '00', '00', '10', '00', '10', '00', '10', '10', '10', '10', '10', '10', '00', '00', '10', '10', '10', '00', '00', '00', '00', '00', '00', '10', '00', '10', '00', '00', '10', '10', '00', '10', '00', '10', '00', '00', '10', '00', '00', '00', '10', '10', '00', '10', '00', '00', '10', '00', '00', '00', '10', '00', '10', '00', '10', '10', '00', '00', '10', '10', '00', '00', '00', '00', '00', '10', '00', '10', '10', '00', '10', '00', '00', '10', '10', '10', '10', '10', '10', '10', '10', '10', '00', '10', '10', '00', '10', '00', '00', '10', '10', '10', '10', '00', '10', '10', '10', '10', '10', '10', '00', '00', '10', '10', '10', '00', '00', '10', '10', '00', '10', '10', '10', '10', '10', '10', '00', '00', '10', '00', '10', '10', '10', '10', '10', '10', '00', '10', '10', '00', '00', '10', '00', '00', '00', '00', '00', '10', '00', '10', '10', '10', '10', '10', '10', '00', '10', '10', '00', '10', '10', '10', '00', '00', '10', '10', '10', '00', '10', '10', '10', '00', '10', '10', '10', '10', '10', '10', '10', '00', '10', '00', '10', '10', '00', '00', '10', '10', '10', '10', '00', '00', '00', '10', '00', '10', '10', '10', '10', '10', '00', '10', '10', '00', '00', '00', '10', '00', '10', '10', '10', '10', '00', '10', '10', '10', '10', '10', '00', '10', '10', '10', '10', '00', '00', '00', '00', '00', '00', '00', '10', '10', '10', '10', '10', '00']\n", "{'0': 256}\n", "['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']\n" ] } ], "source": [ "from qiskit.circuit import (\n", " Parameter, QuantumCircuit, ClassicalRegister, QuantumRegister\n", ")\n", "\n", "#from qiskit.primitives import StatevectorSampler\n", "#from quantumrings.toolkit.qiskit import QrStatevectorSampler\n", "from quantumrings.toolkit.qiskit import QrRuntimeService\n", "from quantumrings.toolkit.qiskit import QrSamplerV2\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "# Acquire Quantum Rings backend\n", "qr_services = QrRuntimeService(name = my_name, token = my_token)\n", "qr_backend = qr_services.backend(name = my_backend, precision = \"single\")\n", "\n", "# Define our circuit registers, including classical registers\n", "# called 'alpha' and 'beta'.\n", "qreg = QuantumRegister(3)\n", "alpha = ClassicalRegister(2, \"alpha\")\n", "beta = ClassicalRegister(1, \"beta\")\n", " \n", "# Define a quantum circuit with two parameters.\n", "circuit = QuantumCircuit(qreg, alpha, beta)\n", "circuit.h(0)\n", "circuit.cx(0, 1)\n", "circuit.cx(1, 2)\n", "circuit.ry(Parameter(\"a\"), 0)\n", "circuit.rz(Parameter(\"b\"), 0)\n", "circuit.cx(1, 2)\n", "circuit.cx(0, 1)\n", "circuit.h(0)\n", "circuit.measure([0, 1], alpha)\n", "circuit.measure([2], beta)\n", "\n", "number_of_params = 100\n", "\n", "# Define a sweep over parameter values, where the second axis is over.\n", "# the two parameters in the circuit.\n", "params = np.vstack([\n", " np.linspace(-np.pi, np.pi, number_of_params),\n", " np.linspace(-4 * np.pi, 4 * np.pi, number_of_params)\n", "]).T\n", " \n", "# Instantiate a new statevector simulation based sampler object.\n", "#sampler = QrStatevectorSampler(backend = qr_backend)\n", "sampler = QrSamplerV2(backend = qr_backend)\n", " \n", "# Start a job that will return shots for all 100 parameter value sets.\n", "pub = (circuit, params)\n", "job = sampler.run([pub], shots=256)\n", " \n", "# Extract the result for the 0th pub (this example only has one pub).\n", "result = job.result()[0]\n", " \n", "# There is one BitArray object for each ClassicalRegister in the\n", "# circuit. Here, we can see that the BitArray for alpha contains data\n", "# for all 100 sweep points, and that it is indeed storing data for 2\n", "# bits over 256 shots.\n", "\n", "\n", "assert result.data.alpha.shape == (number_of_params,)\n", "assert result.data.alpha.num_bits == 2\n", "assert result.data.alpha.num_shots == 256\n", " \n", "# We can work directly with a binary array in performant applications.\n", "raw = result.data.alpha.array\n", " \n", "# For small registers where it is anticipated to have many counts\n", "# associated with the same bitstrings, we can turn the data from,\n", "# for example, the 22nd sweep index into a dictionary of counts.\n", "counts = result.data.alpha.get_counts(22)\n", "print(counts)\n", "\n", "# Or, convert into a list of bitstrings that preserve shot order.\n", "bitstrings = result.data.alpha.get_bitstrings(22)\n", "print(bitstrings)\n", "\n", "assert result.data.beta.num_bits == 1\n", "assert result.data.beta.num_shots == 256\n", " \n", "# We can work directly with a binary array in performant applications.\n", "raw = result.data.beta.array\n", " \n", "# For small registers where it is anticipated to have many counts\n", "# associated with the same bitstrings, we can turn the data from,\n", "# for example, the 22nd sweep index into a dictionary of counts.\n", "counts = result.data.beta.get_counts(23)\n", "print(counts)\n", "\n", "# Or, convert into a list of bitstrings that preserve shot order.\n", "bitstrings = result.data.beta.get_bitstrings(99)\n", "print(bitstrings)" ] }, { "cell_type": "code", "execution_count": null, "id": "5f545875-ff2d-4068-9b34-63ea0e93a3a5", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.12.9" } }, "nbformat": 4, "nbformat_minor": 5 }