Skip to content

Commit

Permalink
Make cirq_gate_as_bloq public (#1112)
Browse files Browse the repository at this point in the history
public cirq_gate_as_bloq
  • Loading branch information
mpharrigan authored Jul 9, 2024
1 parent 3315602 commit 3f325ce
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 13 deletions.
6 changes: 3 additions & 3 deletions qualtran/bloqs/mcmt/multi_control_multi_target_pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ def on_classical_vals(self, **vals: 'ClassicalValT') -> Dict[str, 'ClassicalValT
return {'controls': controls, 'target': target}

def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:
from qualtran.cirq_interop._cirq_to_bloq import _cirq_gate_to_bloq
from qualtran.cirq_interop import cirq_gate_to_bloq

ret = {(_cirq_gate_to_bloq(self.target_gate.controlled(1)), 1)}
ret = {(cirq_gate_to_bloq(self.target_gate.controlled(1)), 1)}

if is_symbolic(self.n_ctrls):
return ret | {(MultiAnd(self.cvs), 1), (MultiAnd(self.cvs).adjoint(), 1)}
Expand All @@ -204,7 +204,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:
return ret | {(and_gate, 1), (and_gate.adjoint(), 1)}
n_pre_post_x = 2 * (len(self.concrete_cvs) - sum(self.concrete_cvs))
pre_post_graph = {(XGate(), n_pre_post_x)} if n_pre_post_x else set({})
return {(_cirq_gate_to_bloq(self.target_gate.controlled(n)), 1)} | pre_post_graph
return {(cirq_gate_to_bloq(self.target_gate.controlled(n)), 1)} | pre_post_graph

def _apply_unitary_(self, args: 'cirq.ApplyUnitaryArgs') -> np.ndarray:
cpauli = (
Expand Down
1 change: 1 addition & 0 deletions qualtran/cirq_interop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
CirqGateAsBloq,
CirqGateAsBloqBase,
cirq_optree_to_cbloq,
cirq_gate_to_bloq,
decompose_from_cirq_style_method,
)

Expand Down
21 changes: 13 additions & 8 deletions qualtran/cirq_interop/_cirq_to_bloq.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,12 @@ def _gather_input_soqs(
return qvars_in


def _cirq_gate_to_bloq(gate: cirq.Gate) -> Bloq:
def cirq_gate_to_bloq(gate: cirq.Gate) -> Bloq:
"""For a given Cirq gate, return an equivalent bloq.
This will try to find the idiomatically correct bloq to return. If there is no equivalent
Qualtran bloq for the given Cirq gate, we wrap it in the `CirqGateAsBloq` wrapper class.
"""
from qualtran import Adjoint
from qualtran.bloqs.basic_gates import (
CNOT,
Expand Down Expand Up @@ -353,12 +358,7 @@ def _cirq_gate_to_bloq(gate: cirq.Gate) -> Bloq:

if isinstance(gate, cirq.ops.raw_types._InverseCompositeGate):
# Inverse of a cirq gate, delegate to Adjoint
return Adjoint(_cirq_gate_to_bloq(gate._original))

if isinstance(gate, cirq.ControlledGate):
return Controlled(
_cirq_gate_to_bloq(gate.sub_gate), CtrlSpec.from_cirq_cv(gate.control_values)
)
return Adjoint(cirq_gate_to_bloq(gate._original))

# Check specific basic gates instances.
CIRQ_GATE_TO_BLOQ_MAP = {
Expand All @@ -378,6 +378,11 @@ def _cirq_gate_to_bloq(gate: cirq.Gate) -> Bloq:
if gate in CIRQ_GATE_TO_BLOQ_MAP:
return CIRQ_GATE_TO_BLOQ_MAP[gate]

if isinstance(gate, cirq.ControlledGate):
return Controlled(
cirq_gate_to_bloq(gate.sub_gate), CtrlSpec.from_cirq_cv(gate.control_values)
)

# Check specific basic gates types.
CIRQ_TYPE_TO_BLOQ_MAP = {
cirq.Rz: Rz,
Expand Down Expand Up @@ -413,7 +418,7 @@ def _extract_bloq_from_op(op: 'cirq.Operation') -> Bloq:
"""
if op.gate is None:
raise ValueError(f"Only gate operations are supported, not {op}.")
return _cirq_gate_to_bloq(op.gate)
return cirq_gate_to_bloq(op.gate)


def cirq_optree_to_cbloq(
Expand Down
4 changes: 4 additions & 0 deletions qualtran/cirq_interop/t_complexity_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,14 @@ def _from_explicit_annotation(stc: Any) -> Optional[TComplexity]:
def _from_directly_countable(stc: Any) -> Optional[TComplexity]:
"""Directly count a clifford, T or Rotation (if it is one)."""
from qualtran.bloqs.basic_gates import TGate
from qualtran.resource_counting.classify_bloqs import bloq_is_clifford

if isinstance(stc, TGate):
return TComplexity(t=1)

if bloq_is_clifford(stc):
return TComplexity(clifford=1)

if not isinstance(stc, (cirq.Gate, cirq.Operation)):
return None

Expand Down
4 changes: 2 additions & 2 deletions qualtran/resource_counting/generalizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ def ignore_cliffords(b: Bloq) -> Optional[Bloq]:
def cirq_to_bloqs(b: Bloq) -> Optional[Bloq]:
"""A generalizer that replaces Cirq gates with their equivalent bloq, where possible."""
from qualtran.cirq_interop import CirqGateAsBloq
from qualtran.cirq_interop._cirq_to_bloq import _cirq_gate_to_bloq
from qualtran.cirq_interop._cirq_to_bloq import cirq_gate_to_bloq

if not isinstance(b, CirqGateAsBloq):
return _ignore_wrapper(cirq_to_bloqs, b)

return _cirq_gate_to_bloq(b.gate)
return cirq_gate_to_bloq(b.gate)

0 comments on commit 3f325ce

Please sign in to comment.