Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LookaheadSwap "forgets" quantum register names #2066

Closed
1ucian0 opened this issue Apr 3, 2019 · 7 comments
Closed

LookaheadSwap "forgets" quantum register names #2066

1ucian0 opened this issue Apr 3, 2019 · 7 comments
Projects
Milestone

Comments

@1ucian0
Copy link
Member

1ucian0 commented Apr 3, 2019

Information

  • Qiskit Terra version: master

What is the current behavior?

In : qr1 = QuantumRegister(1, 'aQRname1') 
    ...: qr2 = QuantumRegister(2, 'aQRname2') 
    ...: cr = ClassicalRegister(3, 'classic') 
    ...: circuit = QuantumCircuit(qr1, qr2, cr) 
    ...: circuit.cx(qr2[0], qr2[1]) 
    ...: circuit.measure(qr1[0],cr[0]) 
    ...: circuit.measure(qr2[0],cr[1]) 
    ...: circuit.measure(qr2[1],cr[2]) 
    ...: dag = circuit_to_dag(circuit) 
    ...:  
    ...: pass_ = LookaheadSwap(CouplingMap([[0, 1], [0, 2]])) 
    ...: after = pass_.run(dag)                                                                                                                        

In : print(dag_to_circuit(after))                                                                                                                  
             ┌─┐        ┌─┐   
     q_0: |0>┤M├─X───■──┤M├───
             └╥┘ │   │  └╥┘   
     q_1: |0>─╫──X───┼───╫────
              ║    ┌─┴─┐ ║ ┌─┐
     q_2: |0>─╫────┤ X ├─╫─┤M├
              ║    └───┘ ║ └╥┘
classic_0: 0 ═╩══════════╬══╬═
                         ║  ║ 
classic_1: 0 ════════════╩══╬═
                            ║ 
classic_2: 0 ═══════════════╩═

What is the expected behavior?


In : print(dag_to_circuit(after))                                                                                                                  
               ┌─┐        ┌─┐   
aQRname1_0: |0>┤M├─X───■──┤M├───
               └╥┘ │   │  └╥┘   
aQRname2_0: |0>─╫──X───┼───╫────
                ║    ┌─┴─┐ ║ ┌─┐
aQRname2_1: |0>─╫────┤ X ├─╫─┤M├
                ║    └───┘ ║ └╥┘
classic_0: 0 ═══╩══════════╬══╬═
                           ║  ║ 
classic_1: 0 ══════════════╩══╬═
                              ║ 
classic_2: 0 ═════════════════╩═

Suggested solutions

@ajavadia ajavadia added this to To do in Transpiler via automation Apr 3, 2019
@ajavadia ajavadia added this to the 0.8 milestone Apr 3, 2019
@ajavadia
Copy link
Member

ajavadia commented Apr 3, 2019

We need to decide here when the circuit becomes "physical". Whether the layout keeps existing in the property set and every pass consults it, or it just gets applied and further passes work with a flat register.

@itoko
Copy link
Contributor

itoko commented Apr 3, 2019

I think this issue is not discussing when the circuit becomes "physical". Both of the circuits above are "semantically" physical. But they are "syntactically" different. Current LookaheadSwap output uses physical qubit register names. Proposed output (same as BasicSwap) uses virtual qubit register names. I like the LookaheadSwap spec since the circuit is "semantically" physical so it is natural to use the physical syntax i.e. physical qubit register names. Using the virtual register name may be confusing. In fact, I think that's the reason why I and @ajavadia misunderstood BasicSwap output a circuit before applying ApplyLayout pass. See also #2044.

@itoko
Copy link
Contributor

itoko commented Apr 4, 2019

@1ucian0 @ajavadia I found an example that shows why LookaheadSwap spec (Spec-A) is the best (we should forget about the virtual quantum register names).
Please look at the arguments of measurements below.
In the original circuit, we specified measurement result of v1 is stored in c1.
However, in the Spec-B, measurement result of v1 is stored in c0. Isn't this confusing? In this sense, "v1" in the output is no more equal to the original v1. It is a physical qubit q1, isn't it?

[Original circuit]
CNOT(v1, v2)
Measure(v1, c1)
Measure(v2, c2)

 v0:-------M(v0->c0)

 v1:---.---M(v1->c1)
       |
 v2:--(+)--M(v2->c2)

[Spec-A: Semantically and syntactically physical circuit]
#current LookaheadSwap's output
SWAP(q0, q1)
CNOT(q0, q2)
Measure(q0, c1)
Measure(q2, c2)

 q0:--X---.---M(q0->c1)
      |   |
 q1:--X---|---M(q1->c0)
          |
 q2:-----(+)--M(q2->c2)

(no need for initial_layout any more)

[Spec-B: Semantically physical but syntactically virtual circuit]
#Proposed by , current BasicSwap's output
SWAP(v0, v1)
CNOT(v1, v2)
Measure(v0, c1)
Measure(v2, c2)

 v0:--X---.---M(v0->c1)
      |   |
 v1:--X---|---M(v1->c0)
          |
 v2:-----(+)--M(v2->c2)

+ Initial layout: {v0: q0, v1: q1, v2: q2} (is necessary just for syntax mapping)

In the original circuit, there "was" a one-to-one mapping between virtual qubits and classical registers, v0<->c0, v1<->c1, v2<->c2. Each virtual qubit stores computational results and is projected to classical bit at last. But this relation is destroyed by mapping in general. But users will not care about it. Because they can find what they want to compute by classical register names. That's why we can name classical registers. There is no meaning to carry one-to-one relationship between virtual qubits and classical registers after swap mapping. But users might expect it wrongly and be confused (as I did so) if we name the quantum register as virtual qubits. If we name the quantum register as physical qubits, we'll have no such concern. (I guess @kdk is thinking Spec-A is better as well as me.)

@ajavadia
Copy link
Member

ajavadia commented Apr 4, 2019

@itoko I agree with you, I will go one step further and say that the Swapper passes should also consume physical circuits (i.e. their job is to take a circuit and a coupling map and make them compatible, not to also care about a layout object). In that sense, I think the ApplyLayout pass should be run after layout selection and before swappers. ApplyLayout marks the place where we have embedded a virtual circuit onto a device.

The only downside is that it would be hard to track that for example given a 5 qubit physical circuit, qubits 0, 1, 3 correspond to the original virtual qubits and qubits 2, 4 were added ancilla. This is information that is stored in the layout. So I think we need a way to easily visualize/report the correspondence between a physical circuit and the original virtual qubits.

But I think the benefits are greater. In this process, we simplify passes. They don't have to constantly consult a Layout in order to do their job. They will simply work with the circuit they are given.

A few points related to your terminology:

  • I think your notion of "semantic" and "syntactic" physical circuits are a bit hard to define. Because when applying a Layout, you may permute/reorder wires --- MSB may become LSB. So one could say that the semantics of the circuit have changed too (not just labels).
  • We should be careful not to say that physical qubits are named "q". They are just defined by an integer 0,..., n-1, names are given by users. I think we should move towards a place where we can represent circuit wires as being integers, and naming them be optional.

@itoko
Copy link
Contributor

itoko commented Apr 5, 2019

@ajavadia I agree with your proposal - Swapper passes not only return a physical circuit but also consume a physical circuit.

At first, in our discussion on #2044, I found we used the term ApplyLayout pass in the different meanings. From now on, I'll follow your definition: The ApplyLayout pass will only relabel and permute qubits (rename of qubits from virtual ones to physical ones).

I found one more benefit to ApplyLayout before swapper. In some circuits, ApplyLayout solve the mapping problem. In such a case, no Swapper pass is necessary to be run.

Regarding downside example, I think this is not a downside. In the physical circuit after swap mapping, we cannot say these qubits are ancilla. For example, if qubits 2 is not connected with qubit 1 and we have cx between 1 and 2, we may be swap qubit 2 and the other qubit (say 3). I this case, we cannot say qubit 2 is an ancilla any longer (qubit 3 will act as ancilla afterwards). In order to track such information, we need to store all layout changes during swap mapping (That's why I thought the definition of ApplyLayout more complicated). And I think it's almost impossible. Am I misunderstanding anything?

If we accept your proposal, Layout should be updated to be able to handle mapping of physical qubits to physical qubits. (It may be somewhat difficult since we have no Qubit classes :()

Excuse me for my inaccurate terminology. Regarding physical qubits name. Until we can use integers as names, what should we use? QuantumRegister(n_qubits)? QuantumRegister(n_qubits, '')? Or anything else?

@itoko
Copy link
Contributor

itoko commented Apr 11, 2019

@ajavadia Excuse me, but I had second thought. Swapper passes should consume a virtual circuit and return a physical circuit. More generally, Mapper passes should consume a virtual circuit and return a physical circuit. And ApplyLayout pass can be seen a special Mapper pass that cannot always solve the mapping problem.

I think the definition of physical circuit is circuit with no crossing wires. That means we cannot remove swap gates by replacing swap gates to wire crossing. And a swap gate swaps two virtual qubits between two straight wires (=physical qubits). The definition of virtual circuit is a circuit before physical embedding. So by definition, the input of mapping (=Swapper passes) must be a virtual circuit, whatever it has qubits named like physical qubits. If ApplyLayout cannot solve a mapping problem of a virtual circuit, i.e. fails to provide physical embedding, the circuit should still stay as a virtual circuit. We should forget about wrongly embedded physical circuit.

Layout should represent mapping between virtual qubits and physical ones (no need to support physical<->physical, since it is not a mapping it's just a relabeling).

@ajavadia
Copy link
Member

This is no longer an issue following #2584

Transpiler automation moved this from To do to done Jun 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Transpiler
  
done
Development

No branches or pull requests

4 participants