Skip to main contentIBM Quantum Documentation Preview

Write your first Qiskit Serverless program

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.

[2] :
./source_files/transpile_remote.py
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.

[3] :
./source_files/transpile_remote.py (appended)
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:

[4] :
./source_files/transpile_remote.py (appended)
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:

[5] :
./source_files/transpile_remote.py (appended)
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().

[6] :
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:

[7] :
transpile_remote_demo = QiskitFunction(
    title="transpile_remote_serverless",
    entrypoint="transpile_remote.py",
    working_dir="./source_files/",
    dependencies=["qiskit-aer==0.14.1"],
)
[8] :
serverless.upload(transpile_remote_demo)

Output:

'transpile_remote_serverless'

To check if it successfully uploaded, use serverless.list():

[9] :
serverless.list()

Output:

[QiskitFunction(transpile_remote_serverless)]

Next steps

Recommendations