Add generate_clifford_t_pass_manager#15918
Add generate_clifford_t_pass_manager#15918alexanderivrii wants to merge 7 commits intoQiskit:mainfrom
generate_clifford_t_pass_manager#15918Conversation
reno and docs
|
One or more of the following people are relevant to this code:
|
| rz_synthesis_error: float | None = None, | ||
| rz_cache_error: float | None = None, |
There was a problem hiding this comment.
I would expect this to go under the umbrella of generic synthesis arguments. Once we add a plugin here we'll need to accommodate for this, plus other synthesis methods might handle caching differently. Could we just call this rz_synthesis_config and make it a generic dictionary to pass into the synthesis method?
There was a problem hiding this comment.
That was mainly to show that we now can add Clifford+T pipeline-specific arguments (and because you have asked for this for comparing against other tools). But I agree that we need to think a bit more about how synthesis and Clifford+T should look.
Cryoris
left a comment
There was a problem hiding this comment.
Some high level comments, I didn't read the logic yet 🙂
| basis_gates (list): List of basis gate names to unroll to. | ||
| coupling_map (CouplingMap): Directed graph representing a coupling | ||
| map. |
There was a problem hiding this comment.
Could we ditch these and just use a Target instead? Or is there a reason to use these as standalone?
There was a problem hiding this comment.
In theory, we can, however I am personally so used to generate preset pass managers while specifying basis_gates and coupling_map manually, that I would miss this functionality. However, based on our offline discussion, I have removed backend as an argument (especially that we have no such backends at the moment).
Cryoris
left a comment
There was a problem hiding this comment.
I took a closer look and overall this looks good. I left some, mostly minor comments, below. I didn't re-run the benchmarks since this doesn't touch the pipeline itself.
| if pass_manager_config.routing_method != "none": | ||
| split_2q_unitaries_swap = True |
There was a problem hiding this comment.
This is because the routing method cannot be set and is always the default method, right?
| rz_synthesis_error: float | None = None, | ||
| rz_cache_error: float | None = None, | ||
| ): | ||
| r"""Generate a Clifford+T :class:`~.PassManager` |
There was a problem hiding this comment.
Suggested change
| r"""Generate a Clifford+T :class:`~.PassManager` | |
| r"""Generate a preset Clifford+T :class:`.StagedPassManager`. |
| ): | ||
| r"""Generate a Clifford+T :class:`~.PassManager` | ||
|
|
||
| This function provides a fast and convenient way to construct a preset pass manager for |
There was a problem hiding this comment.
I guess every way is "fast" since there's no computation done 😄
| This function provides a fast and convenient way to construct a preset pass manager for | |
| This function provides a convenient way to construct a preset pass manager for |
|
|
||
|
|
||
| def generate_preset_clifford_t_pass_manager( | ||
| optimization_level=2, |
There was a problem hiding this comment.
Could we add typehints to all these arguments?
| :class:`~.StagedPassManager` for. By default optimization level 2 | ||
| is used if this is not specified. This can be 0, 1, 2, or 3. Higher | ||
| levels generate potentially more optimized circuits, at the expense | ||
| of longer transpilation time: |
There was a problem hiding this comment.
Can we ensure to use compilation and transpilation consistently? So far we've been talking about compilation in the docstring, which I think makes sense due to the RZ->T step.
| qc.rz(theta, 0) | ||
|
|
||
| # testing approximation_degree | ||
| for eps in 10.0 ** np.arange(-2, -13, -1): |
There was a problem hiding this comment.
How long do these run? We could just run a few values here, we don't need to run every one 🙂
| unitary_synthesis_method (str): The name of the unitary synthesis | ||
| method to use. By default ``'default'`` is used. You can see a list of | ||
| installed plugins with :func:`.unitary_synthesis_plugin_names`. |
There was a problem hiding this comment.
| unitary_synthesis_method (str): The name of the unitary synthesis | |
| method to use. By default ``'default'`` is used. You can see a list of | |
| installed plugins with :func:`.unitary_synthesis_plugin_names`. | |
| unitary_synthesis_method (str): The name of the unitary synthesis | |
| method to use. By default ``'default'`` is used. You can see a list of | |
| installed plugins with :func:`.unitary_synthesis_plugin_names`. | |
| Note that, while this is supported, it is encouraged to not synthesize | |
| arbitrary unitaries in this fashion due to high T count and no available | |
| cache. |
| features_transpiler: | ||
| - | | ||
| Added a new function :func:`~.generate_preset_clifford_t_pass_manager`, which provides | ||
| a fast and convenient way to construct a preset pass manager for Clifford+T compilation. |
There was a problem hiding this comment.
| a fast and convenient way to construct a preset pass manager for Clifford+T compilation. | |
| a convenient way to construct a preset pass manager for Clifford+T compilation. |
|
|
||
| For example:: | ||
|
|
||
| from qiskit.transpiler.preset_passmanagers import generate_preset_clifford_t_pass_manager |
There was a problem hiding this comment.
Can we make this available on qiskit.transpiler?
| basis_gates = ["cx", "s", "sdg", "h", "t", "tdg"] | ||
| pass_manager = generate_preset_clifford_t_pass_manager(basis_gates=basis_gates, optimization_level=3) |
There was a problem hiding this comment.
I would suggest this example to not set the basis gates specifically, one of the nice things here is that we don't have to do that anymore. Instead maybe just show compiling a simple circuit and counting the gates?
Summary
This PR introduces a function
generate_clifford_t_pass_managerwhich is analogous togenerate_preset_pass_managerbut exposes arguments specifically tailored for Clifford+T compilation. In particular it does not have arguments such asinit_stageoroptimization_stagebut has argumentsrz_synthesis_errorandrz_cache_errorrelevant to synthesizing RZ-gates to Clifford+T basis set.The previously existing ways of instantiating a Clifford+T transpiler pipeline (via
transpileorgenerate_preset_pass_managerwith a Clifford+T basis set) are still supported, however using the new function is recommended.Details and comments
I have defined the following classes:
PassManagerCliffordTConfig, which is analogous toPassManagerConfigbut tailored for Clifford+T. Currently it subclassesPassManagerConfigas Clifford+T compilation pipeline (not changed in this PR) uses default layout, routing and scheduling stages. (Actually the only place which really needs this to be a subclass isDefaultRoutingPassManagerwhich callsSabreSwapPassManager, which assumes that config includeslayout_method. And I did not want to explicitly addlayout_methodtoPassManagerCliffordTConfigas per previous discussions we might want to completely change how layout and routing look for Clifford+T compilations).PassManagerCliffordTStagePlugin, which is analogous toPassManagerCliffordTStagePlugin, but tailored for Clifford+T compilation.Both of the above classes are internal for now (not exposed in the documentation on purpose) since we might want to further refactor them when the PBC compilation pipeline will be added.