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

Add BackendV2 abstract class #5885

Merged
merged 130 commits into from
Dec 1, 2021
Merged

Add BackendV2 abstract class #5885

merged 130 commits into from
Dec 1, 2021

Conversation

mtreinish
Copy link
Member

@mtreinish mtreinish commented Feb 19, 2021

Summary

This commit adds a new abstract class that adds a new version of the
backend abstract class. The primary changes being made in this class are
that instead of using BackendConfiguration for immutable characteristics
of the backend those are instead exposed as read only attributes of the
Backend object itself. This also takes some time to improve how we
represent some core data about a backend. The primary example of this is
that basis gates are no longer a list of names but contained inside a new
Target class which represents a compiler target for Qiskit.

Details and comments

TODO:

  • Add optional attributes for common pulse and timing configuration properties, we need to decouple what IBMQ returns from a common set of properties. (IBMQ backends can still return extra fields which are IQX specific, not everything needs to be in the base class only things that the rest of terra needs)
  • Come up with an interface for properties, including figuring out a native object model to use (not a python object mapping the iqx api format like BackendProperties) for representing the data
  • Come up with a similar interface for pulse defaults

Longer term follow ups (these will need to be handled in a backendV3 and JobV2):

  • Add job manager concept for splitting jobs automatically
  • Add support for running parameterized circuits with a bind table
  • Based on Add defined phases to the PassManager #5978 add support for transpiler hooks in a backend (ie having transpiler passes in a backend object)
  • Standardize mechanism for discovery of backend result type (statevector vs unitary vs counts, etc)
  • We should start update the data model used in the pass manager to assume Gate and Instruction objects instead of names

@mtreinish mtreinish added the on hold Can not fix yet label Feb 19, 2021
@mtreinish mtreinish requested review from chriseclectic, jyu00 and a team as code owners February 19, 2021 22:09
@1ucian0 1ucian0 marked this pull request as draft February 23, 2021 10:10
@mtreinish mtreinish mentioned this pull request May 11, 2021
7 tasks
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Jun 14, 2021
The changes made in Qiskit#6543 were unecessary and add ibm backend specific
options to common interfaces in terra. This commit reverts Qiskit#6543 so it
can be isolated to just the ibmq provider as the new options added in
it are not common to all providers and isolated to just ibm backends.
The changes made in Qiskit#6543 should have been done directly in the ibm
provider and no changes to terra are actually needed here. Terra already
provides all the functionality to enable the provider to add custom options
like this. A provider can advertise the new run time option via the
backend's `Options` object, expose the backend configuration option as
a custom attribute at construction time, and pass the setting from the
options to assemble so it gets set in the qobj config appropriately
without requiring any changes from terra. However, this isn't all
necessarily clear as the interface for `BackendV1` was primarily
inherited from `BaseBackend` which didn't have this level of flexibility
and doesn't make the distinction between required, optional, and custom
options and backend attributes super clear. This is something we can
hopefully address in the next version of the backend interface
`BackendV2` (ideas for this are being collected in Qiskit#5885).

This reverts commit 6d605a0.
mergify bot added a commit that referenced this pull request Jun 15, 2021
The changes made in #6543 were unecessary and add ibm backend specific
options to common interfaces in terra. This commit reverts #6543 so it
can be isolated to just the ibmq provider as the new options added in
it are not common to all providers and isolated to just ibm backends.
The changes made in #6543 should have been done directly in the ibm
provider and no changes to terra are actually needed here. Terra already
provides all the functionality to enable the provider to add custom options
like this. A provider can advertise the new run time option via the
backend's `Options` object, expose the backend configuration option as
a custom attribute at construction time, and pass the setting from the
options to assemble so it gets set in the qobj config appropriately
without requiring any changes from terra. However, this isn't all
necessarily clear as the interface for `BackendV1` was primarily
inherited from `BaseBackend` which didn't have this level of flexibility
and doesn't make the distinction between required, optional, and custom
options and backend attributes super clear. This is something we can
hopefully address in the next version of the backend interface
`BackendV2` (ideas for this are being collected in #5885).

This reverts commit 6d605a0.

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
@ajavadia
Copy link
Member

ajavadia commented Jul 1, 2021

Let's discuss how we can define an instruction set to cover #5774, and to replace the following with something general:

  • config.basis_gates
  • config.supported_instruction
  • config.custom_instruction (Aer)
  • config.gates

@ajavadia
Copy link
Member

ajavadia commented Jul 1, 2021

Add job manager concept for splitting jobs automatically

This seems like a provider responsibility. The backend should just run what is given to it.
I think we should move towards making the backend simpler not more complicated. The most basic backend.run() implementation should be to just run a single circuit. Note that some backends don't even allow running multiple circuits (qiskit-community/qiskit-ionq#70). If the provider wants to allow multi-circuit runs, then great, but that should be built as something separate to backend.run() I think. It will be a breaking change, but since it's V2 I don't feel too bad about it :)

@ajavadia ajavadia added this to the 0.20 milestone Jul 1, 2021
@ajavadia ajavadia added the ISA ISA-related issues label Jul 13, 2021
@kdk kdk modified the milestones: 0.20, 0.19 Jul 20, 2021
This commit adds a new abstract class that adds a new version of the
backend abstract class. The primary changes being made in this class are
that instead of using BackendConfiguration for immutable characteristics
of the backend those are instead exposed as read only attributes of the
Backend object itself. This also takes some time to improve how we
represent some core data about a backend. The primary example of this is
that basis gates are no longer a list of names but instead a list of
Gate objects.
This commit reworks the GateMap class to be an internal dict of gate
instances to qargs (with optional properties) instead of building a
graph. The graph representation was inherently limited in that it
couldn't describe multiqubit gates involving > 2 qubits.
This commit finishes by adding the defined optional methods for querying
the equivalent of the backend properties on the new backend v2
interface. The per gate properties were already defined in the gate map
class as optional fields for each gate entry so this defines methods for
the per qubit fields (t2, t1, freq, readout error and duration). While
not every backend supports these fields they're common ones that most
could implement (assuming the data is available). For any other backend
properties they can be custom fieldss in a subclass.
ajavadia
ajavadia previously approved these changes Nov 30, 2021
@mtreinish mtreinish linked an issue Nov 30, 2021 that may be closed by this pull request
Co-authored-by: Rathish Cholarajan <rathishc24@gmail.com>
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Dec 1, 2021
The RZXCalibrationBuilder and EchoRZXWeylDecomposition transpiler passes
were previously taking BaseBackend instances as arguments. Besides that
being a deprecated class which will be removed soon, it also is
incorrect because backend objects are not guaranteed to be pickleable so
when a pass manager runs in parallel processes this will cause an error.
This was never caught because these passes aren't part of any default
pass managers and their tests don't include running them as part of
transpile().

To fix this passes typically take the properties of a backend they
require. This is being reworked for BackendV2 in Qiskit#5885 so a target
object can be used to encapsulate the model of a backend so we have a
single data structure to pass around, but until that is the minimum
backend version we need to also support taking the individual components
for BackendV1 and BaseBackend.

This commit changes the pass constructors to take only use the parameters
from the backend object used in the pass internals and stop requiring a
backend object be used to construct an instance of either pass.
@mergify mergify bot merged commit 3694fff into Qiskit:main Dec 1, 2021
@mtreinish mtreinish deleted the backends-v2 branch December 1, 2021 14:25
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Dec 1, 2021
As a follow-on to Qiskit#5885 this commit updates the top level
qiskit.providers module documentation for BackendV2. This primarily
consists of two things, updating the writing a provider section to use
BackendV2 instead of BackendV1 and adding a migration section on user
facing changes between BackendV1 and BackendV2.
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Dec 1, 2021
In Qiskit#5885 we added the next version of the abstract Backend interface
BackendV2 which added the concept of a Target which represents a
compiler target for the transpiler. It contains all the information
about the constraints of a backend for the compiler to use and replaces
the combination of basis_gates, coupling_map, etc and expands the
representation to model more complex devices. However, in Qiskit#5885 we only
introduced the interface and didn't modify the transpiler to use the
Target natively or any of the extra information it contains. This commit
is the start of the process of updated the transpiler to work with a
target natively. To start if a backend has a target that is now passed
through from transpile to the passmanager_config so we can start passing
it directly to passes as we enable it. Then the basis translator is
updated to work natively with a target instead of the basis gates list
it used before. In addition to using a target directly support is added
for heterogeneous gate sets so that target instructions can work on only
a subset of qargs.

Building off this in the future There are additional features in target
that we might want to expand support for in the BasisTranslator in the
future, such as supporting custom variants of the same gate, or handling
fixed angle rotation gate variants, etc.
mergify bot pushed a commit that referenced this pull request Dec 1, 2021
…7331)

* Fix arguments for RZXCalibrationBuilder and EchoRZXWeylDecomposition

The RZXCalibrationBuilder and EchoRZXWeylDecomposition transpiler passes
were previously taking BaseBackend instances as arguments. Besides that
being a deprecated class which will be removed soon, it also is
incorrect because backend objects are not guaranteed to be pickleable so
when a pass manager runs in parallel processes this will cause an error.
This was never caught because these passes aren't part of any default
pass managers and their tests don't include running them as part of
transpile().

To fix this passes typically take the properties of a backend they
require. This is being reworked for BackendV2 in #5885 so a target
object can be used to encapsulate the model of a backend so we have a
single data structure to pass around, but until that is the minimum
backend version we need to also support taking the individual components
for BackendV1 and BaseBackend.

This commit changes the pass constructors to take only use the parameters
from the backend object used in the pass internals and stop requiring a
backend object be used to construct an instance of either pass.

* Deprecate backend for RZXCalibrationBuilder instead of removing
mergify bot pushed a commit that referenced this pull request Dec 1, 2021
* Update top level provider documentation for BackendV2

As a follow-on to #5885 this commit updates the top level
qiskit.providers module documentation for BackendV2. This primarily
consists of two things, updating the writing a provider section to use
BackendV2 instead of BackendV1 and adding a migration section on user
facing changes between BackendV1 and BackendV2.

* Apply suggestions from code review

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>

* Update qiskit-aqt example wording

* Fix lint

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
mergify bot pushed a commit that referenced this pull request Dec 4, 2021
* Start making the BasisTranslator Target/BackendV2 aware

In #5885 we added the next version of the abstract Backend interface
BackendV2 which added the concept of a Target which represents a
compiler target for the transpiler. It contains all the information
about the constraints of a backend for the compiler to use and replaces
the combination of basis_gates, coupling_map, etc and expands the
representation to model more complex devices. However, in #5885 we only
introduced the interface and didn't modify the transpiler to use the
Target natively or any of the extra information it contains. This commit
is the start of the process of updated the transpiler to work with a
target natively. To start if a backend has a target that is now passed
through from transpile to the passmanager_config so we can start passing
it directly to passes as we enable it. Then the basis translator is
updated to work natively with a target instead of the basis gates list
it used before. In addition to using a target directly support is added
for heterogeneous gate sets so that target instructions can work on only
a subset of qargs.

Building off this in the future There are additional features in target
that we might want to expand support for in the BasisTranslator in the
future, such as supporting custom variants of the same gate, or handling
fixed angle rotation gate variants, etc.

* Deduplicate computation of non-global operations

The modifications to the BasisTranslator needed to compute operations in
the basis which weren't global for a particular target and accomplished
this via a dedicated helper function in the pass module. However the
BackendV2 class had an identical function for accomplishing this so it
could log a warning when basis gates were queried. This commit
deduplicates them and creates a dedicated method on the target for
returning the list (and caches it so it's only computed once per target).

* Add missing check for a dag calibration on the target path

* Rename extra_basis_transforms -> qarg_local_basis_transforms

* Make GateDirection and CheckGateDirection Target aware too

In debugging the basis translator changes we realized that we should be
relying on the GateDirection pass to fix directionality on non-symmetric
2q gates instead of trying to handle it natively in the basis translator
for now. To do this with a target we need to make the GateDirection and
CheckGateDirection passes target aware and update the basis translator
to treat all 2q gates as symmetric. This commit makes this change and
updates the preset pass managers to pass targets to GateDirection and
CheckGateDirection (also updates the rule determining if we need to run
them to leverage the target not the coupling map).

* Handle working with a non-global 1q basis

In the case of a non-global 1q basis where there are 1q gates only
available on a subset of qubits the basis translator was not correctly
able to translate multi-qubit gates. This was due to how the local basis
search was done just on the global target basis gates and the local
target basis gates for that argument, with multi-qubit gates the
translations also typically involve a 1q rotation. But if there are no
global 1q gates those rotation gates can't be translated and the search
fails. To address this the 1q local gates for the individual qubits in
the multi-qubit argument are added to the local search for non-global
multi-qubit gates.

* Also use target for gate direction in level 0

* Add release notes

* Consider all non-local subset operations for multiqubit non local gates

* Update qiskit/providers/backend.py

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>

* Finish incomplete strict_direction docstring

* Adjust tests to be fp precision tolerant

* Relax tests further for windows

* Update qiskit/transpiler/target.py

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>

* Correct detection of non-global ops with strict_direction=False

Co-authored-by: georgios-ts <45130028+georgios-ts@users.noreply.github.com>

* Fix handling of non-local subset searching

* Simplify target path in gate direction pass

* Rename extra_source_basis -> local_source_basis

* Rename incomplete_basis -> non_global_operations

* Rename qarg_with_incomplete -> qargs_with_non_global_operation and incomplete_source_basis -> qargs_local_source_basis

* Update target handling in transpile()

This fixes 2 issues found in review with the the transpile() functions
handling of target. First if a target kwarg is passed by a user that
target will be used instead of the backend for not just the target but
also all derived quantities (such as coupling_map and basis_gates).
Also previously the backend_properties field was not being correctly
built from a target (both for a backendv2 or a standalone target). So a
converter helper function was added to go from a target and build a
BackendPropeties object from the data contained in the target. This will
enable noise aware transpilation until the transpiler passes are all
target aware.

* Calculate qargs with non global operation once per pass instance

* Expand docstring to include non-global operation behavior description

* Add test assertion that it matches the target

* Add GateDirection to the optimization loop for level 3

Optimization level 3 is different from the other lower optimization
levels because it uses unitary synthesis by default. The unitary
synthesis pass is basis and coupling map to optimize the synthesized
circuit for a unitary to be hardware efficient. However when using a
target the basis gates and coupling map don't give a complete picture of
the device constraints (mainly the non-global gates if any). To account
for this we need to run the gate direction pass after unitary synthesis
to correct an incorrect decision the unitary synthesis pass might make
based on it's incomplete data. Once UnitarySynthesis is target aware we
probably do not require this anymore.

* Add tests of 5q ghz on non-linear non-global target with different entangling gates

* Use frozenset instead of tuple for local search and transformation tracking

* Fix copy paste error for gate error in _target_to_backend_properties

* Apply suggestions from code review

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>

* Only run gate direction in level 3 with a target

* Move target overrides inside _parse_transpile_args()

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>
Co-authored-by: georgios-ts <45130028+georgios-ts@users.noreply.github.com>
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 ISA ISA-related issues priority: high
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement next version of the provider interface