{ "cells": [ { "cell_type": "markdown", "id": "9feeb937", "metadata": {}, "source": [ "# Compiling and Submitting Circuits onto Sqorpius via Qiskit\n" ] }, { "cell_type": "markdown", "id": "decent-blowing", "metadata": {}, "source": [ "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Infleqtion/client-superstaq/blob/main/docs/source/optimizations/sqorpius/sqorpius_compile_qss.ipynb) [![Launch Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Infleqtion/client-superstaq/HEAD?labpath=docs/source/optimizations/sqorpius/sqorpius_compile_qss.ipynb)" ] }, { "cell_type": "markdown", "id": "c23a3c34", "metadata": {}, "source": [ "## Import Requirements" ] }, { "cell_type": "markdown", "id": "41137c11", "metadata": {}, "source": [ "This tutorial will showcase how to compile and submit a circuit onto Infleqtion's hardware, Sqorpius, using the ```qiskit-superstaq``` client." ] }, { "cell_type": "code", "execution_count": 1, "id": "c01de181-761d-428e-b0a2-f038d12cdb84", "metadata": {}, "outputs": [], "source": [ "# Required imports\n", "try:\n", " import qiskit\n", " import qiskit_superstaq as qss\n", "except ImportError:\n", " print(\"Installing qiskit-superstaq...\")\n", " %pip install --quiet 'qiskit-superstaq[examples]'\n", " print(\"Installed qiskit-superstaq.\")\n", " print(\"You may need to restart the kernel to import newly installed packages.\")\n", " import qiskit\n", " import qiskit_superstaq as qss\n", "\n", "# Optional imports\n", "import os # Used if setting a token as an environment variable" ] }, { "cell_type": "markdown", "id": "fdab508b", "metadata": {}, "source": [ "To interface Superstaq via Qiskit, we must first instantiate a service provider in ```qiskit-superstaq```. We then supply a Superstaq API key (which you can get from https://superstaq.infleqtion.com) by either providing the API key as an argument, i.e., ```qss.superstaq_provider.SuperstaqProvider(api_key=\"token\")```, or by setting it as an environment variable (see more details [here](https://superstaq.readthedocs.io/en/latest/get_started/basics/basics_qss.html#Set-up-access-to-Superstaq%E2%80%99s-API))." ] }, { "cell_type": "code", "execution_count": 2, "id": "b38e6a2c-36fc-426c-a6e0-3f5167900e54", "metadata": {}, "outputs": [], "source": [ "provider = qss.superstaq_provider.SuperstaqProvider()" ] }, { "cell_type": "markdown", "id": "72d7ac85-84b4-4feb-8ecf-0af31ddf5f83", "metadata": { "tags": [] }, "source": [ "## Create a Circuit" ] }, { "cell_type": "markdown", "id": "3eb32f10", "metadata": {}, "source": [ "First, we will create an example Qiskit circuit that we can then compile and submit onto Sqorpius" ] }, { "cell_type": "code", "execution_count": 3, "id": "7c88500b-8c09-43d3-8b16-0078a95a551d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
     ┌───┐┌─┐\n",
       "  q: ┤ H ├┤M├\n",
       "     └───┘└╥┘\n",
       "c: 1/══════╩═\n",
       "           0 
" ], "text/plain": [ " ┌───┐┌─┐\n", " q: ┤ H ├┤M├\n", " └───┘└╥┘\n", "c: 1/══════╩═\n", " 0 " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit1 = qiskit.QuantumCircuit(1, 1)\n", "\n", "circuit1.h(0)\n", "circuit1.measure(0, 0)\n", "circuit1.draw(fold=-1)" ] }, { "cell_type": "markdown", "id": "d41c8d8e", "metadata": {}, "source": [ "## Single Circuit Compilation" ] }, { "cell_type": "markdown", "id": "b2b2a613", "metadata": {}, "source": [ "We will now compile the above circuit onto Sqorpius's native gateset and visualize the differences by drawing the compiled circuit" ] }, { "cell_type": "code", "execution_count": 4, "id": "8b259905-2984-4f4a-88d4-d767581685b4", "metadata": {}, "outputs": [], "source": [ "compiler_output = provider.cq_compile(circuit1)" ] }, { "cell_type": "code", "execution_count": 5, "id": "b01be319-68f3-4aed-b9b4-4d6b10b391bc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ┌───────────────────┐┌─┐\n", " q_0: ┤0 ├┤M├\n", " │ │└╥┘\n", " q_1: ┤1 ├─╫─\n", " │ │ ║ \n", " q_2: ┤2 ├─╫─\n", " │ │ ║ \n", " q_3: ┤3 ├─╫─\n", " │ │ ║ \n", " q_4: ┤4 ├─╫─\n", " │ │ ║ \n", " q_5: ┤5 ├─╫─\n", " │ │ ║ \n", " q_6: ┤6 ├─╫─\n", " │ │ ║ \n", " q_7: ┤7 ├─╫─\n", " │ │ ║ \n", " q_8: ┤8 ├─╫─\n", " │ │ ║ \n", " q_9: ┤9 ├─╫─\n", " │ │ ║ \n", "q_10: ┤10 ├─╫─\n", " │ │ ║ \n", "q_11: ┤11 ├─╫─\n", " │ GR(1.57, -1.57) │ ║ \n", "q_12: ┤12 ├─╫─\n", " │ │ ║ \n", "q_13: ┤13 ├─╫─\n", " │ │ ║ \n", "q_14: ┤14 ├─╫─\n", " │ │ ║ \n", "q_15: ┤15 ├─╫─\n", " │ │ ║ \n", "q_16: ┤16 ├─╫─\n", " │ │ ║ \n", "q_17: ┤17 ├─╫─\n", " │ │ ║ \n", "q_18: ┤18 ├─╫─\n", " │ │ ║ \n", "q_19: ┤19 ├─╫─\n", " │ │ ║ \n", "q_20: ┤20 ├─╫─\n", " │ │ ║ \n", "q_21: ┤21 ├─╫─\n", " │ │ ║ \n", "q_22: ┤22 ├─╫─\n", " │ │ ║ \n", "q_23: ┤23 ├─╫─\n", " └───────────────────┘ ║ \n", " c: 1/══════════════════════╩═\n", " 0 \n" ] } ], "source": [ "print(compiler_output.circuit)" ] }, { "cell_type": "markdown", "id": "617cc752", "metadata": {}, "source": [ "If you would like to compile (or submit) on a different number of qubits, this can be done via the ```grid_shape``` option. This simply sets the shape of the rectangular qubit grid. However, specifying a grid that is incompatible with Sqorpius's current capabilities will result in an error when submitting." ] }, { "cell_type": "code", "execution_count": 6, "id": "4af423b0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
     ┌──────────────────┐     ┌─────────────────┐   ┌──────────────────┐     ┌─────────────────┐\n",
       "q_0: ┤0                 ├─────┤0                ├─■─┤0                 ├─────┤0                ├\n",
       "     │                  │┌───┐│                 │ │ │                  │┌───┐│                 │\n",
       "q_1: ┤1                 ├┤ Z ├┤1                ├─■─┤1                 ├┤ Z ├┤1                ├\n",
       "     │  GR(-0.79, 1.57) │└───┘│  GR(0.79, 1.57) │   │  GR(-0.79, 1.57) │└───┘│  GR(0.79, 1.57) │\n",
       "q_2: ┤2                 ├─────┤2                ├─■─┤2                 ├─────┤2                ├\n",
       "     │                  │┌───┐│                 │ │ │                  │┌───┐│                 │\n",
       "q_3: ┤3                 ├┤ Z ├┤3                ├─■─┤3                 ├┤ Z ├┤3                ├\n",
       "     └──────────────────┘└───┘└─────────────────┘   └──────────────────┘└───┘└─────────────────┘
" ], "text/plain": [ " ┌──────────────────┐ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐\n", "q_0: ┤0 ├─────┤0 ├─■─┤0 ├─────┤0 ├\n", " │ │┌───┐│ │ │ │ │┌───┐│ │\n", "q_1: ┤1 ├┤ Z ├┤1 ├─■─┤1 ├┤ Z ├┤1 ├\n", " │ GR(-0.79, 1.57) │└───┘│ GR(0.79, 1.57) │ │ GR(-0.79, 1.57) │└───┘│ GR(0.79, 1.57) │\n", "q_2: ┤2 ├─────┤2 ├─■─┤2 ├─────┤2 ├\n", " │ │┌───┐│ │ │ │ │┌───┐│ │\n", "q_3: ┤3 ├┤ Z ├┤3 ├─■─┤3 ├┤ Z ├┤3 ├\n", " └──────────────────┘└───┘└─────────────────┘ └──────────────────┘└───┘└─────────────────┘" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example_circuit = qiskit.QuantumCircuit(4, 1)\n", "example_circuit.cx(0, 1)\n", "example_circuit.cx(2, 3)\n", "new_compiler_output = provider.cq_compile(example_circuit, grid_shape=(2, 2))\n", "new_compiler_output.circuit.draw(fold=-1)" ] }, { "cell_type": "markdown", "id": "601cf4a9", "metadata": {}, "source": [ "## Single Circuit Submission" ] }, { "cell_type": "markdown", "id": "74c20c53", "metadata": {}, "source": [ "The code below will submitt he circuit to the noiseless Sqorpius simulator. If you would like to run on Sqorpius, change the ```target``` argument in backend from ```cq_sqorpius_simulator``` to ```cq_sqorpius_qpu```. It is recommended to first submit to the simulator for testing to ensure your code runs before submitting to Sqorpius. " ] }, { "cell_type": "code", "execution_count": 7, "id": "30c6dc89", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counts from qiskit-superstaq submission: {'1': 48, '0': 52}\n" ] } ], "source": [ "backend = provider.get_backend(\"cq_sqorpius_simulator\")\n", "job = backend.run(circuit1, shots=100)\n", "print(f\"Counts from qiskit-superstaq submission: {job.result().get_counts()}\")" ] }, { "cell_type": "markdown", "id": "faebe062", "metadata": {}, "source": [ "If you would like to submit these circuits to a noisy simulator, you can specify via ```method = noise-sim``` in ```job```." ] }, { "cell_type": "code", "execution_count": 8, "id": "507cbb5a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counts from noisy qiskit-superstaq submission: {'0': 58, '1': 42}\n" ] } ], "source": [ "backend = provider.get_backend(\"cq_sqorpius_simulator\")\n", "job = backend.run(circuit1, shots=100, method=\"noise-sim\")\n", "print(f\"Counts from noisy qiskit-superstaq submission: {job.result().get_counts()}\")" ] }, { "cell_type": "markdown", "id": "441a7232-a617-4f35-9fbb-66bcbe8abfec", "metadata": {}, "source": [ "## Multiple circuit compilation" ] }, { "cell_type": "markdown", "id": "9322aa52", "metadata": {}, "source": [ "All the functionalities we have seen so far can also be used on a multiple-circuit input as well. To illustrate this, let us create a different example two-qubit circuit, and compile both circuits we have created at the same time. " ] }, { "cell_type": "code", "execution_count": 9, "id": "6e6b56e6-92d1-4b3d-b8da-dee099286091", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
               \n",
       "q_0: ──■───────\n",
       "     ┌─┴─┐┌───┐\n",
       "q_1: ┤ X ├┤ H ├\n",
       "     └───┘└───┘
" ], "text/plain": [ " \n", "q_0: ──■───────\n", " ┌─┴─┐┌───┐\n", "q_1: ┤ X ├┤ H ├\n", " └───┘└───┘" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit2 = qiskit.QuantumCircuit(2)\n", "circuit2.cx(0, 1)\n", "circuit2.h(1)\n", "circuit2.draw(fold=-1)" ] }, { "cell_type": "code", "execution_count": 10, "id": "5d3993fd-83f1-42e9-b1e0-f4e553765682", "metadata": {}, "outputs": [], "source": [ "compiler_output = provider.cq_compile([circuit1, circuit2])" ] }, { "cell_type": "code", "execution_count": 11, "id": "d7bdb8fb-a0d0-4fae-932a-f2fc51848f4f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ┌───────────────────┐┌─┐\n", " q_0: ┤0 ├┤M├\n", " │ │└╥┘\n", " q_1: ┤1 ├─╫─\n", " │ │ ║ \n", " q_2: ┤2 ├─╫─\n", " │ │ ║ \n", " q_3: ┤3 ├─╫─\n", " │ │ ║ \n", " q_4: ┤4 ├─╫─\n", " │ │ ║ \n", " q_5: ┤5 ├─╫─\n", " │ │ ║ \n", " q_6: ┤6 ├─╫─\n", " │ │ ║ \n", " q_7: ┤7 ├─╫─\n", " │ │ ║ \n", " q_8: ┤8 ├─╫─\n", " │ │ ║ \n", " q_9: ┤9 ├─╫─\n", " │ │ ║ \n", "q_10: ┤10 ├─╫─\n", " │ │ ║ \n", "q_11: ┤11 ├─╫─\n", " │ GR(1.57, -1.57) │ ║ \n", "q_12: ┤12 ├─╫─\n", " │ │ ║ \n", "q_13: ┤13 ├─╫─\n", " │ │ ║ \n", "q_14: ┤14 ├─╫─\n", " │ │ ║ \n", "q_15: ┤15 ├─╫─\n", " │ │ ║ \n", "q_16: ┤16 ├─╫─\n", " │ │ ║ \n", "q_17: ┤17 ├─╫─\n", " │ │ ║ \n", "q_18: ┤18 ├─╫─\n", " │ │ ║ \n", "q_19: ┤19 ├─╫─\n", " │ │ ║ \n", "q_20: ┤20 ├─╫─\n", " │ │ ║ \n", "q_21: ┤21 ├─╫─\n", " │ │ ║ \n", "q_22: ┤22 ├─╫─\n", " │ │ ║ \n", "q_23: ┤23 ├─╫─\n", " └───────────────────┘ ║ \n", " c: 1/══════════════════════╩═\n", " 0 \n" ] } ], "source": [ "print(compiler_output.circuits[0])" ] }, { "cell_type": "code", "execution_count": 12, "id": "a02b75d5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ┌───────────────────┐ ┌──────────────────┐ \n", " q_0: ┤0 ├─────┤0 ├─■─\n", " │ │┌───┐│ │ │ \n", " q_1: ┤1 ├┤ Z ├┤1 ├─■─\n", " │ │└───┘│ │ \n", " q_2: ┤2 ├─────┤2 ├───\n", " │ │ │ │ \n", " q_3: ┤3 ├─────┤3 ├───\n", " │ │ │ │ \n", " q_4: ┤4 ├─────┤4 ├───\n", " │ │ │ │ \n", " q_5: ┤5 ├─────┤5 ├───\n", " │ │ │ │ \n", " q_6: ┤6 ├─────┤6 ├───\n", " │ │ │ │ \n", " q_7: ┤7 ├─────┤7 ├───\n", " │ │ │ │ \n", " q_8: ┤8 ├─────┤8 ├───\n", " │ │ │ │ \n", " q_9: ┤9 ├─────┤9 ├───\n", " │ │ │ │ \n", "q_10: ┤10 ├─────┤10 ├───\n", " │ │ │ │ \n", "q_11: ┤11 ├─────┤11 ├───\n", " │ GR(-0.79, 1.57) │ │ GR(0.79, 1.57) │ \n", "q_12: ┤12 ├─────┤12 ├───\n", " │ │ │ │ \n", "q_13: ┤13 ├─────┤13 ├───\n", " │ │ │ │ \n", "q_14: ┤14 ├─────┤14 ├───\n", " │ │ │ │ \n", "q_15: ┤15 ├─────┤15 ├───\n", " │ │ │ │ \n", "q_16: ┤16 ├─────┤16 ├───\n", " │ │ │ │ \n", "q_17: ┤17 ├─────┤17 ├───\n", " │ │ │ │ \n", "q_18: ┤18 ├─────┤18 ├───\n", " │ │ │ │ \n", "q_19: ┤19 ├─────┤19 ├───\n", " │ │ │ │ \n", "q_20: ┤20 ├─────┤20 ├───\n", " │ │ │ │ \n", "q_21: ┤21 ├─────┤21 ├───\n", " │ │ │ │ \n", "q_22: ┤22 ├─────┤22 ├───\n", " │ │ │ │ \n", "q_23: ┤23 ├─────┤23 ├───\n", " └───────────────────┘ └──────────────────┘ \n" ] } ], "source": [ "print(compiler_output.circuits[1])" ] } ], "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.11.5" }, "vscode": { "interpreter": { "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" } } }, "nbformat": 4, "nbformat_minor": 5 }