Come inviare un circuito con Qiskit ad Azure Quantum
Informazioni su come inviare un circuito quantistico Qiskit usando il azure-quantum
Python pacchetto. È possibile inviare circuiti Qiskit ad Azure Quantum usando il notebook di Azure Quantum, che include un pacchetto predefinito azure-quantum
Python 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
Python 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
- In VS Code, selezionare Visualizza > Riquadro comandi e selezionare Crea: Nuovo Jupyter Notebook.
- 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.
Accedere all'account Azure, https://portal.azure.com,
Selezionare l'area di lavoro di Azure Quantum e passare a Panoramica.
Copiare i parametri nei campi.
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_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}
È 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}
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
- Accedere al portale di Azure e selezionare l'area di lavoro creata nel passaggio precedente.
- A sinistra selezionare Notebook.
- Fare clic su Notebook personali e quindi su Aggiungi nuovo.
- 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}
È 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}
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())