Advanced Settings
QPU Time Estimation
The creation of the QESEM job starts a process of estimating the QPU time required for the QESEM job. There are two types of QPU time estimation:
Transpilation Level | Description |
---|---|
Analytical | (Default) an upper bound of the QPU time is calculated without consuming any QPU usage. This estimation has a 30-minute resolution (for example, 30 minutes, 60 minutes, 90 minutes, and so forth). It is typically pessimistic and can only be obtained for single Pauli observables or sums of Paulis without intersecting supports (for example, Z0+Z1). It is primarily useful for comparing the complexity levels of different parameters provided by the user (accuracy, circuit compilations, and so on). |
Empirical | Although this option requires running a small number of circuits, it provides a significantly more accurate QPU time estimation. This estimation has a 5-minute resolution (for example, 20 minutes, 25 minutes, 30 minutes, and so on). Empirical time estimation will consume less than 10 minutes of QPU time. |
To obtain empirical time estimation:
job = qedma_client.create_job(
empirical_time_estimation = True,
circuit = circuit,
observables = qedma_api.Observable({"Z1": 1.0, "Z0,Z3": 0.3}),
precision = 0.1,
backend = "ibm_fez",
description = "my qesem job",
)
Max Execution Time
When starting the QESEM job (start_job
), QESEM Allows you to limit the QPU time used for the entire QESEM execution. Example:
qesem_client.start_job(
job_id = job.job_id,
max_qpu_time = datetime.timedelta(minutes=123)
)
Since the final QPU time required to reach the target accuracy is determined dynamically during the QESEM job, this parameter enables you to limit the cost of the experiment. If the dynamically-determined QPU time is shorter than the time allocated by the user, this parameter will not affect the experiment. The max_qpu_time
parameter is particularly useful in cases where the analytical time estimate provided by QESEM before the job starts is too pessimistic and the user wants to initiate a mitigation job anyway. After the time limit it reached, QESEM stops sending new circuits. Circuits that have already been sent continue running (so the total time may surpass the limit by up to 30 minutes), and the user receives the processed results from the circuits that ran up to that point. If you want to apply a QPU time limit shorter than the analytical time estimate, consult with Qedma to obtain an estimate for the accuracy achievable within the time limit.
Transpilation Level
After a circuit is submitted to QESEM, it automatically prepares several alternative circuit transpilations and chooses the one that minimizes QPU time. For instance, alternative transpilations might utilize Qedma-optimized fractional RZZ gates to reduce the circuit depth. Of course, all transpilations are equivalent to the input circuit, in terms of their ideal output. To exert more control over the circuit transpilation, set the transpilation_level
:
job = qedma_client.create_job(
circuit = circuit,
observables = observables,
precision = 0.1,
circuit_options = qedma_api.CircuitOptions(
transpilation_level = 0
),
backend = "ibm_fez",
)
Transpilation Level | Description |
---|---|
1 | (Default) Prepares several alternative transpilations and chooses the one that minimizes QPU time. Barriers may be modified in the layerification step. |
0 | Minimal transpilation: the mitigated circuit will closely resemble the input circuit structurally. Circuits provided in level 0 should match the device connectivity and should be specified in terms of the following gates: CX, Rzz(α), and standard single-qubit gates (U, x, sx, rz, and so on). Barriers will be respected in the layerification step. |
Note
Barriers operations are typically used to specify the layers of two-qubit gates in quantum circuits. In level 0, QESEM preserves the layers specified by the barriers. In level 1, the layers specified by the barriers are considered as one transpilation alternative when minimizing QPU time.
Execution Mode
Using the execution_mode
flag, the user can choose to run the QESEM job in either a dedicated IBM session or across multiple IBM batches:
qedma_client.start_job(
job_id = job.job_id,
max_qpu_time = datetime.timedelta(minutes=123),
options = qedma_api.JobOptions(
execution_mode = qedma_api.ExecutionMode.BATCH
),
)
Execution Mode | Description |
---|---|
BATCH | (Default) In batch mode, the QPU is released during classical computations, leading to lower QPU usage. As batch jobs typically span a longer period, there is a greater risk of hardware drifts; QESEM incorporates measures to detect and compensate for drifts, retaining reliability over extended runs. |
SESSION | Sessions are more expensive but result in a shorter time-to-result. Once the session begins, the QPU is reserved exclusively for the QESEM job. The usage calculation includes both the time spent on QPU execution and the associated classical computations (performed by QESEM and IBM). The QESEM Qiskit Function takes care of creating and closing the session automatically. For users with unlimited access to QPUs (for example, on-premises setups), it is recommended to use session mode for faster QESEM execution. |
Parameterized Circuit 
Many quantum algorithms require running the same circuit with different parameters. Running multiple QESEM jobs for each circuit variation results in significant QPU time overhead, as each execution includes characterization and calibration. Instead, providing a parameterized circuit allows for a single QESEM execution, performing characterization and calibration only once, thereby saving QPU time.
circ = qiskit.QuantumCircuit(4)
circ.x(3)
for i in range(2):
circ.rx(qiskit.circuit.Parameter(f"param{i}"), i)
circ.cx(0, 1)
circ.cx(2, 3)
qedma_client.create_job(
circuit = circ,
observables = (
qedma_api.Observable({"X1": 1.0, "Z0,Z3": 0.3}),
qedma_api.Observable({"X2": 1.0, "Z0,Z3": 0.3})
),
parameters = {"param0": (0.5, 0.0), "param1": (0.1, 0.6)},
precision = 0.1,
backend = "ibm_fez",
precision_mode = qedma_api.PrecisionMode.CIRCUIT,
)
param0
and param1
with two sets of parameters
Circuit Instance | param0 | param1 | Observable |
---|---|---|---|
1 | 0.5 | 0.1 | 1.0X1 + 0.3Z0Z3 |
2 | 0.0 | 0.6 | 1.0X2 + 0.3Z0Z3 |
When executing a parameterized circuit, QESEM can refer to the specified precision
in two ways. You can control it by setting the precision_mode
flag:
Precision Mode | Description |
---|---|
CIRCUIT | QESEM will target the specified precision for each circuit. |
JOB | QESEM will treat the precision as a precision for the sum of the expectation values. |
Note
- QESEM currently supports only a single observable per instance of the circuit.
- All circuit parameters should be in the
parameters
dict, the keys can be either str or qiskit.circuit.Parameter. - The number of values for each parameter should be the same (defines the number of circuits).