Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
In diesem Abschnitt werden Sie das Gelernte anwenden, um ein echtes Hybridprogramm PennyLane mit parametrischer Kompilierung zu schreiben. Sie verwenden das Algorithmus-Skript, um ein Problem mit dem Quantum Approximate Optimization Algorithm (QAOA) zu lösen. Das Programm erstellt eine Kostenfunktion, die einem klassischen Max-Cut-Optimierungsproblem entspricht, spezifiziert einen parametrisierten Quantenschaltkreis und verwendet eine einfache Gradientenabstiegsmethode, um die Parameter so zu optimieren, dass die Kostenfunktion minimiert wird. In diesem Beispiel wird der Einfachheit halber das Problemdiagramm im Algorithmus-Skript generiert. Für typischere Anwendungsfälle empfiehlt es sich jedoch, die Problemspezifikation über einen speziellen Kanal in der Eingabedatenkonfiguration bereitzustellen. Das Flag parametrize_differentiable
ist standardmäßig auf eingestellt, True
sodass Sie automatisch die Vorteile der verbesserten Laufzeitleistung durch die parametrische Kompilierung auf supported nutzen können. 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})
Anmerkung
Die parametrische Kompilierung wird auf allen supraleitenden Gate-basierten Systemen unterstützt QPUs Rigetti Computing mit Ausnahme von Pulspegelprogrammen.