{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "6ec2a7ce-6d72-401c-aecd-59f2f519153a",
      "metadata": {},
      "source": [
        "---\n",
        "title: Run your first Qiskit Serverless workload remotely\n",
        "description: How to list programs available in Serverless, pass inputs into these programs, run them remotely, check status, and retrieve results and logs.\n",
        "---\n",
        "\n",
        "# Run your first Qiskit Serverless workload remotely\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1ffb4bbc-6702-4424-bc38-226eb3194a07",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "<Accordion>\n",
        "  <AccordionItem title=\"Package versions\">\n",
        "    The code on this page was developed using the following requirements.\n",
        "    We recommend using these versions or newer.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=1.4.0\n",
        "    qiskit-ibm-runtime~=0.36.1\n",
        "    qiskit-ibm-catalog~=0.4\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "33bc7389-22b7-4ddd-ae7d-1c4fd603d793",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\">\n",
        "  **Qiskit Serverless is getting an upgrade, and its features are changing fast.** During this development phase, find release notes and the most recent documentation at the [Qiskit Serverless GitHub](https://qiskit.github.io/qiskit-serverless/index.html) page.\n",
        "</Admonition>\n",
        "\n",
        "This section explores how to use `qiskit-ibm-catalog` to list programs available in Qiskit Serverless, pass inputs into these programs, run them remotely, check their status, and retrieve results and logs.\n",
        "\n",
        "Be sure you have followed the workflow in [Write your first Qiskit Serverless program](/docs/guides/serverless-first-program) before you begin.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ec693d85-baaf-487e-aaff-3867512a4790",
      "metadata": {},
      "source": [
        "## List programs available\n",
        "\n",
        "You can use `QiskitServerless.list()` to fetch a list of the available programs to run with Qiskit Serverless. This includes the previously uploaded [`transpile_remote_serverless`](./serverless-first-program).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "4eaad0dc-9b42-48fa-ad08-4e0f9c4d90bc",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(transpile_remote_serverless)"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_catalog import QiskitServerless\n",
        "\n",
        "serverless = QiskitServerless()\n",
        "next(\n",
        "    program\n",
        "    for program in serverless.list()\n",
        "    if program.title == \"transpile_remote_serverless\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e1a5d0f7-e4d9-4289-ac87-ca25e76f968d",
      "metadata": {},
      "source": [
        "## Run an uploaded program and pass inputs\n",
        "\n",
        "First, set up your inputs. Your program has three inputs: `circuits`, `backend`, and `optimization_level`. You can use `random_circuit` to create 30 random circuits:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "46108a95-11f8-4ecf-83bb-131c3e7ea4c2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/serverless-run-first-workload/extracted-outputs/46108a95-11f8-4ecf-83bb-131c3e7ea4c2-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.random import random_circuit\n",
        "\n",
        "qc_random = [(random_circuit(4, 4, measure=True, seed=i)) for i in range(10)]\n",
        "qc_random[0].draw(output=\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "61c17ded-b832-4db1-ba9a-60772362daea",
      "metadata": {},
      "source": [
        "Next, use `QiskitRuntimeService` and `least_busy` to select a `backend`:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "ebefb5ac-c8a8-4350-b16f-0677f0e412e5",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "print(backend.name)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6a6ba35b-b98b-41b1-8dd4-c7cf2fc8b637",
      "metadata": {},
      "source": [
        "Set your optimization level:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "cab2773b-f72a-49fe-a274-169a10e89c5e",
      "metadata": {},
      "outputs": [],
      "source": [
        "optimization_level = 3"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f522b54f-93e5-45e9-9dc7-a2287eb4c707",
      "metadata": {},
      "source": [
        "Select your program with `serverless.load('PROGRAM_NAME')`:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "e9b7e7c1-07b1-4777-bb08-1522433901c6",
      "metadata": {},
      "outputs": [],
      "source": [
        "transpile_remote_serverless = serverless.load(\"transpile_remote_serverless\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8e256a2a-6b14-4194-8fee-df986c7ebc6c",
      "metadata": {},
      "source": [
        "Next, pass your inputs and run it in a pythonic fashion as follows:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "85b1aace-e7d7-4e2e-bb77-44fb514d0236",
      "metadata": {},
      "outputs": [],
      "source": [
        "job = transpile_remote_serverless.run(\n",
        "    circuits=qc_random,\n",
        "    backend=backend.name,\n",
        "    optimization_level=optimization_level,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "2e8b4ec2-b7e3-4218-8742-b67f2a1d82e0",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'118256c5-bbb0-4ea8-9e9f-51aac2220aef'"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "job.job_id"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "87dbb375-cd24-4d0f-a2fc-c653db8345e3",
      "metadata": {},
      "source": [
        "<span id=\"serverless-job-status\" />\n",
        "\n",
        "## Check job status\n",
        "\n",
        "With your Qiskit Serverless `job_id`, you can check the status of running jobs. This includes the following statuses:\n",
        "\n",
        "* **`QUEUED`**: The remote program is in the Qiskit Serverless queue. The queue priority is currently based on how much you've used Qiskit Serverless\n",
        "* **`INITIALIZING`**: The remote program is starting; this includes setting up the remote environment and installing dependencies\n",
        "* **`RUNNING`**: The program is running. At this stage, if you have `print()` outputs in your program, you can retrieve logs using `job.logs()`\n",
        "* **`DONE`**: The program is complete, and you can retrieve data stored in `save_result()` with `job.results()`\n",
        "\n",
        "You can also set more detailed job statuses in [Manage Qiskit Serverless compute and data resources](/docs/guides/serverless-manage-resources).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f4877d45-c350-4855-b1ca-868a6ad8cfa4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'QUEUED'"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "job.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3fa9c01e-18a4-482c-bad6-69dee5acece4",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\">\n",
        "  Currently, the IBM Quantum workloads table only reflects Qiskit Runtime workloads. Use `job.status()` to see your Qiskit Serverless workload's current status.\n",
        "</Admonition>\n",
        "\n",
        "You've successfully run your first Qiskit Serverless program!\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "65566f2c-8d5b-4493-819b-4389155c3d69",
      "metadata": {},
      "source": [
        "## Retrieve logs and results\n",
        "\n",
        "As mentioned before, once a program is `RUNNING`, you can use `job.logs()` to fetch logs created from `print()` outputs:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "cbf12a1b-bfff-4eb2-82f1-298de1e9c114",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "No logs yet.\n"
          ]
        }
      ],
      "source": [
        "logs = job.logs()\n",
        "print(logs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bff87452-bf98-4c7a-85c8-d280d89a7970",
      "metadata": {},
      "source": [
        "At any time, you can also cancel a job:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "bc4fbe20-456c-4ce4-bf26-dfdb8b68e89f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Job has been stopped.'"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "job.stop()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "925a8d81-e85b-4e26-a9e1-3a01e8e0785b",
      "metadata": {},
      "source": [
        "Once a program is `DONE`, you can use `job.results()` to fetch the result stored in `save_result()`:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "c0d999d9-af9e-4312-b5bb-f60f714257ba",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'transpiled_circuits': [<qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93eca64810>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec5e5310>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec5d5310>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec58b490>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec57d310>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec535950>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec523c90>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec60a990>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec5527d0>,\n",
              "  <qiskit.circuit.quantumcircuit.QuantumCircuit at 0x7f93ec4152d0>]}"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# We can't get results from a cancelled job, so we'll fetch a completed one instead\n",
        "completed_job = next(\n",
        "    job for job in serverless.jobs() if job.status() == \"DONE\"\n",
        ")\n",
        "completed_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ca9791df-60c2-49d8-8541-741078ea63c6",
      "metadata": {},
      "source": [
        "## List jobs previously run with Qiskit Serverless\n",
        "\n",
        "You can use `jobs()` to list all jobs submitted to Qiskit Serverless:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "ba9365c4-b07d-4dc6-9594-edc07c44bc63",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[<Job | 118256c5-bbb0-4ea8-9e9f-51aac2220aef>,\n",
              " <Job | e9a36469-7d6b-4f00-bf91-78709ebdbbff>,\n",
              " <Job | 4efd601b-8f61-4c8e-b14a-0b8a9c649dc0>,\n",
              " <Job | 87cd22c7-8eb9-4606-bdb4-befe946e9e9b>,\n",
              " <Job | be9a6dfd-0830-4250-aa60-acdd05bb8818>,\n",
              " <Job | 479513dd-6a76-4c3e-ba49-bb21351b9a05>,\n",
              " <Job | f9c20c31-be46-41b3-97ac-99f7be61f89e>,\n",
              " <Job | 37fa2489-4449-4bfb-974e-9d9a9ec3cc21>,\n",
              " <Job | b754c4e8-6817-48db-9bb9-74c151d6349a>,\n",
              " <Job | 78bc6744-b417-48cb-8e01-59bb63bcc2be>]"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "old_jobs = serverless.jobs()\n",
        "old_jobs"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fd3415a0-0e55-4991-8764-c9fe66eb2664",
      "metadata": {},
      "source": [
        "## Next steps\n",
        "\n",
        "<Admonition type=\"info\" title=\"Recommendations\">\n",
        "  * Explore [compute and data management tools](./serverless-manage-resources) available to your program, including parallelization.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}