-
Notifications
You must be signed in to change notification settings - Fork 7
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
Cirq decompose to supported gate set #93
Comments
@ryanhill1 Is this still open? I'd love to work on this! |
@arulandu It is, go for it! |
I'm thinking of creating a Gateset by extending https://quantumai.google/reference/python/cirq/TwoQubitCompilationTargetGateset. However, I'm unsure how to implement |
I'll admit, I'm not super familiar with how @TheGupta2012 @skushnir123 perhaps you guys could take a look here and weigh in? Or if @vtomole has any insights, as someone who is much closer to the Cirq stack, that could be super helpful as well. |
|
What gateset do ya'll want to decompose to? The list in
Why not copy |
I would copy their implementation and I could decompose PhasedXZ into {Rx,Rz}, but I'm unsure what to do about the |
CZ is in |
You can leave out And yes, like Victory said, the "CZ" gate is already accounted for in our current implementation, so if the qbraid-qir/qbraid_qir/cirq/opsets.py Lines 112 to 118 in 4f009c3
|
I already call two_qubit_matrix_to_cz_operations at the moment. I'll use ^ for CZPowGate and will update afterwards. Thank you! |
Tried this in 530a0ca. Running into a max-recursion depth issue with decompose. Will debug through Cirq implementation tomorrow |
The recursion issue is cause your decomposer is not getting to your target gateset. Here is a decomposer that will # Copyright 2018 The Cirq Developers
#
# 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
#
# https://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.
from typing import Sequence, Union, Type, List
import cirq
from cirq.protocols.decompose_protocol import DecomposeResult
class QirTargetGateSet(cirq.TwoQubitCompilationTargetGateset):
def __init__(
self,
*,
atol: float = 1e-8,
allow_partial_czs: bool = False,
additional_gates: Sequence[
Union[Type["cirq.Gate"], "cirq.Gate", "cirq.GateFamily"]
] = (),
preserve_moment_structure: bool = True,
) -> None:
super().__init__(
cirq.IdentityGate,
cirq.HPowGate,
cirq.XPowGate,
cirq.YPowGate,
cirq.ZPowGate,
cirq.SWAP,
cirq.CNOT,
cirq.CZ,
cirq.TOFFOLI,
cirq.ResetChannel,
*additional_gates,
name="QirTargetGateset",
preserve_moment_structure=preserve_moment_structure,
)
self.allow_partial_czs = allow_partial_czs
self.atol = atol
@property
def postprocess_transformers(self) -> List["cirq.TRANSFORMER"]:
return []
def _decompose_single_qubit_operation(
self, op: "cirq.Operation", moment_idx: int
) -> DecomposeResult:
qubit = op.qubits[0]
mat = cirq.unitary(op)
for gate in cirq.single_qubit_matrix_to_gates(mat, self.atol):
yield gate(qubit)
def _decompose_two_qubit_operation(self, op: "cirq.Operation", _) -> "cirq.OP_TREE":
if not cirq.has_unitary(op):
return NotImplemented
return cirq.two_qubit_matrix_to_cz_operations(
op.qubits[0],
op.qubits[1],
cirq.unitary(op),
allow_partial_czs=self.allow_partial_czs,
atol=self.atol,
)
circuit = cirq.testing.random_circuit(qubits=4, n_moments=6, op_density=0.8)
# Compile the circuit for CZ+ QIR Target Gateset
gateset = QirTargetGateSet()
qir_circuit = cirq.optimize_for_target_gateset(circuit, gateset=gateset) |
Before passing an input cirq circuit to the QIR converter, we first decompose the circuit to ensure that it only uses gates / operations that are supported by QIR, see PYQIR_OP_MAP. Right now, to accomplish this, we use a preprocess_circuit function which loops through each operation, and uses a try / except to determine if the operation is supported, and if not, applies a naive
cirq.decompose_once
to the circuit.qbraid-qir/qbraid_qir/cirq/passes.py
Lines 34 to 43 in 3ef504f
For the majority of use-cases, this works. However, it is:
Instead, we would like to use one of the built-in Cirq transforms such as cirq.optimize_for_target_gateset to automatically ensure that the input circuit conforms to the supported QIR operations. In doing so, hopefully we can eliminate the try except blocks in passes.py, and re-implement
preprocess_circuit
without the clunky helpers.The text was updated successfully, but these errors were encountered: