Skip to content

Conversation

itoko
Copy link
Contributor

@itoko itoko commented Jun 15, 2021

Summary

Add BIP-based mapping pass, which does layout and routing at once as described in https://arxiv.org/abs/2106.06446.

Closes #6437

Details and comments

BIPMapping pass is added as a routing pass while it actually does layout and routing at once (termed "mapping" to stand for "layout and routing"). It employs BIP (binary integer programming) to represent the mapping problem and relies on CPLEX solver to solve the problem, as implemented in BIPMappingModel. This introduces the dependencies to external libraries: docplex (for representing the BIP problem) and cplex (for solving the BIP problem). That implies the paid version of cplex may be needed to solve large BIP problems (roughly, mapping of circuits with more than 5 qubits).

  • Debug
  • Test more (including no cplex environment)
  • How to run unit tests (requiring CPLEX) on CI
  • Docstring
  • Lint
  • Release note

Optional:

  • Replace cplex.Cplex with docplex.mp.model.Model to improve readability
  • Add "error_rate" and "balanced" objective

Co-authored-by: Giacomo Nannicini (@gnannicini )

@itoko itoko requested review from manoelmarques, woodsp-ibm and a team as code owners June 15, 2021 10:47
@CLAassistant
Copy link

CLAassistant commented Jun 15, 2021

CLA assistant check
All committers have signed the CLA.

itoko added 3 commits June 28, 2021 17:26
Add release note

fix typos
Update docstring

fix typo
Copy link
Contributor

@gnannicini gnannicini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest one change that makes the mathematical model stronger. I forgot to detail it in the paper, but this is what we used in the code.

Comment on lines +214 to +229
for t in range(self.depth):
for (p, q) in self.gates[t]:
for (i, j) in self._arcs:
# Apply McCormick to y[t, p, q, i, j] == w[t, p, i] * w[t, q, j]
mdl.add_constraint(
y[t, p, q, i, j] >= w[t, p, i] + w[t, q, j] - 1,
ctname=f"McCormickLB_{p}_{q}_{i}_{j}_at_{t}",
)
mdl.add_constraint(
y[t, p, q, i, j] <= w[t, p, i],
ctname=f"McCormickUB1_{p}_{q}_{i}_{j}_at_{t}",
)
mdl.add_constraint(
y[t, p, q, i, j] <= w[t, q, j],
ctname=f"McCormickUB2_{p}_{q}_{i}_{j}_at_{t}",
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a better version of these constraints that is stronger.

Suggested:

    for t in range(self.depth-1):
            for (p, q) in self.gates[t]:
                for (i, j) in self._arcs:
                    # Stronger version of McCormick: gate (p,q) is implemented at (i, j) iff i moves to i or j, and j moves to i or j
                    mdl.add_constraint(
                        y[t, p, q, i, j] >= x[t, p, i, i] + x[t, p, i, j] + x[t, q, j, i] + x[t, q, j, j] - 1,
                        ctname=f"McCormickLB_{p}_{q}_{i}_{j}_at_{t}",
                    )
                    mdl.add_constraint(
                        y[t, p, q, i, j] <= x[t, p, i, i] + x[t, p, i, j],
                        ctname=f"McCormickUB1_{p}_{q}_{i}_{j}_at_{t}",
                    )
                    mdl.add_constraint(
                        y[t, p, q, i, j] <= x[t, q, j, i] + x[t, q, j, j],
                        ctname=f"McCormickUB2_{p}_{q}_{i}_{j}_at_{t}",
                    )
    # For last time step, use regular McCormick
    for (p, q) in self.gates[self.depth - 1]:
           for (i, j) in self._arcs:
               # Apply McCormick to y[self.depth - 1, p, q, i, j] == w[self.depth - 1, p, i] * w[self.depth - 1, q, j]
               mdl.add_constraint(
                    y[self.depth - 1, p, q, i, j] >= w[self.depth - 1, p, i] + w[self.depth - 1, q, j] - 1,
                    ctname=f"McCormickLB_{p}_{q}_{i}_{j}_at_last",
                )
                mdl.add_constraint(
                    y[self.depth - 1, p, q, i, j] <= w[self.depth - 1, p, i],
                    ctname=f"McCormickUB1_{p}_{q}_{i}_{j}_at_last",
                )
                mdl.add_constraint(
                    y[self.depth - 1, p, q, i, j] <= w[self.depth - 1, q, j],
                    ctname=f"McCormickUB2_{p}_{q}_{i}_{j}_at_last",
                )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the current constraints for several reasons:

  • they are the same as described in arxiv paper cited in the docstring (users would read this code with the paper in hand and would be confused if different-looking constraints show up)
  • they are fewer lines and easier to read (suggesting easier to understand)
  • there is no difference in performance between the suggested ones and the current ones (at least QV circuits in my env).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I can update the paper, and I am planning to do so -- the reason they are not indicated in the paper is oversight, not a deliberate choice.
  • True, the current constraints are easier to understand.
  • The proposed set of constraints is stronger. It is very well possible that one cannot observe the difference on smaller instances, as you say, but on larger QV circuits solved to optimality, the version that I am proposing is better. From an optimization standpoint, there is no reason to choose the weaker version. For large QV experiments, we need the best model we can get.

Copy link
Contributor Author

@itoko itoko Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd personally like to push the suggested change to a follow-up PR after the revised version of the paper is published in the future. I'd like to ask comments for others on this point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's a better/stronger version, let's update to it (follow-up PR is fine).

Copy link
Member

@1ucian0 1ucian0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments here and there, but LGTM in general.

itoko and others added 6 commits July 1, 2021 10:33
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Copy link
Member

@ajavadia ajavadia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@itoko itoko added the automerge label Jul 1, 2021
@mergify mergify bot merged commit cd4a712 into Qiskit:main Jul 1, 2021
@ajavadia ajavadia mentioned this pull request Jul 1, 2021
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: New Feature Include in the "Added" section of the changelog priority: high
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BIP routing pass
9 participants