Closed yaelbh closed 2 years ago
I prefer having unified mechanism for all composites, i.e. transpile sub experiments individually and combine them later on the physical circuit as I wrote in #380 . This is very simple to understand (as you mentioned), and user may want to apply different transpile options to each sublattice (e.g. different dynamical decoupling, maybe!). I don't think current circuit merging logic is correct because we should not merge circuit before we guarantee all circuits are in physical representation, i.e. transpile. Indeed Qiskit is too much agnostic to logical / physical representation of circuit -- we should have metadata at least, but this is not the scope of this issue.
As you mentioned, if user explicitly set some transpile or run option to the composite experiment, this can override sub experiment configurations (no validation, for sake of simplicity, just one-way override). We also need to remove all predefined options from the base classes.
@nkanazawa1989 https://github.com/Qiskit/qiskit-experiments/issues/535#issuecomment-975643237: I've presented the idea of sub-experiment transpilations to the Haifa team. They raised a concern that some operations may require a holistic view of the entire circuit. As concrete examples:
Regarding ancilla issue, we should transpile with coupling map limited to set of physical qubits. If I understand correctly, composite is just a macro so that
exp = CompositeExperiment([exp1, exp2, exp3])
expdata = exp.run()
sub_data1 = expdata.child_data(0)
sub_data2 = expdata.child_data(1)
sub_data3 = expdata.child_data(2)
assert sub_data1 = exp1.run()
assert sub_data2 = exp2.run()
assert sub_data3 = exp3.run()
However, if you do some kind of holistic compilation, that results in different outcome from doing individual experiment as different jobs. If one needs holistic view of your experiment, this should be a dedicated experiment that takes all qubits, rather than composite.
However, if you do some kind of holistic compilation, that results in different outcome from doing individual experiment as different jobs. If one needs holistic view of your experiment, this should be a dedicated experiment that takes all qubits, rather than composite.
This is a good and important point. The only case where it's not obvious is when the transpiler must do something globally in order to not lose correctness. Alignment is an example. I can't think of more examples, and we can do special handling for this specific case. The question is if we don't have to worry about other stuff that we're not aware about, or even stuff that will be added in the future.
What is the alignment? I think measurement instruction can be run individually, i.e. at different time, on each channel (previously not due to the trigger requirement). Probably we need to check with hardware.
I think measurement instruction can be run individually, i.e. at different time, on each channel
This looks right. I checked with this code:
from qiskit import IBMQ, QuantumCircuit, transpile
backend = IBMQ.load_account().backend.ibmq_lima
circ1 = QuantumCircuit(2, 2)
circ1.delay(100, 0, "us")
circ1.measure(0, 0)
circ1 = transpile(circ1, backend)
circ2 = QuantumCircuit(2, 2)
circ2.delay(200, 1, "us")
circ2.measure(1, 1)
circ2 = transpile(circ2, backend)
circ = circ1.compose(circ2)
print(circ)
res = backend.run(circ).result()
print(res.get_counts())
And the output is fine:
┌───────────────────┐┌─┐
q_0 -> 0 ┤ Delay(450000[dt]) ├┤M├───
├───────────────────┤└╥┘┌─┐
q_1 -> 1 ┤ Delay(900000[dt]) ├─╫─┤M├
└───────────────────┘ ║ └╥┘
ancilla_0 -> 2 ──────────────────────╫──╫─
║ ║
ancilla_1 -> 3 ──────────────────────╫──╫─
║ ║
ancilla_2 -> 4 ──────────────────────╫──╫─
║ ║
c: 2/══════════════════════╩══╩═
0 1
{'00': 3824, '01': 88, '10': 83, '11': 5}
I intentionally tried without all the special transpilation flags (alignment
and shceduling_method
). Are they not required anymore? Can we remove them from the code of T1
and T2Ramsey
?
Stale, closing
What is the expected behavior?
Continuing discussions from #380, #535, #543. I suggest the following mechanism:
_set_backend
):exp
, gather the transpile options of all its children.exp
, then raise an error.exp
, where, in case of disagreement ofexp
with the children on an option,exp
wins. (This means also that options set by the user win).As usual, I'm concerned that such a mechanism will be too complex for users to understand and for developers to understand and maintain. One immediate example that comes to mind, is that in order for this to work correctly, we'll probably have to take care of options that are usually defaulted by the
transpile
andrun
methods: for example, we'll have to explicitly set the measurement level in all the experiments, even when it's 2. And I guess that there are many more similar subtleties.On the other hand, this suggestion hopefully covers the different aspects that were raised in the discussions.