# Copyright 2019-2024 Cambridge Quantum Computing## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.fromtypingimportList,castfromlarkimportLark,Transformerfrompytket.circuitimportOpTypefrompytket.passesimportBasePass,RepeatPass,SequencePassfrompytket.passesimport(CliffordSimp,CommuteThroughMultis,ContextSimp,DecomposeArbitrarilyControlledGates,DecomposeBoxes,DecomposeClassicalExp,DecomposeMultiQubitsCX,DecomposeSingleQubitsTK1,DelayMeasures,EulerAngleReduction,FlattenRegisters,FullPeepholeOptimise,GuidedPauliSimp,KAKDecomposition,OptimisePhaseGadgets,PauliSimp,PauliExponentials,PauliSquash,PeepholeOptimise2Q,RebaseTket,RemoveBarriers,RemoveDiscarded,RemoveRedundancies,SimplifyInitial,SimplifyMeasured,SynthesiseTket,SynthesiseUMD,ThreeQubitSquash,)frompytket.circuitimportCXConfigTypefrompytket.transformimportPauliSynthStratpass_grammar="""start: comp_passcomp_pass: ( basic_pass | seq_pass | repeat_pass )basic_pass: | clifford_simp | clifford_simp_no_swaps | commute_through_multis | context_simp | context_simp_no_classical | decompose_arbitrarily_controlled_gates | decompose_boxes | decompose_classical_exp | decompose_multi_qubits_cx | decompose_single_qubits_tk1 | delay_measures | delay_measures_try | euler_angle_reduction | flatten_registers | full_peephole_optimise | full_peephole_optimise_no_swaps | guided_pauli_simp | guided_pauli_simp_default | kak_decomposition | optimise_phase_gadgets | optimise_phase_gadgets_default | pauli_simp | pauli_simp_default | pauli_squash | pauli_squash_default | peephole_optimise_2q | rebase_tket | remove_barriers | remove_discarded | remove_redundancies | simplify_initial | simplify_initial_no_classical | simplify_measured | synthesise_tket | synthesise_umd | three_qubit_squashseq_pass: "[" pass_list "]"pass_list: comp_pass ("," comp_pass)*repeat_pass: "repeat" "(" comp_pass ")"clifford_simp: "CliffordSimp"clifford_simp_no_swaps: "CliffordSimpNoSwaps"commute_through_multis: "CommuteThroughMultis"context_simp: "ContextSimp"context_simp_no_classical: "ContextSimpNoClassical"decompose_arbitrarily_controlled_gates: "DecomposeArbitrarilyControlledGates"decompose_boxes: "DecomposeBoxes"decompose_classical_exp: "DecomposeClassicalExp"decompose_multi_qubits_cx: "DecomposeMultiQubitsCX"decompose_single_qubits_tk1: "DecomposeSingleQubitsTK1"delay_measures: "DelayMeasures"delay_measures_try: "TryDelayMeasures"euler_angle_reduction: "EulerAngleReduction" "(" op_type "," op_type ")"flatten_registers: "FlattenRegisters"full_peephole_optimise: "FullPeepholeOptimise"full_peephole_optimise_no_swaps: "FullPeepholeOptimiseNoSwaps"guided_pauli_simp: "GuidedPauliSimp" "(" pauli_synth_strat "," cx_config_type ")"guided_pauli_simp_default: "GuidedPauliSimp"kak_decomposition: "KAKDecomposition"optimise_phase_gadgets: "OptimisePhaseGadgets" "(" cx_config_type ")"optimise_phase_gadgets_default: "OptimisePhaseGadgets"pauli_exponentials: "PauliExponentials" "(" pauli_synth_strat "," cx_config_type ")"pauli_exponentials_default: "PauliExponentials"pauli_simp: "PauliSimp" "(" pauli_synth_strat "," cx_config_type ")"pauli_simp_default: "PauliSimp"pauli_squash: "PauliSquash" "(" pauli_synth_strat "," cx_config_type ")"pauli_squash_default: "PauliSquash"peephole_optimise_2q: "PeepholeOptimise2Q"rebase_tket: "RebaseTket"remove_barriers: "RemoveBarriers"remove_discarded: "RemoveDiscarded"remove_redundancies: "RemoveRedundancies"simplify_initial: "SimplifyInitial"simplify_initial_no_classical: "SimplifyInitialNoClassical"simplify_measured: "SimplifyMeasured"synthesise_tket: "SynthesiseTket"synthesise_umd: "SynthesiseUMD"three_qubit_squash: "ThreeQubitSquash"cx_config_type: | cx_config_type_snake | cx_config_type_star | cx_config_type_tree | cx_config_type_multi_q_gatecx_config_type_snake: "Snake"cx_config_type_star: "Star"cx_config_type_tree: "Tree"cx_config_type_multi_q_gate: "MultiQGate"op_type: ( op_type_rx | op_type_ry | op_type_rz )op_type_rx: "Rx"op_type_ry: "Ry"op_type_rz: "Rz"pauli_synth_strat: | pauli_synth_strat_individual | pauli_synth_strat_pairwise | pauli_synth_strat_setspauli_synth_strat_individual: "Individual"pauli_synth_strat_pairwise: "Pairwise"pauli_synth_strat_sets: "Sets"%import common.WS_INLINE -> WS%import common.CR%import common.LF_NEWLINE: CR? LF%ignore WS%ignore _NEWLINE"""classPassTransformer(Transformer):defstart(self,t:list[BasePass])->BasePass:returnt[0]defcomp_pass(self,t:list[BasePass])->BasePass:returnt[0]defbasic_pass(self,t:list[BasePass])->BasePass:returnt[0]defseq_pass(self,t:list[BasePass])->BasePass:returnt[0]defpass_list(self,t:list[BasePass])->BasePass:returnSequencePass(t)defrepeat_pass(self,t:list[BasePass])->BasePass:returnRepeatPass(t[0])defclifford_simp(self,t:List)->BasePass:returnCliffordSimp()defclifford_simp_no_swaps(self,t:List)->BasePass:returnCliffordSimp(allow_swaps=False)defcommute_through_multis(self,t:List)->BasePass:returnCommuteThroughMultis()defcontext_simp(self,t:List)->BasePass:returnContextSimp()defcontext_simp_no_classical(self,t:List)->BasePass:returnContextSimp(allow_classical=False)defdecompose_arbitrarily_controlled_gates(self,t:List)->BasePass:returnDecomposeArbitrarilyControlledGates()defdecompose_boxes(self,t:List)->BasePass:returnDecomposeBoxes()defdecompose_classical_exp(self,t:List)->BasePass:returnDecomposeClassicalExp()defdecompose_multi_qubits_cx(self,t:List)->BasePass:returnDecomposeMultiQubitsCX()defdecompose_single_qubits_tk1(self,t:List)->BasePass:returnDecomposeSingleQubitsTK1()defdelay_measures(self,t:List)->BasePass:returnDelayMeasures(False)defdelay_measures_try(self,t:List)->BasePass:returnDelayMeasures(True)defeuler_angle_reduction(self,t:list[OpType])->BasePass:returnEulerAngleReduction(t[0],t[1])defflatten_registers(self,t:List)->BasePass:returnFlattenRegisters()deffull_peephole_optimise(self,t:List)->BasePass:returnFullPeepholeOptimise()deffull_peephole_optimise_no_swaps(self,t:List)->BasePass:returnFullPeepholeOptimise(allow_swaps=False)defguided_pauli_simp(self,t:List)->BasePass:assertisinstance(t[0],PauliSynthStrat)assertisinstance(t[1],CXConfigType)returnGuidedPauliSimp(strat=t[0],cx_config=t[1])defguided_pauli_simp_default(self,t:List)->BasePass:returnGuidedPauliSimp()defkak_decomposition(self,t:List)->BasePass:returnKAKDecomposition()defoptimise_phase_gadgets(self,t:List)->BasePass:assertisinstance(t[0],CXConfigType)returnOptimisePhaseGadgets(cx_config=t[0])defoptimise_phase_gadgets_default(self,t:List)->BasePass:returnOptimisePhaseGadgets()defpauli_exponentials(self,t:List)->BasePass:assertisinstance(t[0],PauliSynthStrat)assertisinstance(t[1],CXConfigType)returnPauliExponentials(strat=t[0],cx_config=t[1])defpauli_exponentials_default(self,t:List)->BasePass:returnPauliExponentials()defpauli_simp(self,t:List)->BasePass:assertisinstance(t[0],PauliSynthStrat)assertisinstance(t[1],CXConfigType)returnPauliSimp(strat=t[0],cx_config=t[1])defpauli_simp_default(self,t:List)->BasePass:returnPauliSimp()defpauli_squash(self,t:List)->BasePass:assertisinstance(t[0],PauliSynthStrat)assertisinstance(t[1],CXConfigType)returnPauliSquash(strat=t[0],cx_config=t[1])defpauli_squash_default(self,t:List)->BasePass:returnPauliSquash()defpeephole_optimise_2q(self,t:List)->BasePass:returnPeepholeOptimise2Q()defrebase_tket(self,t:List)->BasePass:returnRebaseTket()defremove_barriers(self,t:List)->BasePass:returnRemoveBarriers()defremove_discarded(self,t:List)->BasePass:returnRemoveDiscarded()defremove_redundancies(self,t:List)->BasePass:returnRemoveRedundancies()defsimplify_initial(self,t:List)->BasePass:returnSimplifyInitial()defsimplify_initial_no_classical(self,t:List)->BasePass:returnSimplifyInitial(allow_classical=False)defsimplify_measured(self,t:List)->BasePass:returnSimplifyMeasured()defsynthesise_tket(self,t:List)->BasePass:returnSynthesiseTket()defsynthesise_umd(self,t:List)->BasePass:returnSynthesiseUMD()defthree_qubit_squash(self,t:List)->BasePass:returnThreeQubitSquash()defcx_config_type(self,t:List[CXConfigType])->CXConfigType:returnt[0]defcx_config_type_snake(self,t:List)->CXConfigType:returnCXConfigType.Snakedefcx_config_type_star(self,t:List)->CXConfigType:returnCXConfigType.Stardefcx_config_type_tree(self,t:List)->CXConfigType:returnCXConfigType.Treedefcx_config_type_multi_q_gate(self,t:List)->CXConfigType:returnCXConfigType.MultiQGatedefop_type(self,t:List[OpType])->OpType:returnt[0]defop_type_rx(self,t:List)->OpType:returnOpType.Rxdefop_type_ry(self,t:List)->OpType:returnOpType.Rydefop_type_rz(self,t:List)->OpType:returnOpType.Rzdefpauli_synth_strat(self,t:List[PauliSynthStrat])->PauliSynthStrat:returnt[0]defpauli_synth_strat_individual(self,t:List)->PauliSynthStrat:returnPauliSynthStrat.Individualdefpauli_synth_strat_pairwise(self,t:List)->PauliSynthStrat:returnPauliSynthStrat.Pairwisedefpauli_synth_strat_sets(self,t:List)->PauliSynthStrat:returnPauliSynthStrat.Setsparser=Lark(pass_grammar)transformer=PassTransformer()
[docs]defcompilation_pass_from_script(script:str)->BasePass:"""Generate a compilation pass from a specification. The specification must conform to a simple grammar. For example, the following are valid specifications: * "RemoveRedundancies" * "[RemoveBarriers, RemoveRedundancies]" (a sequence of passes) * "repeat(FullPeepholeOptimise)" (repeat a pass until it doesn't change the circuit) Sequences and repeats can be nested arbitrarily. Whitespace is ignored. Most passes are specified using their Python names. For those that take enums as parameters, non-default values can be specified using their Python names: * "PauliSimp" (default parameters) * "PauliSimp(Pairwise, Tree)" * "EulerAngleReduction(Ry, Rz)" For some passes with optional boolean parameters the name can be modified as follows: * "CliffordSimp" (default parameters) * "CliffordSimpNoSwaps" * "SimplifyInitial" (default parameters) * "SimplifyInitialNoClassical" There is currently no support for passes requiring more complex parameters such as lambdas or circuits. The full formal grammar can be inspected using :py:meth:`compilation_pass_grammar`. :param script: specification of pass """tree=parser.parse(script)returncast(BasePass,transformer.transform(tree))
[docs]defcompilation_pass_grammar()->str:"""Formal grammar for specifying compilation passes. This is the grammar assumed by :py:meth:`complilation_pass_from_script`. :return: grammar in extended Backus--Naur form"""returnpass_grammar