310 lines
11 KiB
Plaintext
310 lines
11 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "b24594e7-0ace-4b54-979a-e4c77dd17507",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Port code to Qiskit Serverless"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e20e8e81-c439-4f17-a843-a633259e5268",
|
|
"metadata": {
|
|
"tags": [
|
|
"version-info"
|
|
]
|
|
},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "cb8926d5-a417-478e-9ae1-ec78c64aa86a",
|
|
"metadata": {},
|
|
"source": [
|
|
"<LegacyContent>\n",
|
|
"<Admonition type=\"note\">\n",
|
|
"This documentation is relevant to IBM Quantum® Platform Classic. If you need the newer version, go to the new [IBM Quantum Platform documentation.](https://quantum.cloud.ibm.com/docs/guides/serverless-port-code)\n",
|
|
"</Admonition>\n",
|
|
"</LegacyContent>\n",
|
|
"<CloudContent>\n",
|
|
"<Admonition type=\"note\">\n",
|
|
"This documentation is relevant to the new IBM Quantum® Platform. If you need the previous version, return to the [IBM Quantum Platform Classic documentation.](https://docs.quantum.ibm.com/guides/serverless-port-code)\n",
|
|
"</Admonition>\n",
|
|
"</CloudContent>\n",
|
|
"\n",
|
|
"The following example demonstrates how to port existing code to leverage Qiskit Serverless.\n",
|
|
"<Admonition type=\"note\">\n",
|
|
"The following code assumes that you have saved your credentials. If you have not, follow the instructions in <LegacyContent>[Set up an IBM Quantum channel](/docs/guides/setup-channel#iqp)</LegacyContent><CloudContent>[Set up your IBM Cloud account](/docs/guides/cloud-setup#cloud-untrusted)</CloudContent> to authenticate with your API key.\n",
|
|
"</Admonition>\n",
|
|
"\n",
|
|
"## Update the experiment\n",
|
|
"<LegacyContent>\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()\n",
|
|
"backend = service.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 qc_random\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, update_status, Job\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",
|
|
" update_status(Job.OPTIMIZING_HARDWARE)\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",
|
|
"\n",
|
|
" </TabItem>\n",
|
|
"</Tabs>\n",
|
|
"</LegacyContent>\n",
|
|
"<CloudContent>\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_cloud\")\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",
|
|
"\n",
|
|
" </TabItem>\n",
|
|
"</Tabs>\n",
|
|
"</CloudContent>\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",
|
|
"```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",
|
|
"Output\n",
|
|
"```text\n",
|
|
"'727e921d-512d-4b7d-af97-fe29e93ce7ea'\n",
|
|
"```\n",
|
|
"\n",
|
|
"## Next steps\n",
|
|
"\n",
|
|
"<Admonition type=\"info\" title=\"Recommendations\">\n",
|
|
"\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",
|
|
"\n",
|
|
"</Admonition>"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"description": "How to port existing code to leverage Qiskit Serverless",
|
|
"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": "Port code to Qiskit Serverless"
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|