Causal flow preserving circuit optimisation #189
Causal flow preserving circuit optimisation #189calumholker wants to merge 16 commits intozxcalc:masterfrom
Conversation
|
This looks great Calum. It also makes quite some changes to the API and where the circuits are stored so I need to make sure first this doesn't break anything in some other place, so it might be a while before I can actually approve this. |
dlyongemallo
left a comment
There was a problem hiding this comment.
Thanks for the improvements, Calum.
It would also be nice to add unit tests for each added/modified functionality, and especially to have an end-to-end regression test, for example using a circuit from your paper, to demonstrate/verify the result of teleport_reduce with store = True.
(The demo notebooks and benchmarks aren't run by GitHub as part of its continuous integration, so it would be good to be able to catch future breaking changes with a test as otherwise the demos and benchmarks may break or change their behaviour without anyone noticing.)
I've realised that some of the other demo notebooks may now not run with the changes to where circuits are stored, I'll go through and update these also. |
Sure, I'll add some tests for everything! |
|
With these new commits, is this now ready for merging? |
I suppose he's waiting for an answer about testing |
|
I had already fixed the bug in to_graph_like that you fixed in the recent commit (although have now updated the vertex alignments). I also just added a check that the graph initially contains no H-boxes - previously it just treated a boundary H-box correctly, but really the graph should contain no H-boxes at all, otherwise to_gh() and spider_simp() won't work properly for removing hadamard pairs etc. Running |
|
Yes, I think it is fine to raise an exception in that case. Though the circular import could be prevented by doing a local import inside the function |
|
@jvdwetering Can we try to resolve the conflicts and merge this before more PRs are merged which will cause this to diverge further? |
|
@RazinShaikh is currently in the middle of a PR spree that updates many of the rewrites to work with multigraphs. This is a really big PR and I currently have no overview on all the things it touches. So I think after all the multigraph changes have been made we can revisit how much of this PR still makes sense. |
Causal flow preserving optimisation of quantum circuits
Implements various functions and changes used for optimising quantum circuits (https://arxiv.org/abs/2312.02793).
circuits/benchmarking_circuits/Reorganised benchmarking circuits to be clearer which circuit is optimised by which function, and enable easier integration with the new updated
Benchmarkclass.demos/circuit_optimisation/Added new demo notebooks demonstrating the use of the new
Benchmarkclass for circuit optimisation (benchmarking.ipynb) as well as effective optimisation of QFT circuits (qft-opt.ipynb). Also includes stored benchmarking metadata demonstrating how it can be saved, rather than having to rerun optimisations each time.benchmarking.pyImplements the new
Benchmarkclass for comparing circuit optimisation strategies, replacingbenchmark.py. This allows you to store the data so that routines don't need to be rerun, automatically verifies circuits, and automatically produces a more visually appealing output. Demonstrated indemos/circuit_optimisation/benchmarking.ipynb.Benchmark.load_circuitsenables loading directories containing unoptimised circuits as well as directories containing circuits pre-optimised by a specific routine.Benchmark.add_simplification_funcallows you to add any optimisation function which accepts a circuit and outputs an optimised circuit.Benchmark.dfgenerates a dataframe containing desired results, outputting a stylised version of this.Benchmark.Pt_graphsautomatically produces graphs comparing results on randomly generated circuits with varying T-gate probabilitypyzx/flow.pyReplaced file
gflow.pywithflow.py, implementing the following functions:gflowis the same function as before (although marginally optimised), implementing the gflow algorithm from dx.doi.org/10.1007/978-3-540-70575-8_70.cflowimplements the causal flow algorithm from the same paper. If phase gadgets are desired to be included then this points tofull_cflow.full_cflowimplements the causal flow algorithm from https://doi.org/10.48550/arXiv.quant-ph/0603072, which calculates the full partial order. It also checks for cflow with phase gadgets (which can then be extracted via phase polynomial synthesis).pyzx/extract.pyUpdated the
extract_simplefunction:phase_poly_synthfunction, implementing the algorithm from https://arxiv.org/abs/2004.06052.func: teleport_reduceReimplemented phase teleportation in
pyzx/simplify.py,pyzx/graph/base.pyandpyzx/graph/graph_s.pyin order to track all potential vertices which phases can be fused on, as well as allow phase jumping between these variables throughout simplification. The basic use ofteleport_reducewith the parameterstore = False(default) is identical to before.The new objects stored in
BaseGraphare as follows:phase_trackingdenotes whether the graph is tracking phases, either when the diagram is being simplified initially to find fused phase variables or afterwards when the diagram is being simplified and phases variables are not yet placed on the graph, or phase jumping is allowed.phase_teleporterpoints to an instance ofpyzx/simplify.PhaseTeleporter. This is only used for the initial simplification when finding phase variables which fuse together. In post-simplification all metadata about the variables is then stored on the graph in the following variables, and this is set toNone:parent_vertexpoints a vertex to the original vertex containing the phase variable on the graphvertex_groupsindexes a vertex to which vertex group it is ingroup_datastores the list of vertices remaining (i.e. not placed on the graph yet) in each group of fused variables.phase_sumstores the total phase sum of each group which remains to be added to the graph on one of the variables. If only one variable remains it the phase will be automatically placed and the group removed.phase_multstores any phase multipliers for vertices (if -1 then the phase sum needs to be subtracted from the graph on that variable rather than added) - i.e. the result of the functionphase_negatewhen gadgets are negated.vertex_rankstores the ordering of how vertices were fused together in the initial simplification process.vertices_to_updatestores any vertices which have been modified by fixing other phases (i.e. if it was the last in the group), such that potential matches involving these can be updated/removed - used inflow_2Q_simp.In
pyzx/simplify.PhaseTeleporterfused phase variables are now stored in a disjoint set. Thisparentfunction is not the same as theparent_vertexinBaseGraph, but rather the parent in the disjoint set.pyzx/simplify.pyModified some functions and added new functions for selective simplification
simpnow includes an additional parameternumwhich limits the number of rewrites applied. It also implements rules usingapply_rulerather than separately within the functionbasic_simpiteratively applies justid_simpandspider_simpflow_2Q_simpis the main optimisation function, selectively applying the transformation which reduces the two-qubit gate count the most (if causal flow is chosen to be preserved).selective_simp,match_score_2Q_simpandupdate_2Q_simp_matchesare all helper functions used for this.to_graph_likeandis_graph_likewere updated, including an optionalassert_bound_connectionsparameter if the input/output connection conditions are not required to be modified.pyzx/rules.pyThe following modifications to existing functions are made:
allow_interacting_matchesparameter was added, used when the matches are not all going to be applied at once (such as inflow_2Q_simp).MatchPivotTypeandMatchLcompTypeare modified to use tuples rather than lists, so that they are now immutable and can be used as keys in a dictionary.match_pivot_gadget,match_pivot_boundaryandmatch_phase_gadgetswere updated such that they no longer modify the graph at all, with all modifications being moved to the respective rewrite functions. The structure of the MatchTypes for each of these are also modified accordingly.pivot_gadgetis the new rewrite function for bothmatch_pivot_gadgetandmatch_pivot_boundary, using a helper functiongadgetizewhich infuses the relevant spiders into phase gadgets before, before applying the usualpivotrewrite function.Then the following functions were added:
match_id_fuse,id_fuseimplement identity fusion (i.e. identity removal followed by immediate fusion).match_lcomp_unfuse,lcomp_unfuseimplement local complementation including prior applications of neighbour unfusion.match_pivot_unfuse,pivot_unfuseimplement local complementation including prior applications of neighbour unfusion.match_2Q_simp,rewrite_2Q_simpfinds all matches ofid_fuse,lcomp_unfuseandpivot_unfuse.pyzx/heuristics.pyModule which enables the calculation of statistics and heuristics for various matches, used in
flow_2Q_simp