Escribe tu primer programa con Qiskit Serverless
Versiones de paquetes
El código de esta página fue desarrollado con los siguientes requisitos. Recomendamos usar estas versiones o versiones más recientes.
qiskit[all]~=1.3.1
qiskit-ibm-runtime~=0.34.0
qiskit-aer~=0.15.1
qiskit-serverless~=0.18.1
qiskit-ibm-catalog~=0.2
qiskit-addon-sqd~=0.8.1
qiskit-addon-utils~=0.1.0
qiskit-addon-mpf~=0.2.0
qiskit-addon-aqc-tensor~=0.1.2
qiskit-addon-obp~=0.1.0
scipy~=1.15.0
pyscf~=2.8.0
Qiskit Serverless está siendo actualizado y sus funciones están cambiando rápidamente. Durante esta fase de desarrollo, consulta las notas de versión y la documentación más reciente en la página de Qiskit Serverless en GitHub.
Este ejemplo demuestra cómo usar las herramientas de qiskit-serverless para crear un programa de transpilación en paralelo, y luego implementar qiskit-ibm-catalog para subir tu programa a IBM Quantum Platform y usarlo como un servicio remoto reutilizable.
Descripción general del flujo de trabajo
- Crea un directorio local y un archivo de programa vacío (
./source_files/transpile_remote.py) - Agrega código a tu programa que, cuando se suba a Qiskit Serverless, transpilará un circuito
- Usa
qiskit-ibm-catalogpara autenticarte en Qiskit Serverless - Sube el programa a Qiskit Serverless
Después de subir tu programa, puedes ejecutarlo para transpilar el circuito siguiendo la guía Ejecuta tu primera carga de trabajo de Qiskit Serverless de forma remota.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-catalog qiskit-ibm-runtime qiskit-serverless
Ejemplo: Transpilación remota con Qiskit Serverless
Este ejemplo te guía por el proceso de crear y completar un archivo de programa que, cuando lo subas a Qiskit Serverless, transpilará un circuit contra un backend dado y un optimization_level objetivo.
Qiskit Serverless requiere organizar los archivos .py de tu carga de trabajo en un directorio dedicado. La siguiente estructura es un ejemplo de buenas prácticas:
serverless_program
├── program_uploader.ipynb
└── source_files
├── transpile_remote.py
└── *.py
Serverless sube el contenido de un directorio específico (en este ejemplo, el directorio source_files) para ejecutarlo de forma remota. Una vez configurados, puedes ajustar transpile_remote.py para obtener entradas y devolver salidas.
Crea el directorio y un archivo de programa vacío
Primero, crea un directorio llamado source_files, luego crea un archivo de programa en ese directorio, de modo que su ruta sea ./source_files/transpile_remote.py. Este es el archivo que subirás a Qiskit Serverless.
Agrega código a tu archivo de programa
Completa tu archivo de programa con el siguiente código y luego guárdalo.
Si estás leyendo las celdas de código localmente en un notebook, verás el comando mágico %%writefile. Ejecutar celdas con este comando mágico las guarda en disco en lugar de ejecutarlas.
# This cell is hidden from users, it creates a new folder
from pathlib import Path
Path("./source_files").mkdir(exist_ok=True)
%%writefile ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this locally in a notebook), running this cell saves to disk rather than executing the code.
from qiskit.transpiler import generate_preset_pass_manager
def transpile_remote(circuit, optimization_level, backend):
"""Transpiles an abstract circuit into an ISA circuit for a given backend."""
pass_manager = generate_preset_pass_manager(
optimization_level=optimization_level,
backend=backend
)
isa_circuit = pass_manager.run(circuit)
return isa_circuit
Agrega código para obtener los argumentos del programa
Ahora agrega el siguiente código a tu archivo de programa, que configura los argumentos del programa.
Tu archivo inicial transpile_remote.py tiene tres entradas: circuits, backend_name y optimization_level. Serverless actualmente solo acepta entradas y salidas serializables. Por esta razón, no puedes pasar backend directamente, así que usa backend_name como cadena de texto en su lugar.
%%writefile --append ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this locally in a notebook), running this cell saves to disk rather than executing the code.
from qiskit_serverless import get_arguments, save_result, distribute_task, get
# Get program arguments
arguments = get_arguments()
circuits = arguments.get("circuits")
backend_name = arguments.get("backend_name")
optimization_level = arguments.get("optimization_level")
Agrega código que llame al backend
Agrega el siguiente código a tu archivo de programa, que llama a tu backend con QiskitRuntimeService.
El siguiente código asume que ya seguiste el proceso para guardar tus credenciales usando QiskitRuntimeService.save_account, y cargará tu cuenta guardada predeterminada a menos que especifiques lo contrario. Consulta Guarda tus credenciales de inicio de sesión e Inicializa tu cuenta de servicio de Qiskit Runtime para más información.
%%writefile --append ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this locally in a notebook), running this cell saves to disk rather than executing the code.
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.backend(backend_name)
Agrega código para transpilar
Por último, agrega el siguiente código a tu archivo de programa. Este código ejecuta transpile_remote() sobre todos los circuits pasados como entrada y devuelve los transpiled_circuits como resultado:
%%writefile --append ./source_files/transpile_remote.py
# If you include the preceding `%%writefile` command (visible only when you read this locally in a notebook), running this cell saves to disk rather than executing the code.
# Each circuit is being transpiled and will populate the array
results = [
transpile_remote(circuit, 1, backend)
for circuit in circuits
]
save_result({
"transpiled_circuits": results
})
Autentícate en Qiskit Serverless
Usa qiskit-ibm-catalog para autenticarte en QiskitServerless con tu clave de API (puedes usar tu clave de API de QiskitRuntimeService, o crear una nueva clave de API en el panel de IBM Quantum Platform).
from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
# Authenticate to the remote cluster and submit the pattern for remote execution
serverless = QiskitServerless()
Ejecuta el código para subir
Ejecuta el siguiente código para subir el programa. Qiskit Serverless comprime el contenido de working_dir (en este caso, source_files) en un archivo tar, que se sube y luego se limpia. El entrypoint identifica el ejecutable principal del programa que Qiskit Serverless debe ejecutar.
transpile_remote_demo = QiskitFunction(
title="transpile_remote_serverless",
entrypoint="transpile_remote.py",
working_dir="./source_files/",
)
serverless.upload(transpile_remote_demo)
QiskitFunction(transpile_remote_serverless)
Verifica la subida
Para verificar si se subió correctamente, usa serverless.list(), como en el siguiente código:
# Get program from serverless.list() that matches the title of the one we uploaded
next(
program
for program in serverless.list()
if program.title == "transpile_remote_serverless"
)
QiskitFunction(transpile_remote_serverless)
# This cell is hidden from users, it checks the program uploaded correctly
assert _.title == "transpile_remote_serverless" # noqa: F821
# This cell is hidden from users, it checks the program executes correctly
from time import sleep
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
transpile_remote_serverless = serverless.load("transpile_remote_serverless")
job = transpile_remote_serverless.run(
circuits=[qc],
backend="ibm_sherbrooke",
optimization_level=1,
)
while True:
sleep(5)
status = job.status()
if status not in ["QUEUED", "INITIALIZING", "RUNNING", "DONE"]:
raise Exception(
f"Unexpected job status: '{status}'\n"
+ "Here are the logs:\n"
+ job.logs()
)
if status == "DONE":
break
Próximos pasos
- Aprende cómo pasar entradas y ejecutar tu programa de forma remota en el tema Ejecuta tu primera carga de trabajo de Qiskit Serverless de forma remota.