AQT Access: knowledge base for users


This document collects helpful information on submitting jobs proficiently to AQT20  QPU; such information was collected during the AQT Friendly User Pilot Phase.

Limits of the system

  • The maximum supported number of qubits is currently 12;
  • Less than 50 circuits per single job request (to reduce overhead in case the job fails and needs to be repeated);
  • The maximum supported shots is 200
  • You can send 2 jobs at once (before requesting the result) to bypass the network latency. Sending more than 2 jobs at once does not provide any additional advantage.
  • The maximum supported number of gates per circuit is 2000. Circuits containing up to 300 gates can be expected to perform according to the accumulated gate fidelities. The results can be compromised beyond 300 gates per circuit due to decoherence.

Preparation of the tests before running and simulated back-end

We advise the users to test their scripts with a local simulator, to ensure they will not fail during execution on the real hardware. Moreover, a simulated back-end of the AQT hardware can be accessed throught the AQT Qiskit provider, available at https://qiskit-community.github.io/qiskit-aqt-provider/.

Access via MQSS

Circuits are submitted to AQT20 via the MPQ Qiskit Provider.

from mqp.qiskit_provider import MQPProvider

token = "<YOUR TOKEN>"
provider = MQPProvider(token)

[backend] = provider.backends("AQT20")

Submission to the queue

To enter the submission queue, always add the queued=True flag at job submission:

job = backend.run(qc, shots=shots, queued=True)

Transpiled circuits

To submit QASM3-formatted circuits (e.g. Qiskit-transpiled circuits), always add the qasm3=True flag:

job = backend.run(qc, shots=shots, qasm3=True, queued=True)

Optimization level

Use optimization_level = 3 when compiling at the user end and setting no_modify flag as True

from qiskit import QuantumCircuit, compiler
transpiled_circuit = compiler.transpile(circuit, backend, optimization_level=3)
job = backend.run(transpiled_circuit, shots=1000, no_modify=True)

Get Job Results

Job IDs are available https://portal.quantum.lrz.de/jobs. However, at the moment of writing, blocking issues make so that no more than 10 pages can be shown. In case you need to get back results from jobs not visible in the 10 pages, you can run the following script:

"""
Load jobs from a list of job ids and get results
"""

from mqp.qiskit_provider.job import MQPJob
from mqp.qiskit_provider import MQPProvider
from qiskit.providers import JobStatus


# Job IDs from the previous runs
# >>> add your Job IDs here as a list <<<

job_ids = []

# Replace <YOUR TOKEN HERE> with your MQP TOKEN
TOKEN = "<YOUR_TOKEN_HERE>"


def load_jobs_from_ids(jobids: list):
    jobs = []
    provider = MQPProvider(token=TOKEN)
    [backend] = provider.backends(name="AQT20")
    for jobid in jobids:
        job = MQPJob(backend.client, jobid)
        jobs.append(job)
    return jobs


if __name__ == "__main__":
    jobs = load_jobs_from_ids(job_ids)
    for job in jobs:
        if job.status() == JobStatus.DONE:
            print(f"Job ID : {job.job_id()}, Status : {job.status()}")
            result_dict = job.result().to_dict()
            print(f"Submission Time: {result_dict['timestamps']['submitted']}")
            print(f"Scheduling Time: {result_dict['timestamps']['scheduled']}")
            print(f"Completion Time: {result_dict['timestamps']['completed']}")
            print(f"Counts : {job.result().get_counts()}")
        else:
            try:
                counts = job.result().get_counts()
                print(f"Counts : {counts}")
            except RuntimeError as err:
                print(
                    f"Job ID : {job.job_id()}, Status : {job.status()}, Reason : {err}"
                )


What is the typical execution time of a job?

The answer is highly dependent on the circuit itself; as rule of thumb, one can estimate order of 50 000 shots per hour at best.