from qiskit import QuantumCircuit, visualization
from qiskit.compiler import transpile
from iqm.qiskit_iqm import IQMProvider
from iqm.qiskit_iqm.iqm_transpilation import optimize_single_qubit_gates
from iqm.pulla.pulla import Pulla
from iqm.pulla.utils_qiskit import qiskit_to_pulla, station_control_result_to_qiskit
from iqm.iqm_client import IQMClientSubmitting Jobs with Pulse-Level Access
This guide demonstrates how to submit quantum computing jobs with pulse-level access using the IQM Pulla library.
Overview
What this pulse-level access example do:
- We define quantum circuits at the gate level using Qiskit
- The circuit is transpiled and converted to pulse schedules
- Jobs are executed using the Pulla client
Requirement
This notebook requires a Python virtual environment with the following additional libraries installed
iqm-pulla==5.28Step 1: Import Python library dependencies
Step 2: Initialize the pulse-level client
Initialize both the Pulla client for pulse-level execution and the IQM client for retrieving results.
station_url = ""  # TODO: Change to your station URL if needed
server_url = ""  # TODO: Change to your server URL if needed
api_token = (
    ""  # TODO: Insert your API token here or set the IQM_API_TOKEN environment variable
)
# Initialize Pulla client for pulse-level execution
p = Pulla(station_url, get_token_callback=lambda: f"Bearer {api_token}")
provider = IQMProvider(server_url, token=api_token)
backend = provider.get_backend()
# Initialize IQM client for fetching results
client = IQMClient(url=server_url, token=api_token)Step 3: Define the quantum circuit to be executed
Create a quantum circuit using Qiskit. This example creates a simple entanglement circuit.
shots = 100
# Define a quantum circuit.
qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(0, 2)
qc.measure_all()
qc.draw(output="mpl")
Step 4: Transpile quantum circuit to pulse schedule
Convert the quantum circuit to pulse-level instructions that can be executed on the quantum hardware.
# Transpile the circuit using Qiskit, and then convert it into Pulla format.
qc_transpiled = transpile(
    qc, backend=backend, layout_method="sabre", optimization_level=3
)
qc_optimized = optimize_single_qubit_gates(qc_transpiled)
circuits, compiler = qiskit_to_pulla(p, backend, qc_optimized)
# Compile the circuit into an instruction schedule playlist.
playlist, context = compiler.compile(circuits)
settings, context = compiler.build_settings(context, shots=shots)# Optionally visualize the pulse playlist
from iqm.pulse.playlist.visualisation.base import inspect_playlist
from IPython.core.display import HTML
HTML(inspect_playlist(playlist, [0]))Step 5: Execute the job and retrieve results
Execute the pulse schedule on the quantum hardware.
# Execute the job
# Pulla.execute() returns a StationControlResult object; the measurements are in StationControlResult.result
# By default execute() prints the measurement results; disable it with verbose=False
response_data = p.execute(playlist, context, settings, verbose=False)
qiskit_result = station_control_result_to_qiskit(
    response_data, shots=shots, execution_options=context["options"]
)
print(f"Raw results:\n{response_data.result}\n")
print(f"Qiskit result counts:\n{qiskit_result.get_counts()}\n")
visualization.plot_histogram(qiskit_result.get_counts())