Write your first Qiskit Serverless program
Package versions
The code on this page was developed using the following requirements. We recommend using these versions or newer.
qiskit[all]~=1.2.4
qiskit-aer~=0.15.1
qiskit-ibm-runtime~=0.31.0
qiskit-serverless~=0.17.1
qiskit-ibm-catalog~=0.1
This example demonstrates how to use qiskit-serverless
tools to create a parallel transpilation program, and then implement qiskit-ibm-catalog
to deploy your program to IBM Quantum™ Platform to use as a reusable remote service.
Example: remote transpilation with Qiskit Serverless
Start with the following example that transpiles a circuit
against a given backend
and target optimization_level
, and gradually add more elements to deploy your workload to Qiskit Serverless.
Put the following code cell in the file ./source_files/transpile_remote.py
. This file is the program we'll upload to Qiskit Serverless.
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
def transpile_remote(circuit, optimization_level, backend):
"""Transpiles an abstract circuit into an ISA circuit for a given backend."""
pass_manager = generate_preset_pass_manager(
optimization_level=optimization_level,
backend=backend
)
isa_circuit = pass_manager.run(circuit)
return isa_circuit
Set up your files
Qiskit Serverless requires setting up your workload’s .py
files into a dedicated directory. The following structure is an example of good practice:
serverless_program
├── program_uploader.ipynb
└── source_files
├── transpile_remote.py
└── *.py
Serverless uploads the contents of source_files
to run remotely. Once these are set up, you can adjust transpile_remote.py
to fetch inputs and return outputs.
Get program arguments
Your initial transpile_remote.py
has three inputs: circuits
, backend_name
, and optimization_level
. Serverless is currently limited to only accept serializable inputs and outputs. For this reason, you cannot pass in backend
directly, so use backend_name
as a string instead.
from qiskit_serverless import get_arguments, save_result, distribute_task, get
# Get program arguments
arguments = get_arguments()
circuits = arguments.get("circuits")
backend_name = arguments.get("backend_name")
optimization_level = arguments.get("optimization_level")
At this point, you can get your backend with QiskitRuntimeService
, and add your existing program:
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService(channel="ibm_quantum")
backend = service.get_backend(backend_name)
Finally, you can run transpile_remote()
across all circuits
passed in, and return the transpiled_circuits
as a result:
results = [
transpile_remote(circuit, backend)
for circuit in circuits
]
save_result({
"transpiled_circuits": results
})
Deploy to IBM Quantum Platform
The previous section created a program to be run remotely. The code cells in this section upload that program to Qiskit Serverless.
Use qiskit-ibm-catalog
to authenticate to QiskitServerless
with your API token, which you can find in your IBM Quantum account, and upload the program.
You can use save_account()
to save your credentials (See the "Authenticate to the service" step in the Set up to use IBM Quantum Platform section). Note that this writes your credentials to the same file as QiskitRuntimeService.save_account()
.
from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
# Authenticate to the remote cluster and submit the pattern for remote execution
serverless = QiskitServerless()
Qiskit Serverless compresses the contents of working_dir
(in this case, source_files
) into a tar
, which is uploaded and cleaned up after. The entrypoint
identifies the main program executable for Qiskit Serverless to run. Additionally, if your program has custom pip
dependencies, you can add them to a dependencies
array:
transpile_remote_demo = QiskitFunction(
title="transpile_remote_serverless",
entrypoint="transpile_remote.py",
working_dir="./source_files/",
)
serverless.upload(transpile_remote_demo)
Output:
QiskitFunction(transpile_remote_serverless)
To check if it successfully uploaded, use serverless.list()
:
serverless.list()
Output:
[QiskitFunction(transpile_remote_serverless_test_7b71d607),
QiskitFunction(transpile_remote_serverless_test_6169e40a),
QiskitFunction(transpile_remote_serverless_test_3e28580a),
QiskitFunction(transpile_remote_serverless_test_7e16ef16),
QiskitFunction(transpile_remote_serverless_test_47c755bf),
QiskitFunction(transpile_remote_serverless),
QiskitFunction(transpile_remote_serverless_test_579ed35c-3f56-484c-8a64-58dc953ed845),
QiskitFunction(transpile_remote_serverless_test_47c79b69),
QiskitFunction(transpile_remote_serverless_test_53c0786c),
QiskitFunction(transpile_remote_serverless_test_094ae798-88f7-46ab-8997-5a0bf503d908),
QiskitFunction(transpile_remote_serverless_test_35fb8da4-0fa3-4596-85c4-3a13d67f8c6a),
QiskitFunction(transpile_remote_serverless_test_426d1904),
QiskitFunction(transpile_remote_serverless_test_ebd79361),
QiskitFunction(transpile_remote_serverless_test_a966c167),
QiskitFunction(transpile_remote_serverless_test_d19e6f7e-3de0-4dde-b978-bdd03fba9845),
QiskitFunction(transpile_remote_serverless_test_b4d7a503),
QiskitFunction(transpile_remote_serverless_test_ceb9a116),
QiskitFunction(transpile_remote_serverless_test_355478eb),
QiskitFunction(transpile_remote_serverless_test),
QiskitFunction(transpile_remote_serverless_test_8e84c5f0-962d-4cd0-bca8-ebe1e227552f),
QiskitFunction(transpile_remote_serverless_test_4532e330),
QiskitFunction(transpile_remote_serverless_test_7659964c),
QiskitFunction(transpile_remote_serverless_test_5d216ee7),
QiskitFunction(transpile_remote_serverless_test_d0757405),
QiskitFunction(transpile_remote_serverless_test_0f048273),
QiskitFunction(transpile_remote_serverless_test_6a68a773),
QiskitFunction(transpile_remote_serverless_test_f9b5609f),
QiskitFunction(transpile_remote_serverless_test_701468af-437d-4737-8a00-843f0431a09c),
QiskitFunction(transpile_remote_serverless_test_e81ddca0),
QiskitFunction(transpile_remote_serverless_test_c1de9270),
QiskitFunction(transpile_remote_serverless_test_3826f696),
QiskitFunction(transpile_remote_serverless_test_2da7da19),
QiskitFunction(transpile_remote_serverless_test_74c54154),
QiskitFunction(transpile_remote_serverless_test_e51063a5),
QiskitFunction(transpile_remote_serverless_test_69c1b2c6),
QiskitFunction(transpile_remote_serverless_test_abb21121),
QiskitFunction(transpile_remote_serverless_test_0990ad64),
QiskitFunction(transpile_remote_serverless_test_65db9226),
QiskitFunction(transpile_remote_serverless_test_f7057422),
QiskitFunction(transpile_remote_serverless_test_9fad0bc6)]
Next steps
- Learn how to pass inputs and run your program remotely in the Run your first Qiskit Serverless workload remotely topic.