-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Remove qargs/cargs/circuit from instructions, in favor of circuit keeping context #1816
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
aa5a407
to
c53b52c
Compare
This was referenced Mar 9, 2019
03a59d9
to
620a0ec
Compare
5a86f2a
to
42556ba
Compare
9fc3bdd
to
3968684
Compare
This was referenced Mar 13, 2019
c0f7fb7
to
6dce245
Compare
d79b633
to
73a3477
Compare
kdk
approved these changes
Apr 3, 2019
This was referenced Apr 4, 2019
This was referenced Apr 4, 2019
maddy-tod
added a commit
to maddy-tod/qiskit-terra
that referenced
this pull request
Apr 5, 2019
mtreinish
added a commit
to mtreinish/qiskit-core
that referenced
this pull request
Apr 15, 2019
In Qiskit#1816 as part of the larger restructure the dag_to_circuit() and circuit_to_dag() converter were modified to use a copy.deepcopy() instead of native Instruction/Gate constructors. This caused a large performance regressions (around 3x in the worst case) in certain transpile calls. To avoid this performance penalty this commit reintroduces a private function to call the class constructor for each input gate to create a new instance of the object to append to the output. This removes the deepcopy usage and should fix the performance regression. Fixes Qiskit#2131
kdk
pushed a commit
that referenced
this pull request
Apr 16, 2019
* Start of refactor * More updating of variable names * Refactored barrier before final measurements to remove a sort and several add/remove from the DAG * Updated an import * Updated the bits that rely on DAGNode equality to use the new equality method * Updated to use nodes_on_wire and .remove for the list * Fixed an issue with the difference between python 3.5 and 3.6 by adding a new method to the DAG which returns the successors in order * Added in a new pass that merges barriers together - still needs testing * Fixed a failing test - the condition wasn't being copied over * Updated import to make it non cyclic * Added in some testing for MergeAdjacentBarriers pass * Included the test file this time * Updated based on review comments - added in more comments and fixed sort * Updated to work with #1816 * Fixed lint * Updated ordered_successors() method to use topological sort instead of node_id * Update qiskit/dagcircuit/dagcircuit.py Co-Authored-By: maddy-tod <[email protected]> * Renamed file and added in more comments about the types of barriers the pass will merge * merge of stashed chanegs * Fixed a bug in nodes_on_wire * Removed some accidental changes to files * Removed another unintended change * Added in 2 more tests
kdk
pushed a commit
that referenced
this pull request
Apr 18, 2019
* Remove deepcopy usage from dag/circuit converters In #1816 as part of the larger restructure the dag_to_circuit() and circuit_to_dag() converter were modified to use a copy.deepcopy() instead of native Instruction/Gate constructors. This caused a large performance regressions (around 3x in the worst case) in certain transpile calls. To avoid this performance penalty this commit reintroduces a private function to call the class constructor for each input gate to create a new instance of the object to append to the output. This removes the deepcopy usage and should fix the performance regression. Fixes #2131 * Fix lint * Fix circuit name conflict * Try to fix lint again * Don't convert custom gates to Instructions * Remove node type check that's not needed with topological_op_nodes()
This was referenced Jun 7, 2019
lia-approves
pushed a commit
to edasgupta/qiskit-terra
that referenced
this pull request
Jul 30, 2019
…ping context (Qiskit#1816) * remove qarg and carg from Instruction, modify circuit._attach * update circuit_to_dag, remove qarg/carg from all gates * fixing decomposition rule definitions * update to decomposition rules * bring measure qasm under QuantumCircuit * add args context to InstructionSet * fix extension tests, update matrix unitary gate to no qargs * update snapshot instruction * fix barrier insertion pass * update transpiler passes for new format, rest of decomp rules * add instruction shapes (num_qubits, num_clbits) add instruction shapes (num_qubits, num_clbits) * fix tests except initialize * initialize is a generic instruction with decomposition rules * move decompositions to generic instructions, add circuit_to_instruction * add circuit.append() * generalize dag_to_circuit * use copy in circuit_to_dag and dag_to_circuit, temporary slowdown * allow unroller pass to unroll generic instructions, not just gates * initialize as Instruction that recursively decomposes * revert to only gates being unrolled, and method for circuit_to_gate for now * make qargs and cargs optional in circuit.append and dag.apply_operation_back * add circuit.to_gate() method to wrap the convertor * cleanup initialize * use a list of Gate for a Gate.definition, decompose based on that * add flag to indicate instruction reversibility * decompose pass does not error on fundamental gates * rename init to initialize in qobj * circuit.decompose() method * remove instruction._modifiers method * remove instruction.circuit property * CHANGELOG * allow general subroutines via instruction definitions and update unroller * instruction.reverse() -> instruction.mirror() * inplace option for Instruction mirror and inverse * base gates should not modify with inverse. add tests * flatten register in circuit_to_instruction conversion
lia-approves
pushed a commit
to edasgupta/qiskit-terra
that referenced
this pull request
Jul 30, 2019
…#2045) * Start of refactor * More updating of variable names * Refactored barrier before final measurements to remove a sort and several add/remove from the DAG * Updated an import * Updated the bits that rely on DAGNode equality to use the new equality method * Updated to use nodes_on_wire and .remove for the list * Fixed an issue with the difference between python 3.5 and 3.6 by adding a new method to the DAG which returns the successors in order * Added in a new pass that merges barriers together - still needs testing * Fixed a failing test - the condition wasn't being copied over * Updated import to make it non cyclic * Added in some testing for MergeAdjacentBarriers pass * Included the test file this time * Updated based on review comments - added in more comments and fixed sort * Updated to work with Qiskit#1816 * Fixed lint * Updated ordered_successors() method to use topological sort instead of node_id * Update qiskit/dagcircuit/dagcircuit.py Co-Authored-By: maddy-tod <[email protected]> * Renamed file and added in more comments about the types of barriers the pass will merge * merge of stashed chanegs * Fixed a bug in nodes_on_wire * Removed some accidental changes to files * Removed another unintended change * Added in 2 more tests
lia-approves
pushed a commit
to edasgupta/qiskit-terra
that referenced
this pull request
Jul 30, 2019
* Remove deepcopy usage from dag/circuit converters In Qiskit#1816 as part of the larger restructure the dag_to_circuit() and circuit_to_dag() converter were modified to use a copy.deepcopy() instead of native Instruction/Gate constructors. This caused a large performance regressions (around 3x in the worst case) in certain transpile calls. To avoid this performance penalty this commit reintroduces a private function to call the class constructor for each input gate to create a new instance of the object to append to the output. This removes the deepcopy usage and should fix the performance regression. Fixes Qiskit#2131 * Fix lint * Fix circuit name conflict * Try to fix lint again * Don't convert custom gates to Instructions * Remove node type check that's not needed with topological_op_nodes()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Currently each instruction knows about the qubits and cbits that it is attached to. There are two problems with this:
1- It is redundant, as when building a DAG, there are edges corresponding to the qubits and cbits incoming to an instruction. So it adds the burden that these two sources of information must always be synced.
2- It prevents the instruction from being anonymous and thus reused and attached elsewhere.
Additionally, each instruction has a pointer to the circuit that contains it. This is also redundant, cyclic information, and causes many headaches (for example copying instructions amounts to a massively expensive operation). As a result there has been extensive efforts to avoid copying instructions (#1431, #1530), which made the code more verbose and hacky.
In this PR, I remove qargs and cargs from instructions, and give the responsibility of keeping context for each instruction to the circuit. Additionally I remove the circuit pointer, making the instructions very light-weight.
Examples:
So now you can create circuits like this (these can be e.g. opaque gates):
Or custom composite gate:
This will decompose to the sub gates when it goes through a Decompose or Unroller pass.
Details and comments
1- Adds a public
circuit.append()
method that allows any operation to be added to the circuit on any wires (as long as the shapes match).2- Adds a
circuit.to_instruction()
method to convert a constructed circuit to a Gate, which can then be added into another circuit. A gate is anonymous and not attached to any registers, so it's more flexible.3- Adds a
circuit.decompose()
method that decomposes each composite instruction in the circuit by one level. Recursively calling this fuction will decompose the circuit entirely to aU
andCX
basis.4-
CompositeGate
is no longer used. Instead, any Gate can be composite or not (for example,ZGate
is a composite that is made up ofU1Gate
). If you build a gate from a circuit, then that circuit is your decomposition rule.5- An instruction is uniquely identified by the following:
its type,
name
,num_qubits
/num_clbits
(i.e. its shape), andparams
.6- Removed the
reapply()
method of instructions as it is no longer needed (it was used to attach a gate to the same qubits it was defined on).7- The logic of how to print QASM is now in the circuit, because the instructions are significantly simplified.
Breaking Changes
Everything should work in a backwards compatible way except the following syntax for inverting gates:
This is not possible to keep with the current method because it requires an instruction to know about the circuit it is attached to. I think this is a weird syntax to begin with, and it should eventually have been removed. This basically says attach a gate, then modify it in place. Instead, we should attach modified versions of the instructions in the first place. For example: