diff --git a/qualtran/_infra/adjoint.py b/qualtran/_infra/adjoint.py index a732bfea4..edd80968d 100644 --- a/qualtran/_infra/adjoint.py +++ b/qualtran/_infra/adjoint.py @@ -151,10 +151,6 @@ def _circuit_diagram_info_( sub_info.exponent *= -1 return sub_info - def supports_decompose_bloq(self) -> bool: - """Delegate to `subbloq.supports_decompose_bloq()`""" - return self.subbloq.supports_decompose_bloq() - def adjoint(self) -> 'Bloq': """The 'double adjoint' brings you back to the original bloq.""" return self.subbloq diff --git a/qualtran/_infra/adjoint_test.py b/qualtran/_infra/adjoint_test.py index 828214b19..378d6edb8 100644 --- a/qualtran/_infra/adjoint_test.py +++ b/qualtran/_infra/adjoint_test.py @@ -19,7 +19,7 @@ import qualtran.testing as qlt_testing from qualtran import Adjoint, CompositeBloq, Side from qualtran._infra.adjoint import _adjoint_cbloq -from qualtran.bloqs.basic_gates import CNOT, CSwap, ZeroState +from qualtran.bloqs.basic_gates import CNOT, ZeroState from qualtran.bloqs.for_testing.atom import TestAtom from qualtran.bloqs.for_testing.with_call_graph import TestBloqWithCallGraph from qualtran.bloqs.for_testing.with_decomposition import TestParallelCombo, TestSerialCombo @@ -101,14 +101,6 @@ def test_adjoint_signature(): assert adj_reg.side == Side.LEFT -def test_adjoint_supports_decompose(): - assert not CNOT().supports_decompose_bloq() - assert not Adjoint(CNOT()).supports_decompose_bloq() - - assert CSwap(bitsize=5).supports_decompose_bloq() - assert Adjoint(CSwap(bitsize=5)).supports_decompose_bloq() - - def test_adjoint_adjoint(): zero = ZeroState() adj = Adjoint(zero) # specifically use the Adjoint wrapper for testing diff --git a/qualtran/_infra/bloq.py b/qualtran/_infra/bloq.py index 393e9e1fe..bc33622d6 100644 --- a/qualtran/_infra/bloq.py +++ b/qualtran/_infra/bloq.py @@ -146,15 +146,6 @@ def decompose_bloq(self) -> 'CompositeBloq': """ return _decompose_from_build_composite_bloq(self) - def supports_decompose_bloq(self) -> bool: - """Whether this bloq supports `.decompose_bloq()`. - - By default, we check that the method `build_composite_bloq` is overriden. For - extraordinary circumstances, you may need to override this method directly to - return an accurate value. - """ - return not self.build_composite_bloq.__qualname__.startswith('Bloq.') - def as_composite_bloq(self) -> 'CompositeBloq': """Wrap this Bloq into a size-1 CompositeBloq. diff --git a/qualtran/_infra/bloq_test.py b/qualtran/_infra/bloq_test.py index d9c80b927..1a78fa0a0 100644 --- a/qualtran/_infra/bloq_test.py +++ b/qualtran/_infra/bloq_test.py @@ -36,7 +36,8 @@ def test_bloq(): def test_as_composite_bloq(): tb = TestAtom() - assert not tb.supports_decompose_bloq() + with pytest.raises(DecomposeTypeError): + tb.decompose_bloq() cb = tb.as_composite_bloq() assert isinstance(cb, CompositeBloq) bloqs = list(cb.bloq_instances) diff --git a/qualtran/_infra/composite_bloq_test.py b/qualtran/_infra/composite_bloq_test.py index 34d42e991..3842db843 100644 --- a/qualtran/_infra/composite_bloq_test.py +++ b/qualtran/_infra/composite_bloq_test.py @@ -420,7 +420,6 @@ def test_test_parallel_combo_decomp(): @pytest.mark.parametrize('cls', [TestSerialCombo, TestParallelCombo]) def test_copy(cls): - assert cls().supports_decompose_bloq() cbloq = cls().decompose_bloq() cbloq2 = cbloq.copy() assert cbloq is not cbloq2 @@ -509,9 +508,6 @@ def test_flatten(): cbloq3 = cbloq.flatten(lambda binst: True) assert len(cbloq3.bloq_instances) == 5 * 2 - cbloq4 = cbloq.flatten(lambda binst: binst.bloq.supports_decompose_bloq()) - assert len(cbloq4.bloq_instances) == 5 * 2 - cbloq5 = cbloq.flatten() assert len(cbloq5.bloq_instances) == 5 * 2 diff --git a/qualtran/bloqs/basic_gates/su2_rotation_test.py b/qualtran/bloqs/basic_gates/su2_rotation_test.py index c52b2e41a..61b4d09db 100644 --- a/qualtran/bloqs/basic_gates/su2_rotation_test.py +++ b/qualtran/bloqs/basic_gates/su2_rotation_test.py @@ -17,7 +17,6 @@ from qualtran import Bloq from qualtran.bloqs.basic_gates import GlobalPhase, Hadamard, Rx, Rz, TGate, XGate, YGate, ZGate -from qualtran.cirq_interop import BloqAsCirqGate from .su2_rotation import _hadamard, _su2_rotation_gate, _t_gate, SU2RotationGate @@ -30,7 +29,7 @@ def test_decompose_SU2_to_single_qubit_pauli_gates(): gate = SU2RotationGate(theta, phi, lambd, global_shift) np.testing.assert_allclose( - cirq.unitary(BloqAsCirqGate(gate.decompose_bloq())), gate.rotation_matrix + cirq.unitary(gate.decompose_bloq().to_cirq_circuit()), gate.rotation_matrix ) diff --git a/qualtran/cirq_interop/_bloq_to_cirq.py b/qualtran/cirq_interop/_bloq_to_cirq.py index a20a81b15..61475b8c8 100644 --- a/qualtran/cirq_interop/_bloq_to_cirq.py +++ b/qualtran/cirq_interop/_bloq_to_cirq.py @@ -147,14 +147,15 @@ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE: return self._decompose_with_context_(qubits) def _unitary_(self): - if ( - all(reg.side == Side.THRU for reg in self.signature) - and not self.bloq.supports_decompose_bloq() - ): - tensor = self.bloq.tensor_contract() - if tensor.ndim != 2: + if all(reg.side == Side.THRU for reg in self.signature): + try: + _ = self.bloq.decompose_bloq() # check for decomposability return NotImplemented - return tensor + except (DecomposeNotImplementedError, DecomposeTypeError): + tensor = self.bloq.tensor_contract() + if tensor.ndim != 2: + return NotImplemented + return tensor return NotImplemented def on_registers(