question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DynamicalDecoupling creates sequences of delays not multiple of 16

See original GitHub issue

Environment

  • Qiskit Terra version: 0.20.0
  • Python version:
  • Operating system:

What is happening?

When running PassManager with DynamicalDecoupling the sequence of delays returned are not always multiple of 16 and the resulting circuit cannot be run on real hardware.

How can we reproduce the issue?

from qiskit.quantum_info import Pauli
from qiskit.opflow import PauliOp
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.synthesis import SuzukiTrotter
from qiskit import QuantumCircuit, transpile, IBMQ

# Dynamical decoupling
from qiskit.circuit.library import XGate
from qiskit.transpiler import PassManager, InstructionDurations
from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling

# load the backend
provider = IBMQ.load_account()
provider = IBMQ.get_provider(hub='ibm-q-internal', group='deployed')
backend = provider.get_backend('ibmq_mumbai')

layout =  [0,1,4]
shots = 100000

# data for the pass manager
instruction_durations = InstructionDurations.from_backend(backend)

# functions to create the circuit
def heisenberg_EO(n_qubits):
    """Construct Hamiltonian of 1-D Heisenberg chain with n_qubits sites.
    Return a list of matrices corresponding to the even-odd-splitting (154) in
    Childs2021.
    """
    # Three qubits because for 2 we get H_O = 0
    assert n_qubits >= 3
    def OPauli(s):
        return PauliOp(Pauli(s))
    def two_qubit_interaction(i, coeff):
        assert i < n_qubits - 1
        return (OPauli("I" * i + "XX" + "I" * (n_qubits - 2 - i)) +
                OPauli("I" * i + "YY" + "I" * (n_qubits - 2 - i)) +
                OPauli("I" * i + "ZZ" + "I" * (n_qubits - 2 - i)) +
                OPauli("I" * i + "Z" + "I" * (n_qubits - 1 - i)) *
                coeff)

    H_E = sum((two_qubit_interaction(i, 1)
               for i in range(0, n_qubits - 1, 2)))
    H_O = sum((two_qubit_interaction(i, 1)
               for i in range(1, n_qubits - 1, 2)))
    return [H_E, H_O]

def get_circuit(qubits, evo_time, trotter_steps):
    num_qubits = qubits

    # Obtain the matrices for Trotter - careful the algorithm returns sometimes the all zero matrix
    # minimize ||ms||_1 such that ||a||_1 \leq 2
    paulis = heisenberg_EO(num_qubits)

    evo_op = PauliEvolutionGate(paulis, evo_time, synthesis=SuzukiTrotter(order=2, reps=trotter_steps))
    return evo_op.definition

num_qubits = len(layout) # size of the system
evo_time = 1 # evolution time
m = 1 # number of trotter steps (reduced example)

qc = QuantumCircuit(num_qubits, num_qubits)
qc.h(list(range(num_qubits))) # dummy initial state
qc.append(get_circuit(num_qubits, evo_time, m), list(range(num_qubits)))
qc.measure(range(num_qubits), range(num_qubits))

# transpiled circuit
qct = transpile(qc, backend, initial_layout=layout, optimization_level=2)
# add dynamical decoupling
dd_sequence = [XGate(), XGate()]
pm = PassManager([ALAPSchedule(instruction_durations),
                  DynamicalDecoupling(instruction_durations, dd_sequence)])
qctd = pm.run(qct)

Printing the values of the DynamicalDecoupling class gives:

slack 9952
spacing [0.25, 0.5, 0.25]
taus [2488, 4976, 2488]
slack 11488
spacing [0.25, 0.5, 0.25]
taus [2872, 5744, 2872]

What should happen?

The taus should all be multiples of 16.

Any suggestions?

From DynamicalDecoupling:

# insert the actual DD sequence
taus = [int(slack * a) for a in self._spacing]
unused_slack = slack - sum(taus)  # unused, due to rounding to int multiples of dt
middle_index = int((len(taus) - 1) / 2)  # arbitrary: redistribute to middle
taus[middle_index] += unused_slack  # now we add up to original delay duration

Even if slack is a multiple of 16, whenever a is not an integer there is no assurance that int(slack*a) will also be a multiple of 16 (e.g. the a’s in the example above are not integers).

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
eggerdjcommented, Jan 13, 2022

16 is indeed specific to IBM hardware. Other hardware may use different multiples. We should avoid hard-coding multiples of 16, instead this should come from a configuration.

0reactions
mtreinishcommented, Feb 11, 2022

There is a separate pass to align with backend specified timing constraints: https://github.com/Qiskit/qiskit-terra/blob/main/qiskit/transpiler/passes/scheduling/instruction_alignment.py Can you try integrating that into your custom passmanager with dd as I expect it to solve the issue if it’s run after dd.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Robustness of dynamical decoupling sequences - arXiv
Dynamical decoupling (DD) is a promising approach that applies sequences of control pulses to the system in order to reduce the adverse effect...
Read more >
Robust dynamical decoupling - Journals
In the present review, we give an overview of this technique and compare different pulse sequences proposed earlier.
Read more >
qiskit.transpiler.passes.scheduling.padding.dynamical_decoupling ...
[docs]class PadDynamicalDecoupling(BasePadding): """Dynamical decoupling insertion ... is multiple of 16 dt but the gate length of 36 is not multiple of it.
Read more >
Noise-resilient quantum evolution steered by dynamical ...
At the same time, the qubit coherence time is elongated at least 30 fold. The design scheme does not require the dynamical decoupling...
Read more >
Effect of pulse error accumulation on dynamical decoupling of ...
delay.15,16 To suppress the effect of system-environment ... not imply good performance of the decoupling sequence,.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found