Guida introduttiva: Inviare un circuito con Qiskit usando un notebook Azure Quantum

Informazioni su come usare il servizio Azure Quantum per inviare un circuito quantistico Qiskit a un IonQ, Quantinuum o Rigetti quantum computing target. Questo esempio usa un notebook Azure Quantum e il pacchetto azure-quantumPython predefinito. Non sono necessarie installazioni o configurazioni. Per altre informazioni, vedere Circuiti quantistici.

Prerequisiti

Creare un nuovo notebook nell'area di lavoro

  1. Accedere al portale di Azure e selezionare l'area di lavoro creata nel passaggio precedente.
  2. A sinistra selezionare Notebook.
  3. Fare clic su Notebook personali e quindi su Aggiungi nuovo.
  4. In Tipo di kernel selezionare IPython.
  5. Digitare un nome per il file, ad esempio Qiskit.ipynb, e fare clic su Crea file.

Quando si apre il nuovo notebook, viene creato automaticamente il codice per la prima cella, in base alle informazioni sulla sottoscrizione e sull'area di lavoro.

from azure.quantum import Workspace
workspace = Workspace (
    subscription_id = <your subscription ID>, 
    resource_group = <your resource group>,   
    name = <your workspace name>,          
    location = <your location>        
    )

Nota

Se non diversamente specificato, è necessario eseguire ogni cella in ordine durante la creazione per evitare problemi di compilazione.

Fare clic sull'icona triangolare "play" a sinistra della cella per eseguire il codice.

Caricare le importazioni necessarie

Prima di tutto, è necessario importare alcuni moduli aggiuntivi.

Fare clic su + Codice per aggiungere una nuova cella, quindi aggiungere ed eseguire il codice seguente:

from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor
from azure.quantum.qiskit import AzureQuantumProvider

Connessione al servizio Azure Quantum

Usare quindi un costruttore AzureQuantumProvider per creare un oggetto provider che si connette all'area di lavoro di Azure Quantum. Aggiungere una nuova cella, ma non eseguirla ancora, con il codice seguente:

provider = AzureQuantumProvider(
  resource_id="",
  location=""
)

Prima di eseguire questa cella, il programma richiede l'ID risorsa e la posizione dell'area di lavoro di Azure Quantum:

  1. Fare clic su Salva per salvare il notebook.
  2. Fare clic su Panoramica per visualizzare le proprietà dell'area di lavoro.
  3. Passare il puntatore del mouse sopra il campo ID risorsa e fare clic sull'icona Copia negli appunti.
  4. Fare clic su Notebook e aprire il notebook Qiskit.
  5. Incollare l'ID risorsa nel valore per resource_id e quindi aggiungere la stringa di posizione dalla prima cella alla posizione.
  6. Eseguire la cella.

Screenshot del riquadro di panoramica che mostra come recuperare l'ID risorsa e la posizione da un'area di lavoro Di Azure Quantum.

Definire un circuito semplice

In una nuova cella creare un oggetto circuit. Questo esempio è un semplice generatore quantistico di bit casuali. Aggiungere il codice seguente per definire e visualizzare il circuito:

# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(3, 3)
circuit.name = "Qiskit Sample - 3-qubit GHZ circuit"
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure([0, 1, 2], [0, 1, 2])

# Print out the circuit
circuit.draw()
     ┌───┐          ┌─┐      
q_0: ┤ H ├──■───────┤M├──────
     └───┘┌─┴─┐     └╥┘┌─┐   
q_1: ─────┤ X ├──■───╫─┤M├───
          └───┘┌─┴─┐ ║ └╥┘┌─┐
q_2: ──────────┤ X ├─╫──╫─┤M├
               └───┘ ║  ║ └╥┘
c: 3/════════════════╩══╩══╩═
                     0  1  2 

Elenca tutto targets

Nota

I target nomi per i controlli sintassi Quantinuum, emulatori e QPUS sono stati modificati di recente. I nomi aggiornati vengono usati in questo argomento. Per informazioni dettagliate, vedere l'argomento Del provider Quantinuum .

È ora possibile visualizzare tutti i back-end o il calcolo quantistico targets, disponibili nell'area di lavoro. Aggiungere una nuova cella ed eseguire la riga seguente:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Selezionare un target oggetto per eseguire il programma

Per controllare il codice prima di eseguire l'hardware quantistico effettivo, è possibile usare il simulatore quantistico IonQ, ionq.simulator.

Aggiungere una nuova cella e creare un oggetto per rappresentare il simulatore quantistico targetIonQ :

# Get IonQ quantum simulator target:
simulator_backend = provider.get_backend("ionq.simulator")

Eseguire nel simulatore IonQ

Per eseguire il circuito nel simulatore, aggiungere il codice seguente che usa il run metodo dell'oggetto per inviare il processo e quindi monitora lo stato del target processo.

# Submit the circuit to run on Azure Quantum
job = simulator_backend.run(circuit, shots=100)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)

Lo stato del processo viene visualizzato in tempo reale:

Job id 7d909574-98d4-11ec-b382-00155d957f5d
Job status: job is queued
Job status: job is actively running
Job status: job has successfully run

Al termine dell'esecuzione del processo, ottenere i risultati del processo e visualizzarli:

# Get the job results:
result = job.result()
print(result)
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='7d909574-98d4-11ec-b382-00155d957f5d', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts=defaultdict(<class 'int'>, {'000': 50, '111': 50}), probabilities=defaultdict(<class 'int'>, {'000': 0.5, '111': 0.5})), header=QobjExperimentHeader(meas_map='[0, 1, 2]', name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])

Poiché questo tipo result è un oggetto nativo del pacchetto Qiskit, è possibile usare result.get_counts e plot_histogram di Qiskit per visualizzare i risultati. Per assicurarsi che tutte le etichette di stringa di bit possibili siano rappresentate, aggiungerle a counts.

counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
{'000': 50, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 50}

Risultato del circuito Qiskit nel simulatore IonQ

Stimare il costo del processo

Prima di eseguire un processo sull'hardware quantistico effettivo o su un'unità di elaborazione quantistica (QPU), è possibile stimare il costo dell'esecuzione.

Per prima cosa, ottenere di nuovo l'elenco dei provider disponibili:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Creare quindi un oggetto per rappresentare il computer quantistico IonQ:

qpu_backend = provider.get_backend("ionq.qpu")

Per stimare il costo dell'esecuzione di un processo nella QPU, aggiungere ed eseguire una nuova cella usando il estimate_cost metodo di target:

cost = qpu_backend.estimate_cost(circuit, shots=100)

print(f"Estimated cost: {cost.estimated_total}")

In questo modo si visualizza il costo stimato in USD.

Per i dettagli sui prezzi più correnti, vedere Prezzi di IonQ o trovare la propria area di lavoro e visualizzare le opzioni relative ai prezzi nel pannello Provider dell'area di lavoro.

Esecuzione nella QPU di IonQ

Dopo aver eseguito correttamente il simulatore IonQ e aver stimato il costo della QPU, è possibile eseguire il circuito nell'hardware.

Nota

Il tempo necessario per eseguire un circuito nella QPU varia a seconda dei tempi di coda correnti. È possibile visualizzare il tempo medio della coda per un target selezionando il pannello Provider dell'area di lavoro.

Usare lo stesso metodo run e le stesse operazioni usati in precedenza con il validator dell'API per inviare e monitorare il processo:

# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)
Job id 54e8c740-98d9-11ec-b382-00155d957f5d
Job Status: job has successfully run

Al termine dell'esecuzione del processo, ottenere i risultati del processo come prima e visualizzarli in un grafico:

result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id 910b5ac8-98cd-11ec-b3ba-00155d5528cf
Job Status: job has successfully run
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='Job id 54e8c740-98d9-11ec-b382-00155d957f5d', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'0': 505, '1': 6, '2': 1, '3': 1, '4': 1, '5': 10, '6': 11, '7': 488}, probabilities={'0': 0.4932, '1': 0.0059, '2': 0.001, '3': 0.001, '4': 0.001, '5': 0.0098, '6': 0.0117, '7': 0.4766}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])
{'000': 505, '001': 6, '010': 1, '011': 1, '100': 1, '101': 10, '110': 11, '111': 488}

Risultato del circuito Qiskit su IonQ QPU

Selezionare un target oggetto per eseguire il programma

Per controllare il codice prima di eseguirlo su hardware quantistico effettivo, è possibile usare uno dei validator dell'API Quantinuum, quantinuum.sim.h1-1sc.

Aggiungere una nuova cella e creare un oggetto per rappresentare il validator targetAPI Quantinuum :

# Get Quantinuum's API validator target:
apival_backend = provider.get_backend("quantinuum.sim.h1-1sc")

Esecuzione nel validator dell'API

Per eseguire il circuito nel validator API, aggiungere il codice seguente, che usa il run metodo di per inviare il processo e quindi monitora lo stato del target processo.

# Submit the circuit to run on Azure Quantum
job = apival_backend.run(circuit, count=100)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)

Lo stato del processo viene visualizzato in tempo reale:

Job id 89511b08-9691-11ec-be32-00155d00ae89
Job status: job is queued
Job status: job is actively running
Job status: job has successfully run

Al termine dell'esecuzione del processo, ottenere i risultati del processo e visualizzarli:

# Get the job results:
result = job.result()
print(result)
Result(backend_name='quantinuum.sim.h1-1sc', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='89511b08-9691-11ec-be32-00155d00ae89', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 100}, probabilities={'000': 1.0}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])

Poiché questo tipo result è un oggetto nativo del pacchetto Qiskit, è possibile usare result.get_counts e plot_histogram di Qiskit per visualizzare i risultati. Per assicurarsi che tutte le etichette di stringa di bit possibili siano rappresentate, aggiungerle a counts.

counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
{'000': 100, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 0}

Risultato del circuito Qiskit nel validator API Quantinuum

Guardando l'istogramma, è possibile notare che il generatore di numeri casuali ha restituito 0 ogni volta, che non è molto casuale. Ciò è dovuto al fatto che, il validator dell'API garantisce che il codice verrà eseguito correttamente nell'hardware Quantinuum, restituisce anche 0 per ogni misurazione quantistica. Per un vero generatore di numeri casuali, è necessario eseguire il circuito su hardware quantistico.

Stimare il costo del processo

Prima di eseguire un processo sull'hardware quantistico effettivo o su un'unità di elaborazione quantistica (QPU), è possibile stimare il costo dell'esecuzione.

Per prima cosa, ottenere di nuovo l'elenco dei provider disponibili:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Creare quindi un oggetto per rappresentare il modello di sistema Quantinuum H1:

qpu_backend = provider.get_backend("quantinuum.qpu.h1-1")

Per stimare il costo dell'esecuzione di un processo nella QPU, aggiungere ed eseguire una nuova cella usando il estimate_cost metodo di target:

cost = qpu_backend.estimate_cost(circuit, count=100)

print(f"Estimated cost: {cost.estimated_total}")
Estimated cost: 5.72

L'output visualizza il costo stimato in H-System Quantum Credits (HQCs).

Per i dettagli dei prezzi più aggiornati, vedere Prezzi di Azure Quantum o visualizzare le opzioni dei prezzi nel pannello Provider dell'area di lavoro. Per visualizzare lo stato e l'utilizzo correnti del credito, selezionare Credits and quotas (Crediti e quote).

Esecuzione in una QPU Quantinuum

Dopo aver eseguito correttamente il circuito nel validator api e stimando il costo della QPU, è possibile eseguirlo nell'hardware.

Nota

Il tempo necessario per eseguire un circuito nella QPU può variare a seconda dei tempi di coda correnti. È possibile visualizzare il tempo medio della coda per un target selezionando il pannello Provider dell'area di lavoro.

Usare lo stesso metodo run e le stesse operazioni usati in precedenza con il validator dell'API per inviare e monitorare il processo:

# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, count=100)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)
Job id 48282d18-9c15-11ec-bfbd-00155d6373ba
Job Status: job has successfully run

Al termine dell'esecuzione del processo, ottenere i risultati del processo come prima e visualizzarli in un istogramma:

result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)

È possibile vedere che i risultati sono ora suddivisi approssimativamente tra 0 e 1.

Result(backend_name='quantinuum.qpu.h1-1', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='48282d18-9c15-11ec-bfbd-00155d6373ba', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts={'111': 53, '101': 1, '000': 46}, probabilities={'111': 0.53, '101': 0.01, '000': 0.46}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 46, '001': 0, '010': 0, '011': 0, '100': 0, '101': 1, '110': 0, '111': 53}

Risultato del circuito Qiskit in Quantinuum QPU

Selezionare un target oggetto per eseguire il programma

Per controllare il codice prima di eseguirlo sull'hardware quantistico effettivo, è possibile usare il simulatore quantistico Rigetti, rigetti.sim.qvm.

Aggiungere una nuova cella e creare un oggetto per rappresentare il simulatore quantistico targetRigetti :

# Get Rigetti quantum simulator target:
simulator_backend = provider.get_backend("rigetti.sim.qvm")

Eseguire nel simulatore Rigetti

Per eseguire il circuito nel simulatore, aggiungere il codice seguente che usa il run metodo di target per inviare il processo e quindi monitora lo stato del processo.

# Submit the circuit to run on Azure Quantum
job = simulator_backend.run(circuit, shots=100)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)

Lo stato del processo viene visualizzato in tempo reale:

Job id 5de5e2a0-39e3-11ed-bd56-00155d76e336
Job status: job is queued
Job status: job is actively running
Job status: job has successfully run

Al termine dell'esecuzione del processo, ottenere i risultati del processo e visualizzarli:

# Get the job results:
result = job.result()
print(result)
Result(backend_name='rigetti.sim.qvm', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='5de5e2a0-39e3-11ed-bd56-00155d76e336', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts={'[0, 0, 0]': 54, '[1, 1, 1]': 46}, probabilities={'[0, 0, 0]': 0.59, '[1, 1, 1]': 0.41}), header=QobjExperimentHeader(metadata=None, name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])

Poiché questo tipo result è un oggetto nativo del pacchetto Qiskit, è possibile usare result.get_counts e plot_histogram di Qiskit per visualizzare i risultati. Per assicurarsi che tutte le etichette di stringa di bit possibili siano rappresentate, aggiungerle a counts.

counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
{'000': 50, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 50}

Risultato del circuito Qiskit nel simulatore Rigetti

Esecuzione in QPU Rigetti

Dopo aver eseguito correttamente il simulatore Rigetti, è il momento di eseguire il circuito sull'hardware.

Nota

Il tempo necessario per eseguire un circuito nella QPU varia a seconda dei tempi di coda correnti. È possibile visualizzare il tempo medio della coda per un target oggetto selezionando il pannello Provider dell'area di lavoro.

Per prima cosa, ottenere di nuovo l'elenco dei provider disponibili:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Creare quindi un oggetto per rappresentare il computer quantistico Rigetti:

qpu_backend = provider.get_backend("rigetti.qpu.aspen-m-3")

Usare lo stesso metodo e le stesse run operazioni usate in precedenza con il simulatore quantistico Rigetti per inviare e monitorare il processo:

# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)
Job id 54e8c740-98d9-11ec-b382-00155d957f5d
Job Status: job has successfully run

Al termine dell'esecuzione del processo, ottenere i risultati del processo come prima e visualizzarli in un grafico:

result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id cd4800f4-39e5-11ed-bd56-00155d76e336
Job Status: job has successfully run
Result(backend_name='rigetti.qpu.aspen-m-3', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='cd4800f4-39e5-11ed-bd56-00155d76e336', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'[0, 0, 0]': 415.0, '[1, 1, 1]': 280.0, '[1, 1, 0]': 103.0, '[0, 1, 1]': 83.0, '[1, 0, 1]': 8.0, '[0, 1, 0]': 36.0, '[1, 0, 0]': 74.0, '[0, 0, 1]': 25.0}, probabilities={'[0, 0, 0]': 0.4052734375, '[1, 1, 1]': 0.2734375, '[1, 1, 0]': 0.1005859375, '[0, 1, 1]': 0.0810546875, '[1, 0, 1]': 0.0078125, '[0, 1, 0]': 0.03515625, '[1, 0, 0]': 0.072265625, '[0, 0, 1]': 0.0244140625}), header=QobjExperimentHeader(metadata=None, name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])
{'000': 0, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 0, '[0, 0, 0]': 415.0, '[1, 1, 1]': 280.0, '[1, 1, 0]': 103.0, '[0, 1, 1]': 83.0, '[1, 0, 1]': 8.0, '[0, 1, 0]': 36.0, '[1, 0, 0]': 74.0, '[0, 0, 1]': 25.0}

Risultato del circuito Qiskit in QPU Rigetti

Importante

L'invio di più circuiti in un singolo processo non è attualmente supportato. Come soluzione alternativa, è possibile chiamare il backend.run metodo per inviare ogni circuito in modo asincrono, quindi recuperare i risultati di ogni processo. Ad esempio:

jobs = []
for circuit in circuits:
    jobs.append(backend.run(circuit, shots=N))

results = []
for job in jobs:
    results.append(job.result())

Passaggi successivi

Per altri esempi da eseguire, vedere la directory degli esempi per Azure Quantum.

Infine, per altre informazioni sulla scrittura di programmi Q#, vedere il Manuale dell'utente del linguaggio di programmazione Q#.