Commit 85ecc97
Text circuit drawer (#15357)
* Entry point and function created, returns info about instructions in circuit
* printing the qubits and clbits names
* fixed entry point for draw function
* addition to draw function, getting layers from DAG circuit
* code moved to circuit_drawer.rs and added as module for import, no longer needed to import qiskit._accelerate, can simply call qc.draw(text2)
* refactored code, wire and circuit class
* minor qubit rep fixes
* changed from pymodule to pyfunction
* circuit to dag conversion moved to python
* boilerplate code for layer stripping
* creating visualisation layers
* quadratic complexity building of sublayers
* few minor fixes
* get_layers implementation completed
* datastruct for drawing rep
* barrier implementation added
* Visualization Matrix structure completed
* Make build_layers a standalone function
* drawing logic for box and multibox, renamed Enclosed to Drawable
* printing logic complete, normalisation left
* Lay groundwork for VisualizationMatrix
* fixed a counter in draw_layer, removed debug print statement to make code run
* general handling of standard gate and instructions added, inputs also handled
* minor changes in print statements
* Visualization Matrix implementation complete
* Visualization Matrix implementation complete
* text drawer, logic complete. TO DO: fix decorations
* added swap gate support, removed circuit rep
* added top and bottom connect support, fixed parameter labels
* merge wires added
* added cregbundle functionality
* Clean up various `VisualizationMatrix` construction flow
* added draw capabilities
* linting for lib.rs
* added cregbundle flag
* removed visualization matrix printing
* mergewires flag added
* Run cargo fmt
* fixed a few labels
* added vertical lines support for controlled gates
* added standard gate visualisation support barring special cases
* fixed classical wire connection for measurement
* added fold functionality
* cosmetic addition for folding of quantum circuits
* Fix `cregbundle` behavior
The intention of the `cregbundle` parameter is to bundle the bits
of each classical register separately. This commit fixes a bug
where all classical register bits were bundled into a single classical
register.
* added aspect ratio based folding for printing, index out of range bug for creg bundling cases
* Simplify get_label
This commits refactors the `TextDrawer::get_label` method to be more
Rust idiomatic.
* preliminary changes to structure, added PackedInstruction to control and swap, a function that tells the position of the direct on wire element and changed the code to use this function when deciding to use top and bottom connectors for boxed instructions.
* bug fix for top and bottom con for boxed elements
* temporary commit to save changes before merging with text_circuit_drawer
* Implement Debug for VisualizationMatrix
* Simplify VisualizationElement::VerticalLine
* Add get_name to ElementWireInput
* Simplify DirectOnWire case
* Simplify the Boxed::Single(inst) case
* Simplify the Boxed::Multi case
* Fix clippy issues, refactor and clean up a bit
* Propagate "top" to `merge_wires`
* Apply miscellaneous fixes
* Change the VisualizationElement::VerticalLine to hold a PackedInstruction reference
* Fix capitalization of labels
* Fix clippy
* Correct drawing vertical line of a measure
* Fix minor visualization issues
This commit fixes several issues discovered via manual testing. Specifically:
* Single bit wires - avoid printing `_1` for bits of length 1. For example `my_qr` instead of `my_qr_1` if `my_qr` is of length 1
* Changed some standard gate names to match those in the Python drawer
* Count number of chars in label to account for Unicode chars properly when computing label length.
* Fix bugs related to input wires handling
* Changed default names for qubit and clbit wires
* Added support for anonymous bits
* Fixed a bug with mapping clbit indices to `VisualizationMatrix` wires when `cregbunde=true`
* Add clbit_map as a field in VisualizationMatrix
* added indexing for classical bits when bundling
* cargo fmt
* Fix a panic when measuring anonymous clbits with cregbundle
* Add unitary gate support
* linting and final checks
* cleanups
* Fix panic with mergewires=true and improve Delay drawing
* fixed label extraction for packed instruction
* used iterators in multiple places to make the code efficient, inplace allocation to prevent intermediate strings
* replaced a for loop with iterator, linting and final checks
* added tests for merge_wire, cregbundle and folding
* Cleanup tests and strip trailing whitespace
This commit updates the formatting in the unit tests to make it easier
to maintain. It uses multi-line strings in the source to show the output
of the visualizations as they would be printed to make it easier to
debug. Additionally, one aspect of the output that made working with it
harder was all the lines in the strings were fixed width with
whitespace. This is an artifact of the matrix approach that was filling
in each space in the visualization even if it didn't have anything to
draw in that coordinate. This was making the visualization tests harder
to debug because there was a lot of whitespace that had to be exactly
right. To address this and to make the output strings easier to work
with this commit strips the unnecessary whitespace from the output.
* Update use for crossterm to indicate source of size() call
This commit updates the crossterm::terminal::size() use statement to
avoid a bare `size()` function call. It wasn't super clear from reading
that this is referring to the terminal size as "size" is a fairly
generic function name. This switches to importing the `terminal` module
making the sole call to the function `terminal::size()` which provides a
bit more context around the call making the code clearer.
* Remove the python entry point function
This commit removes the pyfunction that enables calling the rust drawer
from python. This is not needed right now becase the scope of this
function is to be a drawer for C. In the future if it reaches feature
pairity with the Python we can expose it to python and replace the
python drawer's code with this. But, for this initial implementation we
don't need to expose it to Python.
* Remove TODO comment
This commit removes a TODO comment about renaming a struct. This wasn't
needed because the name is fine, especially as it's in use in the
current code for the drawer. We can rename it later, but it's not really
a TODO item at this point, especially as we prepare to merge this PR.
* Avoid box creation in unitary label handling
* Use label for fallback
This commit updates the fallback operation label in the output
visualization to first use the label field if set and then the operation
name as a fallback if a label is not set.
* Add missing whitespace back to fallback name string
The previous commit erroneously removed the whitespace around the string
label set when using the name. This restores that extra whitespace
padding.
* Add global phase display and expand test coverage
This commit expands the test coverage to cover more of the operating
space of this function. We want to be able to cover the surface area of
the types of circuits coming from C as that is the intent of this
function. This commit expands the test coverage to include more of this
surface area, although it's probably still incomplete.
The drawer was missing the global phase from the visualization. This
commit adds it so that when visualizing a circuit users can see the
global phase. This was found during the expansion of the test coverage
for setting global phase.
* Skip miri on tests with dynamic terminal width
This commit adds miri skips on the tests that are using the
circuit_drawer with dynamic terminal width determination. This relies on
calls miri can't track (using the fs) and will cause miri to fail.
Skipping is the only option in these cases as we want coverage of these
code paths.
* Update copyright header
In #15629 the copyright header url was updated to use https instead of
http. This was not reflected in this PR though, this commit makes the
necessary update.
* Simplify range loop
* Update barrier usage in tests
* Fix parameterized output
This commit fixes the display of ParameterExpression parameters for
global phase and gate/instruction parameters. Previously it was using
debug formatting for parameter expressions which was resulting in
debugging output instead of a normal string representation of the
expression. This switches to use the ParameterExpression::to_string()
method which is more useful.
* Fix unicode width handling in drawer
This commit fixes the handling of unicode character widths in the
drawer. Previously the width of strings was determined by
`string.chars().count()` which was only valid for ascii and a subset of
UTF-8 as it's counting the number of bytes not even the unique graphemes
as in UTF-8 graphemes are variable length. To address this we need to
use external crates, first unicode-width is used to estimate the number
of columns of text are used to display the graphemes in a string. This
is needed because some unicode is wider than a single column, especially
some of the emoji and icons. When calculating how wide to make boxes in
the drawings this is important because we need to know how long to make
the boxes to match the rendered width of the labels. The second crate is
unicode-segmentation is used to provide an iterator over graphemes
instead of raw bytes.
* Build visualization layers on circuit data
This commit adjusts the circuit drawer to avoid the intermediate
DAGCircuit usage. Previously a DAGCircuit was constructed to compute
layers of gates for drawing. The downside with this besides the general
overhead is that we need to keep the instructions in circuit data mapped
to the dagcircuit which complicates the code. However, this wasn't
strictly needed as we can generate layers directly from a circuit data.
This commit makes this change and adds an algorithm for computing layers
by iterating over circuit data. This algorithm does not produce layers
in the same way as DAGCircuit would, it is sensitive to insertion order
and maybe produce different layers depending on the order which gates
are added to the circuit. However as this drawer is just for C/Rust to
start and this is an initial implementation we can change and improve
this over time. The initial algorithm added in this commit is fairly
simple.
* Make build_layers less eager with adding new layers
* Fix rendering bug of controlled gates
Fixes a bug where controlled gates (e.g. a CPhase gate) had
their top or bottom connectors misaligned by one position with
the corresponding controlled lines, in case their label width
is even.
* Update comment for connector alignment
* Address remaining minor comments
---------
Co-authored-by: Eli Arbel <arbel@il.ibm.com>
Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Co-authored-by: Eli Arbel <46826214+eliarbel@users.noreply.github.com>1 parent 14ec7d3 commit 85ecc97
4 files changed
Lines changed: 2108 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
31 | 34 | | |
32 | 35 | | |
33 | 36 | | |
| |||
0 commit comments