{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "b24594e7-0ace-4b54-979a-e4c77dd17507",
      "metadata": {},
      "source": [
        "---\n",
        "title: Port code to Qiskit Serverless\n",
        "description: How to port existing code to leverage Qiskit Serverless\n",
        "---\n",
        "\n",
        "# Port code to Qiskit Serverless\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e20e8e81-c439-4f17-a843-a633259e5268",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cb8926d5-a417-478e-9ae1-ec78c64aa86a",
      "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",
        "The following example demonstrates how to port existing code to leverage Qiskit Serverless.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  The following code assumes that you have saved your credentials. If you have not, follow the instructions in [Set up your IBM Cloud account](/docs/guides/cloud-setup-untrusted) to authenticate with your API key.\n",
        "</Admonition>\n",
        "\n",
        "## Update the experiment\n",
        "\n",
        "<Tabs>\n",
        "  <TabItem value=\"LocalExperiment\" label=\"Local Experiment\">\n",
        "    ```python\n",
        "    from qiskit.transpiler import generate_preset_pass_manager\n",
        "    from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "    from qiskit.circuit.random import random_circuit\n",
        "\n",
        "    qc_random = [(random_circuit(20, 20, measure=True)) for _ in range(30)]\n",
        "    optimization_level = 3\n",
        "\n",
        "    service = QiskitRuntimeService(channel=\"ibm_quantum_platform\")\n",
        "    backend = service.get_backend(backend_name)\n",
        "\n",
        "    pass_manager = generate_preset_pass_manager(\n",
        "        optimization_level=optimization_level, backend=backend\n",
        "    )\n",
        "\n",
        "    # @distribute_task(target={\"cpu\": 1})\n",
        "    def transpile_parallel(circuit, pass_manager):\n",
        "        \"\"\"Distributed transpilation for an abstract circuit into an ISA circuit for a given backend.\"\"\"\n",
        "\n",
        "        isa_circuit = pass_manager.run(circuit)\n",
        "\n",
        "        return isa_circuit\n",
        "\n",
        "    transpiled_circuits = [\n",
        "        transpile_parallel(circuit, pass_manager)\n",
        "        for circuit in circuits\n",
        "    ]\n",
        "\n",
        "    print(transpiled_circuits)\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"Serverless\" label=\"Serverless\">\n",
        "    ```python\n",
        "    # transpile_remote.py\n",
        "\n",
        "    from qiskit.transpiler import generate_preset_pass_manager\n",
        "    from qiskit_serverless import get_arguments, save_result, distribute_task, get\n",
        "    from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "    # Get program arguments\n",
        "    arguments = get_arguments()\n",
        "    circuits = arguments.get(\"circuits\")\n",
        "    backend_name = arguments.get(\"backend_name\")\n",
        "    optimization_level = arguments.get(\"optimization_level\")\n",
        "    pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=optimization_level, backend=backend_name\n",
        "    )\n",
        "\n",
        "    # Distribute task across workers\n",
        "    @distribute_task(target={\"cpu\": 1})\n",
        "    def transpile_parallel(circuit, pass_manager):\n",
        "    \"\"\"Distributed transpilation for an abstract circuit into an ISA circuit for a given backend.\"\"\"\n",
        "\n",
        "    isa_circuit = pass_manager.run(circuit)\n",
        "\n",
        "    return isa_circuit\n",
        "\n",
        "    try:\n",
        "    # Get backend\n",
        "    service = QiskitRuntimeService()\n",
        "    backend = service.get_backend(backend_name)\n",
        "\n",
        "    # run distributed tasks as async function\n",
        "    # we get task references as a return type\n",
        "    sample_task_references = [\n",
        "        transpile_parallel(circuit, pass_manager)\n",
        "        for circuit in circuits\n",
        "    ]\n",
        "\n",
        "    # now we need to collect results from task references\n",
        "    results = get(sample_task_references)\n",
        "\n",
        "    # Return results\n",
        "    save_result({\n",
        "        \"transpiled_circuits\": results\n",
        "    })\n",
        "\n",
        "    except Exception as e:\n",
        "    # Exception handling\n",
        "    import traceback\n",
        "    print(traceback.format_exc())\n",
        "    ```\n",
        "  </TabItem>\n",
        "</Tabs>\n",
        "\n",
        "## Upload to Qiskit Serverless\n",
        "\n",
        "Follow the instructions on the [Introduction to Qiskit Functions](/docs/guides/functions) page to authenticate with your API key.\n",
        "\n",
        "```python\n",
        "from qiskit_ibm_catalog import QiskitServerless, QiskitFunction\n",
        "\n",
        "# Authenticate to the remote cluster and submit the pattern for remote execution.\n",
        "serverless = QiskitServerless()\n",
        "\n",
        "transpile_remote_demo = QiskitFunction(\n",
        "    title=\"transpile_remote_serverless\",\n",
        "    entrypoint=\"transpile_remote.py\",\n",
        "    working_dir=\"./source_files/\",\n",
        ")\n",
        "\n",
        "serverless.upload(transpile_remote_demo)\n",
        "```\n",
        "\n",
        "Output\n",
        "\n",
        "```text\n",
        "'transpile_remote_serverless'\n",
        "```\n",
        "\n",
        "## Remotely run in Qiskit Serverless\n",
        "\n",
        "```python\n",
        "from qiskit.circuit.random import random_circuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "# Setup inputs\n",
        "qc_random = [(random_circuit(20, 20, measure=True)) for _ in range(30)]\n",
        "backend = \"ibm_brisbane\"\n",
        "optimization_level = 3\n",
        "\n",
        "# Running program\n",
        "transpile_remote_serverless = serverless.load('transpile_remote_serverless')\n",
        "job = transpile_remote_serverless.run(\n",
        "    circuits=qc_random,\n",
        "    backend=backend,\n",
        "    optimization_level=optimization_level\n",
        ")\n",
        "\n",
        "job.job_id\n",
        "```\n",
        "\n",
        "Output\n",
        "\n",
        "```text\n",
        "'727e921d-512d-4b7d-af97-fe29e93ce7ea'\n",
        "```\n",
        "\n",
        "## Next steps\n",
        "\n",
        "<Admonition type=\"info\" title=\"Recommendations\">\n",
        "  * Read a paper in which researchers used Qiskit Serverless and quantum-centric supercomputing to [explore quantum chemistry](https://arxiv.org/abs/2405.05068v1).\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": 4
}