def test_swap_network_str(): n_qubits = 5 phys_qubits = cirq.GridQubit.rect(n_qubits, 1) log_qubits = cirq.LineQubit.range(n_qubits) gates = {(l, ll): cirq.ZZ for l, ll in itertools.combinations(log_qubits, 2)} initial_mapping = {p: l for p, l in zip(phys_qubits, log_qubits)} execution_strategy = cca.GreedyExecutionStrategy(gates, initial_mapping) routed_circuit = cca.complete_acquaintance_strategy(phys_qubits, 2) execution_strategy(routed_circuit) swap_network = ccr.SwapNetwork(routed_circuit, initial_mapping) actual_str = str(swap_network) expected_str = """ (0, 0): ───0───ZZ───0───╲0╱───1────────1─────────1───ZZ───1───╲0╱───3────────3─────────3───ZZ───3───╲0╱───4─── │ │ │ │ │ │ (1, 0): ───1───ZZ───1───╱1╲───0───ZZ───0───╲0╱───3───ZZ───3───╱1╲───1───ZZ───1───╲0╱───4───ZZ───4───╱1╲───3─── │ │ │ │ (2, 0): ───2───ZZ───2───╲0╱───3───ZZ───3───╱1╲───0───ZZ───0───╲0╱───4───ZZ───4───╱1╲───1───ZZ───1───╲0╱───2─── │ │ │ │ │ │ (3, 0): ───3───ZZ───3───╱1╲───2───ZZ───2───╲0╱───4───ZZ───4───╱1╲───0───ZZ───0───╲0╱───2───ZZ───2───╱1╲───1─── │ │ │ │ (4, 0): ───4────────4─────────4───ZZ───4───╱1╲───2────────2─────────2───ZZ───2───╱1╲───0────────0─────────0─── """.strip() assert actual_str == expected_str
def test_get_logical_acquaintance_opportunities(n_qubits, acquaintance_size): qubits = cirq.LineQubit.range(n_qubits) acquaintance_strategy = cca.complete_acquaintance_strategy( qubits, acquaintance_size) initial_mapping = {q: i for i, q in enumerate(qubits)} opps = cca.get_logical_acquaintance_opportunities( acquaintance_strategy, initial_mapping) assert opps == set(frozenset(s) for s in combinations(range(n_qubits), acquaintance_size))
def test_executor_explicit(): num_qubits = 8 qubits = cirq.LineQubit.range(num_qubits) circuit = cca.complete_acquaintance_strategy(qubits, 2) gates = {(i, j): ExampleGate([str(k) for k in ij]) for ij in combinations(range(num_qubits), 2) for i, j in (ij, ij[::-1])} initial_mapping = {q: i for i, q in enumerate(sorted(qubits))} execution_strategy = cca.GreedyExecutionStrategy(gates, initial_mapping) executor = cca.StrategyExecutor(execution_strategy) with pytest.raises(NotImplementedError): bad_gates = { (0, ): ExampleGate(['0']), (0, 1): ExampleGate(['0', '1']) } cca.GreedyExecutionStrategy(bad_gates, initial_mapping) with pytest.raises(TypeError): executor(cirq.Circuit()) with pytest.raises(TypeError): bad_strategy = cirq.Circuit.from_ops(cirq.X(qubits[0])) executor(bad_strategy) with pytest.raises(TypeError): op = cirq.X(qubits[0]) bad_strategy = cirq.Circuit.from_ops(op) executor.optimization_at(bad_strategy, 0, op) executor(circuit) actual_text_diagram = circuit.to_text_diagram().strip() expected_text_diagram = """ 0: ───0───1───╲0╱─────────────────1───3───╲0╱─────────────────3───5───╲0╱─────────────────5───7───╲0╱───────────────── │ │ │ │ │ │ │ │ │ │ │ │ 1: ───1───0───╱1╲───0───3───╲0╱───3───1───╱1╲───1───5───╲0╱───5───3───╱1╲───3───7───╲0╱───7───5───╱1╲───5───6───╲0╱─── │ │ │ │ │ │ │ │ │ │ │ │ 2: ───2───3───╲0╱───3───0───╱1╲───0───5───╲0╱───5───1───╱1╲───1───7───╲0╱───7───3───╱1╲───3───6───╲0╱───6───5───╱1╲─── │ │ │ │ │ │ │ │ │ │ │ │ 3: ───3───2───╱1╲───2───5───╲0╱───5───0───╱1╲───0───7───╲0╱───7───1───╱1╲───1───6───╲0╱───6───3───╱1╲───3───4───╲0╱─── │ │ │ │ │ │ │ │ │ │ │ │ 4: ───4───5───╲0╱───5───2───╱1╲───2───7───╲0╱───7───0───╱1╲───0───6───╲0╱───6───1───╱1╲───1───4───╲0╱───4───3───╱1╲─── │ │ │ │ │ │ │ │ │ │ │ │ 5: ───5───4───╱1╲───4───7───╲0╱───7───2───╱1╲───2───6───╲0╱───6───0───╱1╲───0───4───╲0╱───4───1───╱1╲───1───2───╲0╱─── │ │ │ │ │ │ │ │ │ │ │ │ 6: ───6───7───╲0╱───7───4───╱1╲───4───6───╲0╱───6───2───╱1╲───2───4───╲0╱───4───0───╱1╲───0───2───╲0╱───2───1───╱1╲─── │ │ │ │ │ │ │ │ │ │ │ │ 7: ───7───6───╱1╲─────────────────6───4───╱1╲─────────────────4───2───╱1╲─────────────────2───0───╱1╲───────────────── """.strip() assert actual_text_diagram == expected_text_diagram
def test_executor_random( num_qubits: int, acquaintance_size: int, gates: Dict[Tuple[cirq.Qid, ...], cirq.Gate] ): qubits = cirq.LineQubit.range(num_qubits) circuit = cca.complete_acquaintance_strategy(qubits, acquaintance_size) logical_circuit = cirq.Circuit([g(*Q) for Q, g in gates.items()]) expected_unitary = logical_circuit.unitary() initial_mapping = {q: q for q in qubits} final_mapping = cca.GreedyExecutionStrategy(gates, initial_mapping)(circuit) permutation = {q.x: qq.x for q, qq in final_mapping.items()} circuit.append(cca.LinearPermutationGate(num_qubits, permutation)(*qubits)) actual_unitary = circuit.unitary() np.testing.assert_allclose(actual=actual_unitary, desired=expected_unitary, verbose=True)
def get_phase_sep_circuit( gates: LogicalGates, qubits: Sequence[cirq.Qid], initial_mapping: LogicalMapping, verbose: bool = True, ): # An acquaintance strategy containing permutation gates and acquaintance # opportunity gates. circuit = cca.complete_acquaintance_strategy(qubits, 2) if verbose: print('Circuit containing a single complete linear swap network:') print(circuit) print('\n\n') acquaintance_opportunities = cca.get_logical_acquaintance_opportunities( circuit, initial_mapping ) assert set(frozenset(edge) for edge in gates) <= acquaintance_opportunities cca.expose_acquaintance_gates(circuit) if verbose: print('Circuit with acquaintance opportunities show explicitly:') print(circuit) print('\n\n') # The greedy execution strategy replaces inserts the logical gates into the # circuit at the first opportunity. execution_strategy = cca.GreedyExecutionStrategy(gates, initial_mapping) # The final mapping may be different from the initial one. # In this case, the mapping is simply reversed final_mapping = execution_strategy(circuit) for p, q in zip(qubits, reversed(qubits)): assert initial_mapping[p] == final_mapping[q] if verbose: print('Circuit with logical gates:') print(circuit) print('\n\n') # All of the operations act on adjacent qubits now positions = {q: x for x, q in enumerate(qubits)} for op in circuit.all_operations(): p, q = op.qubits assert abs(positions[p] - positions[q]) == 1 return circuit
def test_display_mapping(): indices = [4, 2, 0, 1, 3] qubits = cirq.LineQubit.range(len(indices)) circuit = cca.complete_acquaintance_strategy(qubits, 2) cca.expose_acquaintance_gates(circuit) initial_mapping = dict(zip(qubits, indices)) cca.display_mapping(circuit, initial_mapping) expected_diagram = """ 0: ───4───█───4───╲0╱───2───────2─────────2───█───2───╲0╱───1───────1─────────1───█───1───╲0╱───3─── │ │ │ │ │ │ 1: ───2───█───2───╱1╲───4───█───4───╲0╱───1───█───1───╱1╲───2───█───2───╲0╱───3───█───3───╱1╲───1─── │ │ │ │ 2: ───0───█───0───╲0╱───1───█───1───╱1╲───4───█───4───╲0╱───3───█───3───╱1╲───2───█───2───╲0╱───0─── │ │ │ │ │ │ 3: ───1───█───1───╱1╲───0───█───0───╲0╱───3───█───3───╱1╲───4───█───4───╲0╱───0───█───0───╱1╲───2─── │ │ │ │ 4: ───3───────3─────────3───█───3───╱1╲───0───────0─────────0───█───0───╱1╲───4───────4─────────4─── """ cirq.testing.assert_has_diagram(circuit, expected_diagram)
def test_complete_acquaintance_strategy(): qubits = [cirq.NamedQubit(s) for s in alphabet] with pytest.raises(ValueError): _ = cca.complete_acquaintance_strategy(qubits, -1) empty_strategy = cca.complete_acquaintance_strategy(qubits) assert empty_strategy._moments == [] trivial_strategy = cca.complete_acquaintance_strategy(qubits[:4], 1) actual_text_diagram = trivial_strategy.to_text_diagram().strip() expected_text_diagram = """ a: ───█─── b: ───█─── c: ───█─── d: ───█─── """.strip() assert actual_text_diagram == expected_text_diagram assert cca.get_acquaintance_size(trivial_strategy) == 1 is_shift_or_lin_perm = lambda op: isinstance(op.gate, ( cca.CircularShiftGate, cca.LinearPermutationGate)) expand = cirq.ExpandComposite(no_decomp=is_shift_or_lin_perm) quadratic_strategy = cca.complete_acquaintance_strategy(qubits[:8], 2) actual_text_diagram = quadratic_strategy.to_text_diagram().strip() expected_text_diagram = """ a: ───×(0,0)─── │ b: ───×(1,0)─── │ c: ───×(2,0)─── │ d: ───×(3,0)─── │ e: ───×(4,0)─── │ f: ───×(5,0)─── │ g: ───×(6,0)─── │ h: ───×(7,0)─── """.strip() assert actual_text_diagram == expected_text_diagram assert cca.get_acquaintance_size(quadratic_strategy) == 2 expand(quadratic_strategy) actual_text_diagram = quadratic_strategy.to_text_diagram( transpose=True).strip() expected_text_diagram = '\n'.join( ("a b c d e f g h ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "█───█ █───█ █───█ █───█ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ █───█ █───█ █───█ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "█───█ █───█ █───█ █───█ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ █───█ █───█ █───█ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "█───█ █───█ █───█ █───█ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ █───█ █───█ █───█ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "█───█ █───█ █───█ █───█ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ █───█ █───█ █───█ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip(), "│ ╲0╱─╱1╲ ╲0╱─╱1╲ ╲0╱─╱1╲ │ ".strip(), "│ │ │ │ │ │ │ │ ".strip())) assert actual_text_diagram == expected_text_diagram assert cca.get_acquaintance_size(quadratic_strategy) == 2 cubic_strategy = cca.complete_acquaintance_strategy(qubits[:4], 3) actual_text_diagram = cubic_strategy.to_text_diagram( transpose=True).strip() expected_text_diagram = """ a b c d │ │ │ │ ×(0,0)─×(0,1)─×(1,0)─×(1,1) │ │ │ │ ╱1╲────╲0╱ ╱1╲────╲0╱ │ │ │ │ ×(0,0)─×(1,0)─×(1,1)─×(2,0) │ │ │ │ │ ╲0╱────╱1╲ │ │ │ │ │ ×(0,0)─×(0,1)─×(1,0)─×(1,1) │ │ │ │ ╱1╲────╲0╱ ╱1╲────╲0╱ │ │ │ │ ×(0,0)─×(1,0)─×(1,1)─×(2,0) │ │ │ │ │ ╲0╱────╱1╲ │ │ │ │ │ """.strip() assert actual_text_diagram == expected_text_diagram assert cca.get_acquaintance_size(cubic_strategy) == 3