-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Oxidize UnitarySynthesis
pass
#13141
base: main
Are you sure you want to change the base?
Conversation
479fbe0
to
e4ec3ff
Compare
8de52b5
to
e11ffe6
Compare
e11ffe6
to
1296234
Compare
Pull Request Test Coverage Report for Build 10922534515Details
💛 - Coveralls |
Performance is starting to look promising:
|
let new_qargs = dag.qargs_interner.get(packed_instr.qubits).to_vec(); | ||
let mut owned_instr = packed_instr.clone(); | ||
owned_instr.qubits = out_dag.qargs_interner.insert_owned(new_qargs); | ||
let _ = out_dag.push_back(py, owned_instr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (and all other places where dag.push_back
is used) could be replaced by #13143.
Benchmarking status as of eb815d1 (more benchmarks show improvement but the improvement looks slightly smaller).
|
One or more of the following people are relevant to this code:
|
UnitarySynthesis
passUnitarySynthesis
pass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a first pass through this, thanks for doing this @ElePT! I left some inline comments. The two high level ones that stuck out the most to me from my first pass is that this PR seems to make a lot of things public, some of them make sense like the dagcircuit methods, but others I'm skeptical we need to be reusing or accessing outside of their definition. Some of the internal attributes of structures for example.
The other thing that I think is potentially a bigger issue especially for performance is around some of the typing choices and how that leads to a lot of conversions. The most concrete example is things are normalized on DAGCircuit
between all the different decomposer, but this leads to creating an expensive object to be constructed when it'd be far more efficient to iterate over the synthesized sequence directly and add the gates directly to the dag.
let circuit_to_dag = imports::CIRCUIT_TO_DAG.get_bound(py); | ||
let dag_to_circuit = imports::DAG_TO_CIRCUIT.get_bound(py); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These exist in rust now, see: https://github.com/Qiskit/qiskit/blob/main/crates/circuit/src/converters.rs so I'd suggest calling them directly. Especially if you're doing circuit_to_dag
you can call the inner DAGCircuit
constructor and avoid the python overhead when you've built a CircuitData
directly in rust (not that I think that's the case here).
|
||
#[derive(Clone, Debug)] | ||
enum UnitarySynthesisReturnType { | ||
DAGType(Box<DAGCircuit>), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need a box?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a suggestion from clippy, it raised a warning because of the size difference between variants. Apparently (citing the docs) "Enum size is bounded by the largest variant. Having one large variant can penalize the memory layout of that enum."
warning: large size difference between variants
--> crates/accelerate/src/unitary_synthesis.rs:65:1
|
65 | / enum UnitarySynthesisReturnType {
66 | | DAGType(DAGCircuit),
| | ------------------- the largest variant contains at least 776 bytes
67 | | TwoQSequenceType(TwoQubitUnitarySequence),
| | ----------------------------------------- the second-largest variant contains at least 120 bytes
68 | | }
| |_^ the entire enum is at least 776 bytes
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
= note: `#[warn(clippy::large_enum_variant)]` on by default
help: consider boxing the large fields to reduce the total size of the enum
|
66 | DAGType(Box<DAGCircuit>),
| ~~~~~~~~~~~~~~~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's true DAGCircuit
is huge compared to the Vec
. But I guess what my concern here is that we're adding a layer of pointer indirection to an owned object that we're creating in the pass. I think maybe this is pointing to the larger concern I had around some of the switching logic here in that we're treating a DAGCircuit
and sequence identically when there is an optimized path when we're working with the TwoQubitUnitarySequence
because it's a simplified data type.
Co-authored-by: Matthew Treinish <[email protected]>
e560bf8
to
7498419
Compare
…unitary-synthesis
* Fix details after applying inline suggestions * Keep TwoQubitWeilDecomposition attributes private. Add getter. * Initialize new_blocks using size hint * Remove basis_set as it's not used if there is a target. * Use ref_qubits ([PhysicalQubit; 2]) instead of wire_map (IndexMap<Qubit, Physicalqubit>) * Define static GOODBYE_SET as suggested * Use ImportOnceCell for XXDecomposer and XXEmbodiments to avoid importing in a loop. * Set preferred_direction without making it mutable. * Fix check_goodbye * Privatize assets * Use the add_global_phase method instead of the private function. * Add qs_decomposition to imports * Simplify flip_bits * Use NormalOperation to pass around decomposer gate and params info * First attempt at attaching synth circuits directly * Second attempt at attaching synth circuits directly * Use edge set for coupling map * Avoid exposing internals from NullableIndexMap * Use unitary_to_gate_sequence_inner instead of optimize_1q_gates_decomposition. * Use concat! in long error message.
607aa1f
to
7fc0a8a
Compare
Summary
The code is an almost literal copy of the Python one (not very rusty), but it's a start.
Details and comments
TODO:
dag_to_circuit
(not reflected in unit tests)dag.push_back
and see if it can be done with the newdag.apply_operation_back
method