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.27.0
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 — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit": "qiskit", "qiskit_ibm_catalog": "qiskit-ibm-catalog", "qiskit_serverless": "qiskit-serverless"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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 para un backend dado con 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 obtiene un servicio de runtime y lo utiliza para seleccionar tu backend.
Dentro del código que se ejecuta en Qiskit Serverless, crea tu servicio de runtime con get_runtime_service() (importado desde qiskit_serverless) en lugar de instanciar QiskitRuntimeService() directamente.
get_runtime_service() devuelve un wrapper directo (drop-in) alrededor de QiskitRuntimeService que registra cada trabajo y sesión de primitivas de IBM Quantum que lanza, asociándolos al trabajo padre de Qiskit Serverless. Esta vinculación es lo que le permite a la plataforma asociar un trabajo de Serverless con los trabajos y sesiones de QPU que genera, para el seguimiento de estado, los registros (logs) y la contabilidad de uso. Un QiskitRuntimeService simple envía trabajos que la plataforma nunca asocia con tu trabajo de Serverless, por lo que esa vinculación se pierde.
Todos los argumentos son opcionales. Dentro del código fuente del programa, la forma recomendada es get_runtime_service() sin argumentos, que obtiene tus datos de autenticación del entorno. Acepta los mismos argumentos opcionales channel, token, instance y url que 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 IBM Quantum Compute Service 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_serverless import get_runtime_service
service = get_runtime_service()
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 elimina. 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.