Compartir a través de


Envío de un circuito con Qiskit a Azure Quantum

Aprenda a enviar un circuito cuántico qiskit mediante el azure-quantumPython paquete. Puede enviar circuitos Qiskit a Azure Quantum mediante el cuaderno de Azure Quantum, que tiene un paquete integrado azure-quantumPython o desde la máquina local.

Para más información, consulte Circuitos cuánticos.

Requisitos previos

Para obtener más información sobre la instalación, consulte Instalación del QDK en VS Code.

Crear un nuevo cuaderno de Jupyter Notebook

  1. En VS Code, seleccione Ver > Paleta de comandos y seleccione Crear: Nuevo Jupyter Notebook.
  2. En la parte superior derecha, VS Code detectará y mostrará la versión de Python y el entorno virtual Python seleccionado para el cuaderno. Si tiene varios Python entornos, es posible que tenga que seleccionar un kernel mediante el selector de kernel en la parte superior derecha. Si no se detectó ningún entorno, consulte Jupyter Notebooks in VS Code (Cuadernos de Jupyter Notebook en VS Code ) para obtener información de configuración.

Carga de las importaciones necesarias

En la primera celda del cuaderno, ejecute el código siguiente para cargar las importaciones necesarias:

import azure.quantum
from azure.quantum import Workspace 
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from azure.quantum.qiskit import AzureQuantumProvider

Conexión al servicio Azure Quantum

Para conectarse al servicio Azure Quantum, necesita el identificador de recurso y la ubicación del área de trabajo de Azure Quantum.

  1. Inicie sesión en su cuenta de Azure, https://portal.azure.com,

  2. Seleccione el área de trabajo de Azure Quantum y vaya a Información general.

  3. Copie los parámetros en los campos.

    Captura de pantalla de Visual Studio Code en la que se muestra cómo expandir el panel de información general del área de trabajo de Quantum.

Agregue una nueva celda en el cuaderno y use la información de la cuenta para crear Workspace objetos y AzureQuantumProvider conectarse al área de trabajo de 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)

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.sim.h1-1e
- rigetti.sim.qvm

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 

Selección de para target ejecutar el programa

Ejecución en el simulador de IonQ

Antes de ejecutarse en hardware real, vamos a probar el circuito en el simulador. Use get_backend para crear un Backend objeto 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, debe transpile en el compatible gateset mediante la transpile función proporcionada por Qiskit:

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

La función transpile devuelve un nuevo objeto de circuito donde las puertas se descompone 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=8)
job_id = job.id()
print("Job id", job_id)
Job id 00000000-0000-0000-0000-000000000000

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

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)

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

Resultado del circuito de Qiskit en el simulador de IonQ

También puede usar la get_memory() función para mostrar datos de captura individuales del trabajo.

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

Nota:

En IonQ targets, si envía un trabajo con un número impar de disparos, los resultados se redondearán al siguiente número par. Por ejemplo, si especifica 9 tomas, los resultados mostrarán los datos de 8 tomas.

Estimación del costo del trabajo

Antes de ejecutar un trabajo en la QPU, debe calcular cuánto cuesta ejecutarse.

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 target"ionq.qpu.aria-1" al get_backend método :

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

Envíe el circuito para que se ejecute en Azure Quantum, obtenga los resultados y ejecútelos plot_histogram para trazar los resultados.

Nota:

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

# 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}

Resultado del circuito de Qiskit en la QPU de IonQ

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

Requisitos previos

Creación de un cuaderno en el área de trabajo

  1. Inicie sesión en Azure Portal y seleccione el área de trabajo que creó en el paso anterior.
  2. En la hoja izquierda, seleccione Cuadernos.
  3. Haga clic en Mis cuadernos y, luego, en Agregar nuevo.
  4. Escriba un nombre para el archivo, por ejemplo Qiskit.ipynb, y haga clic en Crear archivo.

Cuando se abre el cuaderno nuevo, este crea automáticamente el código de la primera celda, en función de la información de la suscripción y del área de trabajo.

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

Nota:

A menos que se indique lo contrario, debe ejecutar cada celda en orden a medida que se cree para evitar problemas de compilación.

Haga clic en el icono triangular "reproducir" situado a la izquierda de la celda para ejecutar el código.

Carga de las importaciones necesarias

En primer lugar, tendrá que importar algunos módulos adicionales.

Haga clic en + Código para agregar una nueva celda y, a continuación, agregue y ejecute el código siguiente:

from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from azure.quantum.qiskit import AzureQuantumProvider

Conexión al servicio Azure Quantum

A continuación, cree un AzureQuantumProvider objeto mediante el Workspace objeto de la celda anterior para conectarse al área de trabajo de Azure Quantum. Agregue una nueva celda con el código siguiente:

provider = AzureQuantumProvider(workspace)

Definición de un circuito simple

En una nueva celda, cree un objeto circuit. Este ejemplo es un generador cuántico de bits aleatorios simple. Agregue el código siguiente para definir y mostrar el 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 

Enumerar todos targets

Ahora puede mostrar todos los back-end o computación targetscuántica que están disponibles en el área de trabajo. Añada una nueva celda y ejecute la siguiente línea:

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

Selección de para target ejecutar el programa

Para comprobar el código antes de ejecutarlo en hardware cuántico real, puede usar el simulador de cuántico de IonQ, ionq.simulator.

Agregue una nueva celda y cree un objeto para representar el simulador targetcuántico de IonQ:

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

Ejecución en el simulador de IonQ

Para ejecutar el circuito en el simulador, agregue el código siguiente. En este ejemplo se usa el run método de target para enviar el trabajo y, a continuación, se supervisa el estado del trabajo.

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

Cuando el trabajo se ejecute correctamente, obtenga los resultados del trabajo y mostrarlos:

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

Dado que este tipo result es un objeto nativo del paquete de Qiskit, puede usar los objetos result.get_counts y plot_histogram de Qiskit y 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': 4, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 4}

Resultado del circuito de Qiskit en el simulador de IonQ

También puede usar la get_memory() función para mostrar datos de captura individuales del trabajo.

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

Nota:

En IonQ targets, si envía un trabajo con un número impar de disparos, los resultados se redondearán al siguiente número par. Por ejemplo, si especifica 9 tomas, los resultados mostrarán los datos de 8 tomas.

Estimación del costo del trabajo

Antes de ejecutar un trabajo en hardware cuántico real o en una unidad de procesamiento cuántico (QPU), debe calcular cuánto cuesta ejecutar.

Para ver la información sobre precios más actual, consulte Precios de IonQ o vaya a su área de trabajo y consulte las opciones de precios en la hoja Proveedores.

Ejecución en la QPU de IonQ

Después de ejecutar el trabajo correctamente en el simulador de IonQ y calcular el costo de QPU, es el momento de ejecutar el circuito en el hardware.

Nota:

El tiempo necesario para ejecutar un circuito en la QPU puede variar en función de los tiempos de cola actuales. Para ver el tiempo medio de cola de un target , seleccione la hoja Proveedores del área de trabajo.

Use el mismo método run y las mismas operaciones que usó anteriormente con el validador de API para enviar y supervisar el trabajo:

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

Cuando finalice el trabajo, obtenga los resultados del trabajo como antes y mostrándolos en un gráfico:

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}

Resultado del circuito de Qiskit en la QPU de IonQ

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

Pasos siguientes