Inicio rápido: Envío de un circuito con Qiskit a Azure Quantum

Aprenda a usar el azure-quantumPython paquete para enviar circuitos cuánticos de Qiskit a una computación target cuántica ionQ, Quantinuum o Rigetti a través del servicio Azure Quantum. Para más información, consulte Circuitos cuánticos.

Prerrequisitos

  • Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.

  • Crear un área de trabajo de Azure Quantum. Para más información, consulte Creación de un área de trabajo de Azure Quantum.

  • Instale el paquete de azure-quantum para Python más reciente mediante la etiqueta [qiskit].

    Nota:

    Antes de instalar o actualizar el paquete azure-quantum , desinstale todas las versiones de pyqir, pyqir-*y qiskit-qir en la máquina para evitar conflictos de dependencia.

    Sugerencia

    Si usa Miniconda o Anaconda, también puede crear un nuevo entorno; para ello, descargue el archivo environment.yml y ejecute lo siguiente:

    conda env create -f environment.yml
    

    Esto crea un nuevo entorno de Conda que puede activar con lo siguiente:

    conda activate azurequantum
    
  • Inicie su editor de código preferido o una herramienta Python interactiva, como VS Code, Jupyter o iPython.

Nota:

En los ejemplos de este inicio rápido se usa un entorno de Jupyter Notebook. En el entorno de Conda, ejecute Jupyter Notebook.

Carga de las importaciones necesarias

En Jupyter Notebooks, cree un cuaderno que use el Python kernel 3 . En la primera celda, ejecute el código siguiente para cargar las importaciones necesarias:

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

Conexión al servicio Azure Quantum

Para conectarse al servicio Azure Quantum, el programa necesitará el identificador de recurso y la ubicación del área de trabajo de Azure Quantum. Inicie sesión en su cuenta de Azure, https://portal.azure.com, vaya al área de trabajo de Azure Quantum y copie los valores del encabezado.

Cómo recuperar el identificador de recurso y la ubicación de un área de trabajo de Azure Quantum

Pegue los valores en el constructor AzureQuantumProvider siguiente para crear un objeto provider que se conecte al área de trabajo de Azure Quantum.

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

Enumeración de todos los back-end

Ahora puede imprimir todos los back-end de computación cuántica que están disponibles en el área de trabajo:

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.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-11
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Ejecución de un circuito simple

En primer lugar, cree un circuito de Qiskit simple para ejecutarlo.

# 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 

Para obtener un resultado rápidamente, use provider.get_backend para crear un objeto Backend para conectarse al back-end del simulador de IonQ:

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

Los back-end de IonQ admiten puertas de un conjunto de puertas definido, que se compilan para ejecutarse de forma óptima en el hardware. Si el circuito contiene puertas que no están en esta lista, deberá transpilar en el conjunto de puertas admitido mediante la función transpile proporcionada por Qiskit:

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

Esto devolverá un nuevo objeto de circuito en el que las puertas se descomponen en puertas compatibles con el back-end especificado.

Ahora puede ejecutar el programa a través del servicio Azure Quantum y obtener el resultado. La celda siguiente envía un trabajo que ejecuta el circuito con 100 tomas:

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

Para supervisar el progreso del trabajo, puede usar el objeto job_monitor de Qiskit importado anteriormente para hacer un seguimiento del estado del trabajo. Esta llamada producirá un bloqueo hasta que se complete el trabajo:

job_monitor(job)
Job Status: job has successfully run

Para esperar hasta que se complete el trabajo y devolver los resultados, ejecute:

result = job.result()

Esto devuelve un objeto qiskit.Result.

type(result)
qiskit.result.result.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=100, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 50, '111': 50}, probabilities={'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'))])

Dado que el resultado es un objeto nativo del paquete de Qiskit, puede usar los objetos result.get_counts y plot_histogram de Qiskit para visualizar los resultados. Para asegurarse de que se representan todas las etiquetas de cadena de bits posibles, agréguelas 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}

Resultado del circuito de Qiskit en el simulador de IonQ

Estimación del costo del trabajo

Antes de ejecutar un trabajo en la QPU, puede calcular cuánto cuesta ejecutarse. Para calcular el costo de ejecutar un trabajo en la QPU, puede usar el método estimate_cost.

backend = provider.get_backend("ionq.qpu")
cost = backend.estimate_cost(circuit, shots=1024)

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

El costo estimado se muestra en USD.

Para obtener los precios más actuales, consulte los precios de IonQ o vaya a su área de trabajo y consulte las opciones de precios en la hoja "Proveedores" en: aka.ms/aq/myworkspaces.

Ejecución en la QPU de IonQ

Para conectarse al hardware real (una unidad de procesador cuántico (QPU), simplemente proporcione el nombre del al target"ionq.qpu"provider.get_backend método :

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

Envíe el circuito para que se ejecute en Azure Quantum.

Nota:

El tiempo necesario para ejecutar un circuito en la QPU puede variar en función de los tiempos de cola actuales.

Como antes, use job_monitor para hacer un seguimiento del estado del trabajo, y plot_histogram para trazar los resultados.

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

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

# Get the job results (this method also waits for the Job to complete):
result = qpu_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.simulator', 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}

Resultado del circuito de Qiskit en la QPU de IonQ

Carga de las importaciones necesarias

En Jupyter Notebooks, cree un cuaderno que use el Python kernel 3 . En la primera celda, ejecute el código siguiente para cargar las importaciones necesarias:

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

Conexión al servicio Azure Quantum

Para conectarse al servicio Azure Quantum, el programa necesitará el identificador de recurso y la ubicación del área de trabajo de Azure Quantum. Inicie sesión en su cuenta de Azure, https://portal.azure.com, vaya al área de trabajo de Azure Quantum y copie los valores del encabezado.

Cómo recuperar el identificador de recurso y la ubicación de un área de trabajo de Azure Quantum

Pegue los valores en el constructor AzureQuantumProvider siguiente para crear un objeto provider que se conecte al área de trabajo de Azure Quantum.

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

Enumeración de todos los back-end

Nota:

Los target nombres de los comprobadores de sintaxis de Quantinuum, emuladores y QPU han cambiado recientemente. Los nombres actualizados se usan en este tema. Para obtener más información, consulte el tema del proveedor Quantinuum .

Ahora puede imprimir todos los back-end de computación cuántica que están disponibles en el área de trabajo:

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.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-11
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Ejecutar en el comprobador de sintaxis

Para probar el programa antes de ejecutarlo en el hardware, ejecútelo primero en el comprobador de sintaxis de Quantinuum.

Nota:

El back-end del comprobador de sintaxis quantinuum siempre devolverá 0 en la medida.

# Get Quantinuum's syntax checker backend:
syntax_backend = provider.get_backend("quantinuum.sim.h1-1sc")
# 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 

Ahora puede ejecutar el programa a través del servicio Azure Quantum y obtener el resultado. La celda siguiente envía un trabajo que ejecuta el circuito con 1024 tomas:

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

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

# Get the job results (this method also 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='quantinuum.qpu.h1-1sc', 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={'000': 1024}, probabilities={'000': 1.0}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 1024, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 0}

Resultado del circuito Qiskit en el validador de API de Quantinuum

Nota:

Aunque el comprobador de sintaxis garantiza que el código se ejecutará correctamente en el hardware quantinuum, también devuelve 0 para cada medida cuántica. Para una medida cuántica verdadera, debe ejecutar el circuito en hardware cuántico.

Estimación del costo del trabajo

Antes de ejecutar un trabajo en la QPU, puede calcular cuánto cuesta ejecutarse. Para calcular el costo de ejecutar un trabajo en la QPU, puede usar el método estimate_cost.

qpu_backend = provider.get_backend("quantinuum.qpu.h1-1")
cost = qpu_backend.estimate_cost(circuit, shots=1024)

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

Esto imprime el costo estimado en créditos cuánticos de H-System (HQC).

Para obtener los detalles de precios más actuales, consulte Precios de Azure Quantum o busque el área de trabajo y vea las opciones de precios en la pestaña Proveedor del área de trabajo a través de: aka.ms/aq/myworkspaces.

Ejecución en una QPU de Quantinuum

Después de una ejecución correcta en el validador de API, puede ejecutar el trabajo en uno de los procesadores de hardware de Quantinuum, una unidad de procesador cuántico (QPU).

Nota:

El tiempo necesario para ejecutar un circuito en la QPU puede variar en función de los tiempos de cola actuales.

# Get Quantinuum's QPU backend:
qpu_backend = provider.get_backend("quantinuum.qpu.h1-1")
# 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 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
# Get the job results (this method also 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)
Result(backend_name='quantinuum.qpu.h1-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={'011': 16, '010': 5, '001': 1, '000': 500, '111': 471, '101': 6, '100': 17, '110': 8}, probabilities={'011': 0.015625, '010': 0.0048828125, '001': 0.0009765625, '000': 0.48828125, '111': 0.4599609375, '101': 0.005859375, '100': 0.0166015625, '110': 0.0078125}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 500, '001': 1, '010': 5, '011': 16, '100': 17, '101': 6, '110': 8, '111': 471}

Resultado del circuito de Qiskit en la QPU de Quantinuum

Carga de las importaciones necesarias

En Jupyter Notebooks, cree un cuaderno que use el Python kernel 3 . En la primera celda, ejecute el código siguiente para cargar las importaciones necesarias:

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

Conexión al servicio Azure Quantum

Para conectarse al servicio Azure Quantum, el programa necesitará el identificador de recurso y la ubicación del área de trabajo de Azure Quantum. Inicie sesión en su cuenta de Azure, https://portal.azure.com, vaya al área de trabajo de Azure Quantum y copie los valores del encabezado.

Cómo recuperar el identificador de recurso y la ubicación de un área de trabajo de Azure Quantum

Pegue los valores en el constructor AzureQuantumProvider siguiente para crear un objeto provider que se conecte al área de trabajo de Azure Quantum.

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

Enumeración de todos los back-end

Ahora puede imprimir todos los back-end de computación cuántica que están disponibles en el área de trabajo:

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.qpu.h1-2
- quantinuum.sim.h1-2sc
- quantinuum.sim.h1-1e
- quantinuum.sim.h1-2e
- rigetti.sim.qvm
- rigetti.qpu.aspen-11
- rigetti.qpu.aspen-m-2
- rigetti.qpu.aspen-m-3

Ejecución en el simulador de QVM

Para probar el programa antes de ejecutarlo en el hardware, ejecútelo primero en el simulador QVM de Rigetti.

# Get Rigetti's QVM simulator backend:
qvm_backend = provider.get_backend("rigetti.sim.qvm")
# 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 

Ahora puede ejecutar el programa a través del servicio Azure Quantum y obtener el resultado. La celda siguiente envía un trabajo que ejecuta el circuito con 1024 tomas:

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

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

# Get the job results (this method also 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='rigetti.sim.qvm"', 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={'000': 1024}, probabilities={'000': 1.0}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 1024, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 0}

Resultado del circuito Qiskit en el simulador QVM de Rigetti

Ejecución en una QPU de Rigetti

Después de ejecutarse correctamente en el simulador de QVM, puede ejecutar el trabajo en uno de los procesadores de hardware de Rigetti (una unidad de procesador cuántico [QPU]).

Nota:

El tiempo necesario para ejecutar un circuito en la QPU puede variar en función de los tiempos de cola actuales.

# Get Rigetti's QPU backend:
qpu_backend = provider.get_backend("rigetti.qpu.aspen-m-3")
# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=500)
job_id = job.id()
print("Job id", job_id)

# Monitor job progress and wait until complete:
job_monitor(job)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
# Get the job results (this method also 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)
Result(backend_name='rigetti.qpu.aspen-m-3', 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={'011': 16, '010': 5, '001': 1, '000': 500, '111': 471, '101': 6, '100': 17, '110': 8}, probabilities={'011': 0.015625, '010': 0.0048828125, '001': 0.0009765625, '000': 0.48828125, '111': 0.4599609375, '101': 0.005859375, '100': 0.0166015625, '110': 0.0078125}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit'))])
{'000': 500, '001': 1, '010': 5, '011': 16, '100': 17, '101': 6, '110': 8, '111': 471}

Resultado del circuito Qiskit en Rigetti QPU

Importante

Actualmente, no se admite el envío de varios circuitos en un solo trabajo. Como solución alternativa, puede llamar al método backend.run para enviar cada circuito de forma asincrónica y, a continuación, capturar los resultados de cada trabajo. Por ejemplo:

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

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