From 2a78ca1d3641dcfce4c4813456dfdee1c6c00749 Mon Sep 17 00:00:00 2001 From: Anurudh Peduri <7265746+anurudhp@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:06:20 -0700 Subject: [PATCH] Make param `ctrl_spec` of `get_ctrl_system` mandatory (#1209) * make param `ctrl_spec` of `get_ctrl_system` mandatory * invert if branch in `CNOT.get_ctrl_system` --- qualtran/_infra/bloq.py | 14 +++++------ qualtran/_infra/single_qubit_controlled.py | 7 +----- qualtran/bloqs/arithmetic/addition.py | 7 +----- qualtran/bloqs/basic_gates/cnot.py | 28 ++++++++++------------ qualtran/bloqs/basic_gates/global_phase.py | 9 +++---- qualtran/bloqs/basic_gates/hadamard.py | 6 ++--- qualtran/bloqs/basic_gates/x_basis.py | 6 ++--- qualtran/bloqs/basic_gates/y_gate.py | 6 ++--- qualtran/bloqs/basic_gates/z_basis.py | 7 ++---- 9 files changed, 33 insertions(+), 57 deletions(-) diff --git a/qualtran/_infra/bloq.py b/qualtran/_infra/bloq.py index 55830a41b..6b7a296d9 100644 --- a/qualtran/_infra/bloq.py +++ b/qualtran/_infra/bloq.py @@ -364,9 +364,7 @@ def bloq_counts( return dict(get_bloq_callee_counts(self, generalizer=generalizer)) - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: """Get a controlled version of this bloq and a function to wire it up correctly. Users should likely call `Bloq.controlled(...)` which uses this method behind-the-scenes. @@ -400,10 +398,7 @@ def _my_add_controlled( add_controlled: A function with the signature documented above that the system can use to automatically wire up the new control registers. """ - from qualtran import Controlled, CtrlSpec - - if ctrl_spec is None: - ctrl_spec = CtrlSpec() + from qualtran import Controlled return Controlled.make_ctrl_system(self, ctrl_spec=ctrl_spec) @@ -423,6 +418,11 @@ def controlled(self, ctrl_spec: Optional['CtrlSpec'] = None) -> 'Bloq': Returns: A controlled version of the bloq. """ + from qualtran import CtrlSpec + + if ctrl_spec is None: + ctrl_spec = CtrlSpec() + controlled_bloq, _ = self.get_ctrl_system(ctrl_spec=ctrl_spec) return controlled_bloq diff --git a/qualtran/_infra/single_qubit_controlled.py b/qualtran/_infra/single_qubit_controlled.py index 5ae233908..84ca01129 100644 --- a/qualtran/_infra/single_qubit_controlled.py +++ b/qualtran/_infra/single_qubit_controlled.py @@ -56,12 +56,7 @@ def get_single_qubit_controlled_bloq( """Override this to provide a custom controlled bloq""" return attrs.evolve(self, control_val=control_val) # type: ignore[misc] - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: - if ctrl_spec is None: - ctrl_spec = CtrlSpec() - + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: if self.control_val is None and ctrl_spec.shapes in [((),), ((1,),)]: control_val = int(ctrl_spec.cvs[0].item()) cbloq = self.get_single_qubit_controlled_bloq(control_val) diff --git a/qualtran/bloqs/arithmetic/addition.py b/qualtran/bloqs/arithmetic/addition.py index 8f2fb28fd..2b83106a1 100644 --- a/qualtran/bloqs/arithmetic/addition.py +++ b/qualtran/bloqs/arithmetic/addition.py @@ -502,12 +502,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']: return {loading_cost, (Add(QUInt(self.bitsize)), 1)} - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: - if ctrl_spec is None: - ctrl_spec = CtrlSpec() - + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: if self.cvs: # We're already controlled, use default fallback return super().get_ctrl_system(ctrl_spec) diff --git a/qualtran/bloqs/basic_gates/cnot.py b/qualtran/bloqs/basic_gates/cnot.py index 62ae09258..bf19f090c 100644 --- a/qualtran/bloqs/basic_gates/cnot.py +++ b/qualtran/bloqs/basic_gates/cnot.py @@ -95,26 +95,24 @@ def my_tensors( def on_classical_vals(self, ctrl: int, target: int) -> Dict[str, 'ClassicalValT']: return {'ctrl': ctrl, 'target': (ctrl + target) % 2} - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: from qualtran.bloqs.basic_gates.toffoli import Toffoli - if ctrl_spec is None or ctrl_spec == CtrlSpec(): - bloq = Toffoli() + if ctrl_spec != CtrlSpec(): + return super().get_ctrl_system(ctrl_spec=ctrl_spec) - def add_controlled( - bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT'] - ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]: - (new_ctrl,) = ctrl_soqs - (new_ctrl, existing_ctrl), target = bb.add( - bloq, ctrl=np.array([new_ctrl, in_soqs['ctrl']]), target=in_soqs['target'] - ) - return (new_ctrl,), (existing_ctrl, target) + bloq = Toffoli() - return bloq, add_controlled + def add_controlled( + bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT'] + ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]: + (new_ctrl,) = ctrl_soqs + (new_ctrl, existing_ctrl), target = bb.add( + bloq, ctrl=np.array([new_ctrl, in_soqs['ctrl']]), target=in_soqs['target'] + ) + return (new_ctrl,), (existing_ctrl, target) - return super().get_ctrl_system(ctrl_spec=ctrl_spec) + return bloq, add_controlled def as_cirq_op( self, qubit_manager: 'cirq.QubitManager', ctrl: 'CirqQuregT', target: 'CirqQuregT' # type: ignore[type-var] diff --git a/qualtran/bloqs/basic_gates/global_phase.py b/qualtran/bloqs/basic_gates/global_phase.py index bc3c19178..bb1cc40c4 100644 --- a/qualtran/bloqs/basic_gates/global_phase.py +++ b/qualtran/bloqs/basic_gates/global_phase.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from functools import cached_property -from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING +from typing import Dict, Iterable, List, Sequence, Tuple, TYPE_CHECKING import attrs import cirq @@ -86,12 +86,9 @@ def my_tensors( return [qtn.Tensor(data=self.coefficient, inds=[], tags=[str(self)])] - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: - + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: # Delegate to superclass logic for more than one control. - if not (ctrl_spec is None or ctrl_spec == CtrlSpec() or ctrl_spec == CtrlSpec(cvs=0)): + if not (ctrl_spec == CtrlSpec() or ctrl_spec == CtrlSpec(cvs=0)): return super().get_ctrl_system(ctrl_spec=ctrl_spec) # Otherwise, it's a ZPowGate diff --git a/qualtran/bloqs/basic_gates/hadamard.py b/qualtran/bloqs/basic_gates/hadamard.py index c08c889b2..0e3ca00f5 100644 --- a/qualtran/bloqs/basic_gates/hadamard.py +++ b/qualtran/bloqs/basic_gates/hadamard.py @@ -80,10 +80,8 @@ def my_tensors( ) ] - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: - if not (ctrl_spec is None or ctrl_spec == CtrlSpec()): + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: + if ctrl_spec != CtrlSpec(): return super().get_ctrl_system(ctrl_spec=ctrl_spec) bloq = CHadamard() diff --git a/qualtran/bloqs/basic_gates/x_basis.py b/qualtran/bloqs/basic_gates/x_basis.py index 88e8ba7de..e3d493c34 100644 --- a/qualtran/bloqs/basic_gates/x_basis.py +++ b/qualtran/bloqs/basic_gates/x_basis.py @@ -225,12 +225,10 @@ def my_tensors( ) ] - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: from qualtran.bloqs.basic_gates import CNOT, Toffoli - if ctrl_spec is None or ctrl_spec == CtrlSpec(): + if ctrl_spec == CtrlSpec(): bloq: 'Bloq' = CNOT() elif ctrl_spec == CtrlSpec(cvs=(1, 1)): bloq = Toffoli() diff --git a/qualtran/bloqs/basic_gates/y_gate.py b/qualtran/bloqs/basic_gates/y_gate.py index 1430e1811..e4819a235 100644 --- a/qualtran/bloqs/basic_gates/y_gate.py +++ b/qualtran/bloqs/basic_gates/y_gate.py @@ -75,10 +75,8 @@ def my_tensors( ) ] - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: - if not (ctrl_spec is None or ctrl_spec == CtrlSpec()): + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: + if ctrl_spec != CtrlSpec(): return super().get_ctrl_system(ctrl_spec=ctrl_spec) bloq = CYGate() diff --git a/qualtran/bloqs/basic_gates/z_basis.py b/qualtran/bloqs/basic_gates/z_basis.py index 930a49dde..66c1a00a1 100644 --- a/qualtran/bloqs/basic_gates/z_basis.py +++ b/qualtran/bloqs/basic_gates/z_basis.py @@ -253,11 +253,8 @@ def my_tensors( ) ] - def get_ctrl_system( - self, ctrl_spec: Optional['CtrlSpec'] = None - ) -> Tuple['Bloq', 'AddControlledT']: - - if not (ctrl_spec is None or ctrl_spec == CtrlSpec()): + def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']: + if ctrl_spec != CtrlSpec(): # Delegate to the general superclass behavior return super().get_ctrl_system(ctrl_spec=ctrl_spec)