def get_compiled_sk_model_circuit( problem: SKProblem, qubits: List[cirq.Qid], gammas: Sequence[float], betas: Sequence[float], *, non_negligible=True ) -> Tuple[cirq.Circuit, List[cirq.Qid]]: """Get a fully-compiled SK model circuit. Args: problem: A SKProblem qubits: The qubits to use in construction of the circuit. gammas: Gamma angles to use as parameters for problem unitaries betas: Beta angles to use as parameters for driver unitaries non_negligible: Whether to compile out negligible gates. This will preserve the quality that the returned circuit has homogeneous gate types in each moment but may make it so the predictable pattern of PhX, (SYC, PhX)*n, PhX may be disrupted. Set this argument to `False` if doing echo experiments. Returns: circuit: The final routed, gateset-targeted, and placed circuit with measurements. final_qubits: The qubits in their final logical order. """ circuit = get_routed_sk_model_circuit(problem.graph, qubits, gammas, betas) circuit = compile_to_syc(circuit) mcircuit, final_qubits = measure_with_final_permutation(circuit, qubits) mcircuit = compile_out_virtual_z(mcircuit) if non_negligible: mcircuit = compile_to_non_negligible(mcircuit) validate_well_structured(mcircuit) return mcircuit, final_qubits
def test_compile_to_non_negligible(): qubits = cirq.LineQubit.range(2) circuit = cirq.Circuit(ZZSwap(zz_exponent=0.123).on(*qubits)) c1 = compile_to_syc(circuit) validate_well_structured(c1) assert len(c1) == 3 * 3 + 2 c2 = compile_to_non_negligible(c1) assert c1 != c2 # KAK instability (https://github.com/quantumlib/Cirq/issues/1647) # means the first layer of PhX gets removed on mpharrigan's machine # but not in docker / in CI. assert len(c2) in [9, 10]
def get_compiled_hardware_grid_circuit( problem: HardwareGridProblem, qubits: List[cirq.Qid], gammas: Sequence[float], betas: Sequence[float], non_negligible=True) \ -> Tuple[cirq.Circuit, List[cirq.Qid]]: """Get a fully-compiled grid model circuit. Args: problem: A HardwareGridProblem qubits: The qubits to use in construction of the circuit. gammas: Gamma angles to use as parameters for problem unitaries betas: Beta angles to use as parameters for driver unitaries non_negligible: Whether to compile out negligible gates. This will preserve the quality that the returned circuit has homogeneous gate types in each moment but may make it so the predictable pattern of PhX, (SYC, PhX)*n, PhX may be disrupted. Set this argument to `False` if doing echo experiments. Returns: circuit: The final routed, gateset-targeted, and placed circuit with measurements. final_qubits: The qubits in their final logical order. This is for consistency with other problem types. This will be a copy of `qubits`. """ circuit = get_routed_hardware_grid_circuit( problem_graph=problem.graph, qubits=qubits, coordinates=problem.coordinates, gammas=gammas, betas=betas) circuit = compile_to_syc(circuit) mcircuit = circuit + cirq.measure(*qubits, key='z') mcircuit = compile_out_virtual_z(mcircuit) if non_negligible: mcircuit = compile_to_non_negligible(mcircuit) validate_well_structured(mcircuit) final_qubits = qubits.copy() return mcircuit, final_qubits
async def collect_data(task: PrecomputedDataCollectionTask, base_dir=None, problem_generation_base_dir=None, precomputation_base_dir=None, ): """Collect and save data for the experiment specified by params. The associated problem generation data must already exist. """ if base_dir is None: base_dir = DEFAULT_BASE_DIR if problem_generation_base_dir is None: problem_generation_base_dir = DEFAULT_PROBLEM_GENERATION_BASE_DIR if precomputation_base_dir is None: precomputation_base_dir = DEFAULT_PRECOMPUTATION_BASE_DIR if recirq.exists(task, base_dir=base_dir): print(f"{task.fn} already exists. Skipping.") return precompute_task = task.precomputation_task generation_task = precompute_task.generation_task problem = recirq.load(generation_task, base_dir=problem_generation_base_dir)[ 'problem'] # type: ProblemT optimum = recirq.load(precompute_task, base_dir=precomputation_base_dir)[ 'optimum'] # type: OptimizationResult sampler = recirq.get_sampler_by_name(device_name=task.device_name) device = recirq.get_device_obj_by_name(device_name=task.device_name) try: if isinstance(problem, HardwareGridProblem): initial_qubits = [cirq.GridQubit(r, c) for r, c in problem.coordinates] circuit, final_qubits = get_compiled_hardware_grid_circuit( problem=problem, qubits=initial_qubits, gammas=optimum.gammas, betas=optimum.betas, non_negligible=False) elif isinstance(problem, SKProblem): initial_qubits = place_line_on_device( device_name=task.device_name, n=problem.graph.number_of_nodes(), line_placement_strategy='mixed') circuit, final_qubits = get_compiled_sk_model_circuit( problem=problem, qubits=initial_qubits, gammas=optimum.gammas, betas=optimum.betas, non_negligible=False) elif isinstance(problem, ThreeRegularProblem): initial_qubits, circuit, final_qubits = get_compiled_3_regular_maxcut_circuit( problem=problem, device=device, gammas=optimum.gammas, betas=optimum.betas) else: raise ValueError("Unknown problem: {}".format(problem)) except BadlyStructuredCircuitError: print("!!!! Badly structured circuit: {}".format(task)) # TODO https://github.com/quantumlib/Cirq/issues/2553 return if not task.structured: # Left align circuit = compile_to_non_negligible(circuit) circuit = cirq.Circuit(circuit.all_operations()) if task.echoed: assert task.structured raise NotImplementedError("To be implemented in follow-up PR") violation_indices = find_circuit_structure_violations(circuit) circuit.program_id = task.fn result = await sampler.run_async(program=circuit, repetitions=task.n_shots) bitstrings = result.measurements['z'] recirq.save(task=task, data={ 'bitstrings': recirq.BitArray(bitstrings), 'qubits': initial_qubits, 'final_qubits': final_qubits, 'circuit': circuit, 'violation_indices': violation_indices, }, base_dir=base_dir) print(f"{task.fn} complete.")