Utilisation de tâches hybrides et exécution PennyLane d'un QAOA algorithme - Amazon Braket

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation de tâches hybrides et exécution PennyLane d'un QAOA algorithme

Dans cette section, vous utiliserez ce que vous avez appris pour écrire un véritable programme hybride à l' PennyLane aide d'une compilation paramétrique. Vous utilisez le script d'algorithme pour résoudre un problème lié à l'algorithme d'optimisation approximative quantique (QAOA). Le programme crée une fonction de coût correspondant à un problème d'optimisation Max Cut classique, spécifie un circuit quantique paramétré et utilise une méthode simple de descente du gradient pour optimiser les paramètres afin de minimiser la fonction de coût. Dans cet exemple, nous générons le graphe du problème dans le script de l'algorithme pour des raisons de simplicité, mais pour les cas d'utilisation les plus courants, la meilleure pratique consiste à fournir la spécification du problème via un canal dédié dans la configuration des données d'entrée. L'indicateur est parametrize_differentiable défini par défaut pour True que vous puissiez bénéficier automatiquement des avantages d'une amélioration des performances d'exécution grâce à la compilation paramétrique si elle est prise en charge. 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})
Note

La compilation paramétrique est prise en charge sur tous les appareils supraconducteurs basés sur des portes à partir de QPUs Rigetti Computing à l'exception des programmes de mesure du pouls.