Skip to content

Pulse level access

Pulse level access gives the user a lower level of control over their quantum jobs. Instead of only defining jobs via circuits using gates with pulse level access the user has control over the control pulses of the quantum computer. Pulse level access to the available quantum computers is enabled through the IQM Pulla Python package. IQM Pulla is already installed in the module for each quantum computer. Below you'll find an overview on running pulse level jobs from LUMI on the available quantum computers. For more advanced documentation on using IQM Pulla see IQM's documentation

Device-specific values

The examples on this page use placeholders <DEVICE_VALUE>, <QUANTUM_COMPUTER_ID>, and <CORTEX_URL>. Replace them with the runtime identifiers for your target device, listed under "Runtime identifiers" on the Aalto Q20 or VTT Q50 page. For VLQ see the VLQ instructions.

Import packages

Load the module with module load fiqci-vtt-qiskit.

import os

from qiskit import QuantumCircuit
from qiskit.compiler import transpile
from iqm.iqm_client.util import print_env_vars
from iqm.qiskit_iqm import IQMProvider
from iqm.pulla.pulla import Pulla
from iqm.pulla.utils_qiskit import qiskit_to_pulla, sweep_job_to_qiskit

Define Pulla client and backend

DEVICE_CORTEX_URL = os.getenv('<CORTEX_URL>')

p = Pulla(DEVICE_CORTEX_URL, quantum_computer="<QUANTUM_COMPUTER_ID>")

provider = IQMProvider(DEVICE_CORTEX_URL, quantum_computer="<QUANTUM_COMPUTER_ID>")
backend = provider.get_backend()

VLQ Pulla backend

For VLQ see the VLQ page for instructions for fetching the VLQ Pulla backend as well as loading the VLQ module.

Define a quantum circuit

qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(0, 2)
qc.measure_all()

Transpile to backend

qc_transpiled = transpile(qc, backend=backend, optimization_level=3)

Convert to Pulla

circuits, compiler = qiskit_to_pulla(p, backend, qc_transpiled)

shots = 100
settings = compiler.get_settings(circuits=circuits)
settings.set_shots(shots)

job_definition, context = compiler.compile(circuits, settings=settings)

Visualize pulse scheduling (optional)

Optionally it is possible to visualize the pulse scheduling before submitting the job.

from iqm.pulse.playlist.visualisation.base import inspect_playlist
from IPython.core.display import HTML

HTML(inspect_playlist(job_definition.sweep_definition.playlist, [0]))

Submit through Pulla

job = p.submit_playlist(job_definition, context=context)
job.wait_for_completion()
qiskit_result = sweep_job_to_qiskit(job, shots=shots)

print(f"Raw results:\n{job.result().circuit_measurement_results}\n")
print(f"Qiskit result counts:\n{qiskit_result.get_counts()}\n")

Submitting through LUMI

For submitting jobs see Running quantum jobs.

Further reading

Do you find this page useful?
Thank you for your feedback!
Thank you! Your feedback is appreciated.

Please let us know how we could improve this page by contacting us or by creating an issue in GitHub. You can also edit this page yourself and contribute your improvements by creating a pull request.

November 4, 2026