Come inviare un circuito con Cirq ad Azure Quantum

Informazioni su come inviare un circuito quantistico Cirq usando il azure-quantumPython pacchetto. È possibile inviare circuiti Cirq ad Azure Quantum usando il notebook di Azure Quantum, che include un pacchetto predefinito azure-quantumPython o dal computer locale.

Per altre informazioni, vedere Circuiti quantistici.

Prerequisiti

Per informazioni dettagliate sull'installazione, vedere Installazione di QDK in VS Code.

  • Un'area di lavoro di Azure Quantum nella sottoscrizione di Azure. Per creare un'area di lavoro, vedere Creare un'area di lavoro di Azure Quantum.

  • Ambiente Python con Python e Pip installato.

  • VS Code con le estensioni Azure Quantum Development Kit, Pythone Jupyter installate.

  • Pacchetto di Azure Quantum azure-quantum con il tag [cirq] e i qsharp pacchetti e ipykernel .

    python -m pip install --upgrade azure-quantum[cirq] qsharp ipykernel 
    

    Nota

    Se il kernel ipykernel Jupyter Python non viene rilevato, VS Code chiederà di installarlo.

Creare un nuovo notebook di Jupyter

  1. In VS Code, selezionare Visualizza > Riquadro comandi e selezionare Crea: Nuovo Jupyter Notebook.
  2. In alto a destra VS Code rileverà e visualizzerà la versione di Python e l'ambiente virtuale Python selezionato per il notebook. Se si dispone di più Python ambienti, potrebbe essere necessario selezionare un kernel usando la selezione kernel in alto a destra. Se non è stato rilevato alcun ambiente, vedere Jupyter Notebooks in VS Code per informazioni sull'installazione.

Caricare le importazioni necessarie

Nella prima cella del notebook eseguire il codice seguente per caricare le importazioni necessarie:

import azure.quantum
from azure.quantum.cirq import AzureQuantumService

Connettersi al servizio Azure Quantum

Per connettersi al servizio Azure Quantum, il programma dovrà avere l'ID della risorsa e il percorso dell'area di lavoro di Azure Quantum.

  1. Accedere all'account Azure, https://portal.azure.com,

  2. Selezionare l'area di lavoro di Azure Quantum e passare a Panoramica.

  3. Copiare i parametri nei campi.

    Screenshot di Visual Studio Code che mostra come espandere il riquadro di panoramica dell'area di lavoro quantum.

Aggiungere una nuova cella e usare le informazioni sull'account per creare Workspace oggetti e AzureQuantumService per connettersi all'area di lavoro di Azure Quantum.

workspace = Workspace(  
    resource_id = "", # Add the resourceID of your workspace
    location = "" # Add the location of your workspace (for example "westus")
    )

service = AzureQuantumService(workspace)

Elenca tutto targets

Usare il targets()metodo per elencare tutti gli elementi dell'area targets di lavoro che possono eseguire il circuito, inclusi il tempo e la disponibilità correnti della coda.

Nota

Tutto nell'area targets di lavoro potrebbe non essere elencato. Qui verrà elencato solo l'oggetto targets che può accettare un circuito Cirq o OpenQASM.

print(service.targets())
[<Target name="quantinuum.qpu.h1-1", avg. queue time=0 s, Degraded>,
<Target name="quantinuum.sim.h1-1sc", avg. queue time=1 s, Available>,
<Target name="quantinuum.sim.h1-1e", avg. queue time=40 s, Available>,
<Target name="ionq.simulator", avg. queue time=3 s, Available>,
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>]

Creare un circuito semplice

Creare quindi un circuito Cirq semplice da eseguire. Questo circuito usa la radice quadrata di X gate, nativa del sistema hardware IonQ.

import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0)**0.5,             # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───X^0.5───@───M────────
              │   │
1: ───────────X───M────────

Selezionare un target oggetto per eseguire il programma

Esecuzione nel simulatore IonQ

È ora possibile eseguire il programma tramite il servizio Azure Quantum e ottenere il risultato. La cella seguente invia un processo al simulatore IonQ predefinito, che esegue il circuito con 100 immagini, attende il completamento del processo e restituisce i risultati.

result = service.run(program=circuit, repetitions=100, target="ionq.simulator")

Questa operazione restituisce un oggetto cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Stimare il costo del processo

Prima di eseguire un processo nella QPU, è necessario stimare il costo dell'esecuzione.

Per i dettagli più aggiornati sui prezzi, vedere i prezzi di IonQ oppure trovare l'area di lavoro e visualizzare le opzioni relative ai prezzi nella scheda "Provider" dell'area di lavoro tramite: aka.ms/aq/myworkspaces.

Esecuzione nella QPU di IonQ

Il processo precedente è stato eseguito nel simulatore predefinito, "ionq.simulator". Tuttavia, è anche possibile eseguirlo nel processore hardware di IonQ, un'unità di elaborazione query (QPU). Per l'esecuzione nella QPU di IonQ, specificare "ionq.qpu.aria-1" come argomento target:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu.aria-1",
    timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)

Questa operazione restituisce di nuovo un oggetto cirq.Result.

print(result)
b=0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111, 0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111

Modello asincrono con processi

Per i circuiti a esecuzione prolungata, può essere utile l'esecuzione asincrona. Il metodo service.create_job restituisce un oggetto Job, che è possibile usare per ottenere i risultati dopo che il processo è stato eseguito correttamente.

job = service.create_job(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Per controllare lo stato del processo, usare job.status():

print(job.status())
'completed'

Per attendere il completamento del processo e quindi ottenere i risultati, usare la chiamata di blocco job.results():

result = job.results()
print(result)
00: 0.5
11: 0.5

Si noti che questa operazione non restituisce un oggetto cirq.Result. Restituisce invece un oggetto risultato specifico del simulatore IonQ e usa le probabilità di stato anziché i dati dell'immagine.

type(result)
cirq_ionq.results.SimulatorResult

Per convertire questo oggetto in un oggetto cirq.Result, usare result.to_cirq_result():

print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100

Prerequisiti

  • Un account Azure con una sottoscrizione attiva. Se non si ha un account Azure, registrarsi gratuitamente e iscriversi per ottenere una sottoscrizione con pagamento in base al consumo.
  • Un'area di lavoro di Azure Quantum. Per altre informazioni, vedere Creare un'area di lavoro di Azure Quantum.

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. Digitare un nome per il file, ad esempio Cirq.ipynb, e fare clic su Crea file.

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

from azure.quantum import Workspace
workspace = Workspace ( 
  resource_id = "", # Add your resource_id 
  location = ""  # Add your workspace location (for example, "westus") 
)

Nota

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

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

Caricare le importazioni necessarie

Prima di tutto, è necessario importare un modulo aggiuntivo.

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

from azure.quantum.cirq import AzureQuantumService

Connettersi al servizio Azure Quantum

Creare quindi un AzureQuantumService oggetto usando l'oggetto della cella precedente per connettersi all'area workspace di lavoro di Azure Quantum. Aggiungere una nuova cella con il codice seguente:

provider = AzureQuantumService(workspace)

Definire un circuito semplice

Creare quindi un circuito Cirq semplice da eseguire. Questo circuito usa la radice quadrata di X gate, nativa del sistema hardware IonQ.

import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0)**0.5,             # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───X^0.5───@───M────────
              │   │
1: ───────────X───M────────

Elenca tutto targets

Usare il targets()metodo per elencare tutti gli elementi dell'area targets di lavoro che possono eseguire il circuito, inclusi il tempo e la disponibilità correnti della coda.

Nota

Tutto nell'area targets di lavoro potrebbe non essere elencato. Qui verrà elencato solo l'oggetto targets che può accettare un circuito Cirq o OpenQASM.

print("This workspace's targets:")
for target in service.targets():
     print(target)
This workspace's targets:
<Target name="quantinuum.qpu.h1-1", avg. queue time=0 s, Degraded>
<Target name="quantinuum.sim.h1-1sc", avg. queue time=1 s, Available>
<Target name="quantinuum.sim.h1-1e", avg. queue time=40 s, Available>
<Target name="ionq.simulator", avg. queue time=3 s, Available>
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>

Nota

L'elenco completo di può essere diverso per l'area di target lavoro.

Selezionare un target oggetto per eseguire il programma

Eseguire nel simulatore IonQ

Per controllare il circuito prima di eseguirlo sull'hardware quantistico effettivo, è possibile usare il simulatore IonQ, ionq.simulator.

La cella seguente invia un processo che esegue il circuito con 100 immagini, attende il completamento del processo e restituisce i risultati.

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Questa operazione restituisce un oggetto cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

È possibile tracciare i risultati in un istogramma:

import pylab as pl

pl.hist(result.data)
pl.ylabel("Counts")
pl.xlabel("Result")

Stimare il costo del processo

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

Per i dettagli sui prezzi più aggiornati, vedere Prezzi di IonQ o visualizzare le opzioni relative ai 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 nella QPU di IonQ

Il processo precedente è stato eseguito nel simulatore predefinito, ionq.simulator. Tuttavia, è anche possibile eseguirlo nel processore hardware di IonQ, un'unità di elaborazione query (QPU). Per l'esecuzione nella QPU di IonQ, specificare ionq.qpu.aria-1 come argomento target:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu.aria-1",
    timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)

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 oggetto selezionando il pannello Provider dell'area di lavoro.

Questa operazione restituisce di nuovo un oggetto cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Modello asincrono con processi

Per i circuiti a esecuzione prolungata, può essere utile l'esecuzione asincrona. Il metodo service.create_job restituisce un oggetto Job, che è possibile usare per ottenere i risultati dopo che il processo è stato eseguito correttamente.

job = service.create_job(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Per controllare lo stato del processo, usare job.status():

print(job.status())
'completed'

Per attendere il completamento del processo e quindi ottenere i risultati, usare la chiamata di blocco job.results():

result = job.results()
print(result)
00: 0.5
11: 0.5

Nota

La funzione job.results() non restituisce un oggetto cirq.Result. Restituisce invece un oggetto risultato specifico del simulatore IonQ e usa le probabilità di stato anziché i dati dell'immagine.

type(result)
cirq_ionq.results.SimulatorResult

Per convertire questo oggetto in un oggetto cirq.Result, usare result.to_cirq_result():

print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100

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())