def _get_common_cleanup_optimizers( tolerance: float) -> List[Callable[[cirq.Circuit], None]]: return [ cirq.EjectPhasedPaulis(tolerance=tolerance).optimize_circuit, cirq.EjectZ(tolerance=tolerance).optimize_circuit, cirq.DropNegligible(tolerance=tolerance).optimize_circuit, ]
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit, **kwargs): """Check that optimizing the circuit ``before`` produces the circuit ``expected``. The optimized circuit is cleaned up with follow up optimizations to make the comparison more robust to extra moments or extra gates nearly equal to identity that don't matter. Args: before: The input circuit to optimize. expected: The expected result of optimization to compare against. kwargs: Any extra arguments to pass to the ``MergeInteractionsToSqrtIswap`` constructor. """ actual = before.copy() opt = cirq.MergeInteractionsToSqrtIswap(**kwargs) opt.optimize_circuit(actual) # Ignore differences that would be caught by follow-up optimizations. followup_optimizations: List[Callable[[cirq.Circuit], None]] = [ cirq.merge_single_qubit_gates_into_phased_x_z, cirq.EjectPhasedPaulis().optimize_circuit, cirq.EjectZ().optimize_circuit, cirq.DropNegligible().optimize_circuit, cirq.DropEmptyMoments().optimize_circuit, ] for post in followup_optimizations: post(actual) post(expected) assert actual == expected, f'ACTUAL {actual} : EXPECTED {expected}'
def assert_removes_all_z_gates(circuit: cirq.Circuit): opt = cirq.EjectZ() optimized = circuit.copy() opt.optimize_circuit(optimized) has_z = any( _try_get_known_z_half_turns(op) is not None for moment in optimized for op in moment.operations) assert not has_z cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, optimized, atol=1e-8)
def optimize(c): cirq.ConvertToCzAndSingleGates().optimize_circuit(circuit=c) cirq.MergeSingleQubitGates().optimize_circuit(circuit=c) cirq.EjectZ().optimize_circuit(circuit=c) cirq.EjectPhasedPaulis().optimize_circuit(circuit=c) cirq.MergeSingleQubitGates().optimize_circuit(circuit=c) cirq.DropNegligible().optimize_circuit(circuit=c) cirq.DropEmptyMoments().optimize_circuit(circuit=c) c2=cirq.Circuit() for g in c: for g2 in g: # print(g2) c2.append(g2,strategy=cirq.InsertStrategy.EARLIEST) return c2
def test_swap(): a, b = cirq.LineQubit.range(2) original = cirq.Circuit.from_ops([cirq.Rz(.123).on(a), cirq.SWAP(a, b)]) optimized = original.copy() cirq.EjectZ().optimize_circuit(optimized) cirq.DropEmptyMoments().optimize_circuit(optimized) assert optimized[0].operations == (cirq.SWAP(a, b),) # Note: EjectZ drops `global_phase` from Rz turning it into a Z assert optimized[1].operations == (cirq.Z(b)**(.123 / np.pi),) cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(original), cirq.unitary(optimized), atol=1e-8)
def test_swap_iswap(exponent): a, b = cirq.LineQubit.range(2) original = cirq.Circuit([cirq.rz(0.123).on(a), cirq.ISWAP(a, b)**exponent]) optimized = original.copy() with cirq.testing.assert_deprecated("Use cirq.eject_z", deadline='v1.0'): cirq.EjectZ().optimize_circuit(optimized) optimized = cirq.drop_empty_moments(optimized) assert optimized[0].operations == (cirq.ISWAP(a, b)**exponent, ) # Note: EjectZ drops `global_phase` from Rz turning it into a Z assert optimized[1].operations == (cirq.Z(b)**(0.123 / np.pi), ) cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(original), cirq.unitary(optimized), atol=1e-8)
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit): opt = cirq.EjectZ() if cirq.has_unitary(before): cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( before, expected, atol=1e-8) circuit = before.copy() opt.optimize_circuit(circuit) opt.optimize_circuit(expected) cirq.testing.assert_same_circuits(circuit, expected) # And it should be idempotent. opt.optimize_circuit(circuit) cirq.testing.assert_same_circuits(circuit, expected)
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit): actual = cirq.Circuit(before) opt = cirq.MergeInteractions() opt.optimize_circuit(actual) # Ignore differences that would be caught by follow-up optimizations. followup_optimizations: List[Callable[[cirq.Circuit], None]] = [ cirq.merge_single_qubit_gates_into_phased_x_z, cirq.EjectPhasedPaulis().optimize_circuit, cirq.EjectZ().optimize_circuit, cirq.DropNegligible().optimize_circuit, cirq.DropEmptyMoments().optimize_circuit, ] for post in followup_optimizations: post(actual) post(expected) assert actual == expected, f'ACTUAL {actual} : EXPECTED {expected}'
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit, eject_parameterized: bool = False): with cirq.testing.assert_deprecated("Use cirq.eject_z", deadline='v1.0'): opt = cirq.EjectZ(eject_parameterized=eject_parameterized) if cirq.has_unitary(before): cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( before, expected, atol=1e-8) circuit = before.copy() opt.optimize_circuit(circuit) opt.optimize_circuit(expected) cirq.testing.assert_same_circuits(circuit, expected) # And it should be idempotent. opt.optimize_circuit(circuit) cirq.testing.assert_same_circuits(circuit, expected)
def assert_removes_all_z_gates(circuit: cirq.Circuit, eject_parameterized: bool = True): opt = cirq.EjectZ(eject_parameterized=eject_parameterized) optimized = circuit.copy() opt.optimize_circuit(optimized) has_z = any( _try_get_known_z_half_turns(op, eject_parameterized) is not None for moment in optimized for op in moment.operations) assert not has_z if cirq.is_parameterized(circuit): for a in (0, 0.1, 0.5, 1.0, -1.0, 3.0): (cirq.testing. assert_circuits_with_terminal_measurements_are_equivalent( cirq.resolve_parameters(circuit, {'a': a}), cirq.resolve_parameters(optimized, {'a': a}), atol=1e-8)) else: cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, optimized, atol=1e-8)
def compile_out_virtual_z(circuit: cirq.Circuit, *, mutate=False) -> cirq.Circuit: """Eject Z gates from the circuit. This is a wrapper around cirq.EjectZ() Args: circuit: The circuit mutate: By default, return a copy of the circuit. Otherwise, mutate in place. """ if mutate: c2 = circuit else: c2 = circuit.copy() cirq.EjectZ().optimize_circuit(c2) cirq.DropEmptyMoments().optimize_circuit(c2) return c2
def assert_optimizes( before: cirq.Circuit, expected: cirq.Circuit, post_opts: Iterable[cirq.OptimizationPass] = (cirq.DropEmptyMoments(), )): opt = cirq.EjectZ() if cirq.has_unitary(before): cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( before, expected, atol=1e-8) circuit = before.copy() opt.optimize_circuit(circuit) for post in post_opts: post.optimize_circuit(circuit) post.optimize_circuit(expected) cirq.testing.assert_same_circuits(circuit, expected) # And it should be idempotent. opt.optimize_circuit(circuit) cirq.testing.assert_same_circuits(circuit, expected)
def assert_removes_all_z_gates(circuit: cirq.Circuit, eject_parameterized: bool = True): opt = cirq.EjectZ(eject_parameterized=eject_parameterized) optimized = circuit.copy() opt.optimize_circuit(optimized) for op in optimized.all_operations(): assert _try_get_known_z_half_turns(op, eject_parameterized) is None if (isinstance(op.gate, cirq.PhasedXZGate) and (eject_parameterized or not cirq.is_parameterized(op.gate.z_exponent))): assert op.gate.z_exponent == 0 if cirq.is_parameterized(circuit): for a in (0, 0.1, 0.5, 1.0, -1.0, 3.0): (cirq.testing. assert_circuits_with_terminal_measurements_are_equivalent( cirq.resolve_parameters(circuit, {'a': a}), cirq.resolve_parameters(optimized, {'a': a}), atol=1e-8)) else: cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, optimized, atol=1e-8)
def assert_removes_all_z_gates(circuit: cirq.Circuit, eject_parameterized: bool = True): with cirq.testing.assert_deprecated("Use cirq.eject_z", deadline='v1.0'): opt = cirq.EjectZ(eject_parameterized=eject_parameterized) optimized = circuit.copy() opt.optimize_circuit(optimized) for op in optimized.all_operations(): if isinstance(op.gate, cirq.PhasedXZGate) and ( eject_parameterized or not cirq.is_parameterized(op.gate.z_exponent)): assert op.gate.z_exponent == 0 if cirq.is_parameterized(circuit): for a in (0, 0.1, 0.5, 1.0, -1.0, 3.0): (cirq.testing. assert_circuits_with_terminal_measurements_are_equivalent( cirq.resolve_parameters(circuit, {'a': a}), cirq.resolve_parameters(optimized, {'a': a}), atol=1e-8, )) else: cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, optimized, atol=1e-8)
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit): actual = cirq.Circuit(before) opt = cirq.MergeInteractions() opt.optimize_circuit(actual) # Ignore differences that would be caught by follow-up optimizations. followup_optimizations = [ cg.MergeRotations(), cirq.EjectPhasedPaulis(), cirq.EjectZ(), cirq.DropNegligible(), cirq.DropEmptyMoments() ] for post in followup_optimizations: post.optimize_circuit(actual) post.optimize_circuit(expected) if actual != expected: # coverage: ignore print('ACTUAL') print(actual) print('EXPECTED') print(expected) assert actual == expected