As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Usando trabalhos híbridos e PennyLane para executar um algoritmo QAOA
Nesta seção, você usará o que aprendeu para escrever um programa híbrido real usando PennyLane a compilação paramétrica. Você usa o script do algoritmo para resolver um problema do Algoritmo de Otimização Aproximada Quântica (QAOA). O programa cria uma função de custo correspondente a um problema clássico de otimização do Max Cut, especifica um circuito quântico parametrizado e usa um método simples de gradiente descendente para otimizar os parâmetros para que a função de custo seja minimizada. Neste exemplo, geramos o gráfico do problema no script do algoritmo para simplificar, mas para casos de uso mais comuns, a melhor prática é fornecer a especificação do problema por meio de um canal dedicado na configuração dos dados de entrada. O parametrize_differentiable
padrão do sinalizador é para que você True
obtenha automaticamente os benefícios do desempenho aprimorado do tempo de execução a partir da compilação paramétrica, quando suportada. QPUs
import os import json import time from braket.jobs import save_job_result from braket.jobs.metrics import log_metric import networkx as nx import pennylane as qml from pennylane import numpy as np from matplotlib import pyplot as plt def init_pl_device(device_arn, num_nodes, shots, max_parallel): return qml.device( "braket.aws.qubit", device_arn=device_arn, wires=num_nodes, shots=shots, # Set s3_destination_folder=None to output task results to a default folder s3_destination_folder=None, parallel=True, max_parallel=max_parallel, parametrize_differentiable=True, # This flag is True by default. ) def start_here(): input_dir = os.environ["AMZN_BRAKET_INPUT_DIR"] output_dir = os.environ["AMZN_BRAKET_JOB_RESULTS_DIR"] job_name = os.environ["AMZN_BRAKET_JOB_NAME"] checkpoint_dir = os.environ["AMZN_BRAKET_CHECKPOINT_DIR"] hp_file = os.environ["AMZN_BRAKET_HP_FILE"] device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"] # Read the hyperparameters with open(hp_file, "r") as f: hyperparams = json.load(f) p = int(hyperparams["p"]) seed = int(hyperparams["seed"]) max_parallel = int(hyperparams["max_parallel"]) num_iterations = int(hyperparams["num_iterations"]) stepsize = float(hyperparams["stepsize"]) shots = int(hyperparams["shots"]) # Generate random graph num_nodes = 6 num_edges = 8 graph_seed = 1967 g = nx.gnm_random_graph(num_nodes, num_edges, seed=graph_seed) # Output figure to file positions = nx.spring_layout(g, seed=seed) nx.draw(g, with_labels=True, pos=positions, node_size=600) plt.savefig(f"{output_dir}/graph.png") # Set up the QAOA problem cost_h, mixer_h = qml.qaoa.maxcut(g) def qaoa_layer(gamma, alpha): qml.qaoa.cost_layer(gamma, cost_h) qml.qaoa.mixer_layer(alpha, mixer_h) def circuit(params, **kwargs): for i in range(num_nodes): qml.Hadamard(wires=i) qml.layer(qaoa_layer, p, params[0], params[1]) dev = init_pl_device(device_arn, num_nodes, shots, max_parallel) np.random.seed(seed) cost_function = qml.ExpvalCost(circuit, cost_h, dev, optimize=True) params = 0.01 * np.random.uniform(size=[2, p]) optimizer = qml.GradientDescentOptimizer(stepsize=stepsize) print("Optimization start") for iteration in range(num_iterations): t0 = time.time() # Evaluates the cost, then does a gradient step to new params params, cost_before = optimizer.step_and_cost(cost_function, params) # Convert cost_before to a float so it's easier to handle cost_before = float(cost_before) t1 = time.time() if iteration == 0: print("Initial cost:", cost_before) else: print(f"Cost at step {iteration}:", cost_before) # Log the current loss as a metric log_metric( metric_name="Cost", value=cost_before, iteration_number=iteration, ) print(f"Completed iteration {iteration + 1}") print(f"Time to complete iteration: {t1 - t0} seconds") final_cost = float(cost_function(params)) log_metric( metric_name="Cost", value=final_cost, iteration_number=num_iterations, ) # We're done with the hybrid job, so save the result. # This will be returned in job.result() save_job_result({"params": params.numpy().tolist(), "cost": final_cost})
nota
A compilação paramétrica é suportada em todas as formas supercondutoras baseadas em portas QPUs Rigetti Computing com exceção dos programas de nível de pulso.