Come inviare un circuito con Qiskit ad Azure Quantum

Informazioni su come inviare un circuito quantistico Qiskit usando il azure-quantumPython pacchetto. È possibile inviare circuiti Qiskit 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-quantumPython con il tag [qiskit].

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

    Importante

    Assicurarsi di avere la versione più recente di Qiskit. Per altre informazioni, vedere Aggiornare il pacchetto azure-quantumPython.

    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 import Workspace 
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from azure.quantum.qiskit import AzureQuantumProvider

Connettersi al servizio Azure Quantum

Per connettersi al servizio Azure Quantum, è necessario avere l'ID risorsa e la posizione 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 nel notebook e usare le informazioni sull'account per creare Workspace oggetti e AzureQuantumProvider 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")
    )

provider = AzureQuantumProvider(workspace)

Elencare tutti i back-end

È ora possibile stampare tutti i back-end di calcolo quantistico disponibili nell'area di lavoro:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.qpu.aria-1
- ionq.simulator
- microsoft.estimator
- quantinuum.hqs-lt-s1
- quantinuum.hqs-lt-s1-apival
- quantinuum.hqs-lt-s2
- quantinuum.hqs-lt-s2-apival
- quantinuum.hqs-lt-s1-sim
- quantinuum.hqs-lt-s2-sim
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.sim.h1-1e
- rigetti.sim.qvm

Eseguire un circuito semplice

Creare prima di tutto un circuito Qiskit semplice da eseguire.

# 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 

Selezionare un target oggetto per eseguire il programma

Eseguire nel simulatore IonQ

Prima di eseguire su hardware reale, testare il circuito nel simulatore. Usare get_backend per creare un Backend oggetto per connettersi al back-end del simulatore IonQ:

simulator_backend = provider.get_backend("ionq.simulator")

I back-end IonQ supportano i gate da un gateset definito, che vengono compilati per essere eseguiti in modo ottimale nell'hardware. Se il circuito contiene cancelli che non sono inclusi in questo elenco, è necessario eseguire il transpile nell'oggetto supportato gateset usando la transpile funzione fornita da Qiskit:

from qiskit import transpile
circuit = transpile(circuit, simulator_backend)

La funzione transpile restituisce un nuovo oggetto circuito in cui i cancelli vengono scomposti in cancelli supportati nel back-end specificato.

È ora possibile eseguire il programma tramite il servizio Azure Quantum e ottenere il risultato. La cella seguente invia un processo che esegue il circuito con 100 scatti:

job = simulator_backend.run(circuit, shots=8)
job_id = job.id()
print("Job id", job_id)
Job id 00000000-0000-0000-0000-000000000000

Per attendere il completamento del processo e restituire i risultati, eseguire:

result = job.result()
print(result)
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=8, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 4, '111': 4}, memory=['000', '000', '000', '000', '111', '111', '111', '111'], probabilities={'000': 0.5, '111': 0.5}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits=3, metadata={}), status=JobStatus.DONE, name='Qiskit Sample - 3-qubit GHZ circuit')], date=None, status=None, header=None, error_data=None)

Poiché il risultato è un oggetto nativo del pacchetto Qiskit, è possibile usare result.get_countse 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': 4, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 4}

Risultato del circuito Qiskit nel simulatore IonQ

È anche possibile usare la get_memory() funzione per visualizzare i singoli dati di cattura dal processo

result.get_memory(circuit)
['000', '000', '000', '000', '111', '111', '111', '111']

Nota

In IonQ targets, se si invia un processo con un numero dispari di scatti, i risultati verranno arrotondati per difetto al numero pari successivo. Ad esempio, se si specificano 9 scatti, i risultati visualizzeranno i dati per 8 scatti.

Stimare il costo del processo

Prima di eseguire un processo nella QPU, è consigliabile stimare la quantità di costi da eseguire.

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

Per connettersi all'hardware reale (un'unità QPU (Quantum Processor Unit ), specificare semplicemente il nome dell'oggetto target"ionq.qpu.aria-1" al get_backend metodo :

qpu_backend = provider.get_backend("ionq.qpu.aria-1")

Inviare il circuito per l'esecuzione in Azure Quantum, ottenere i risultati ed eseguire plot_histogram per tracciare i risultati.

Nota

Il tempo necessario per eseguire un circuito nella QPU può variare a seconda dei tempi di coda correnti.

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

# Get the job results (this method waits for the Job to complete):
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 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
Result(backend_name='ionq.qpu.aria-1', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', 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 in IonQ QPU

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

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 Qiskit.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 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 azure.quantum.qiskit import AzureQuantumProvider

Connettersi al servizio Azure Quantum

Creare quindi un AzureQuantumProvider 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 = AzureQuantumProvider(workspace)

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

È ora possibile visualizzare tutti i back-end di calcolo targetsquantistico o 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.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.sim.h1-1e
- rigetti.sim.qvm

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. In questo esempio viene usato il run metodo di target per inviare il processo e quindi viene monitorato lo stato del processo.

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

Quando il processo viene eseguito correttamente, 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='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=8, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 4, '111': 4}, memory=['000', '000', '000', '000', '111', '111', '111', '111'], probabilities={'000': 0.5, '111': 0.5}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits=3, metadata={}), status=JobStatus.DONE, name='Qiskit Sample - 3-qubit GHZ circuit')], date=None, status=None, header=None, error_data=None)

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': 4, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 4}

Risultato del circuito Qiskit nel simulatore IonQ

È anche possibile usare la get_memory() funzione per visualizzare i singoli dati di cattura dal processo

result.get_memory(circuit)
['000', '000', '000', '000', '111', '111', '111', '111']

Nota

In IonQ targets, se si invia un processo con un numero dispari di scatti, i risultati verranno arrotondati per difetto al numero pari successivo. Ad esempio, se si specificano 9 scatti, i risultati visualizzeranno i dati per 8 scatti.

Stimare il costo del processo

Prima di eseguire un processo sull'hardware quantistico effettivo o su un'unità di elaborazione quantistica (QPU), è necessario stimare la quantità di costi da eseguire.

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 processo nel simulatore IonQ e aver stimato il costo della QPU, è 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.

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=100)
job_id = job.id()
print("Job id", job_id)

Al termine 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 in IonQ QPU

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