Pular para o conteúdo principal
Este projeto está em fase beta. Encontrou um bug? Abra uma issue no GitHub. Tem uma pergunta ou ideia? Pergunte no Discussions — adoraríamos receber seu feedback!
Como está a qualidade da tradução nesta página?

Escreva seu primeiro programa Qiskit Serverless

Package versions

O código desta página foi desenvolvido com os seguintes requisitos. Recomendamos usar estas versões ou mais recentes.

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
dica

O Qiskit Serverless está sendo atualizado e seus recursos estão mudando rapidamente. Durante esta fase de desenvolvimento, encontre as notas de versão e a documentação mais recente na página do Qiskit Serverless no GitHub.

Este exemplo demonstra como usar as ferramentas do qiskit-serverless para criar um programa de transpilação paralela e, em seguida, implementar o qiskit-ibm-catalog para fazer o upload do seu programa na IBM Quantum Platform e usá-lo como um serviço remoto reutilizável.

Visão geral do fluxo de trabalho​

  1. Crie um diretório local e um arquivo de programa vazio (./source_files/transpile_remote.py)

  2. Adicione código ao seu programa que, quando enviado para o Qiskit Serverless, transpilará um circuito

  3. Use o qiskit-ibm-catalog para autenticar no Qiskit Serverless

  4. Faça o upload do programa para o Qiskit Serverless

Após fazer o upload do seu programa, você pode executá-lo para transpilar o circuito seguindo o guia Execute sua primeira carga de trabalho Qiskit Serverless remotamente.

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

Exemplo: Transpilação remota com Qiskit Serverless​

Este exemplo orienta você na criação e no preenchimento de um arquivo de programa que, quando enviado para o Qiskit Serverless, transpilará um circuit para um determinado backend e nível de otimização optimization_level.

dica

O Qiskit Serverless requer que os arquivos .py da sua carga de trabalho sejam organizados em um diretório dedicado. A estrutura a seguir é um exemplo de boa prática:

serverless_program
├── program_uploader.ipynb
└── source_files
├── transpile_remote.py
└── *.py

O Serverless faz o upload do conteúdo de um diretório específico (neste exemplo, o diretório source_files) para execução remota. Após essa configuração, você pode ajustar transpile_remote.py para buscar entradas e retornar saídas.

Criar o diretório e um arquivo de programa vazio​

Primeiro, crie um diretório chamado source_files e, em seguida, crie um arquivo de programa no diretório, de modo que seu caminho seja ./source_files/transpile_remote.py. Este é o arquivo que você enviará para o Qiskit Serverless.

Adicionar código ao seu arquivo de programa​

Preencha seu arquivo de programa com o código a seguir e, em seguida, salve-o.

cuidado

Se você estiver lendo as células de código localmente em um notebook, verá o comando mágico %%writefile. Executar células com esse comando mágico as salva no disco em vez de executá-las.

# 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

Adicionar código para obter argumentos do programa​

Agora adicione o seguinte código ao seu arquivo de programa, que configura os argumentos do programa.

Seu transpile_remote.py inicial tem três entradas: circuits, backend_name e optimization_level. O Serverless atualmente está limitado a aceitar apenas entradas e saídas serializáveis. Por esse motivo, você não pode passar backend diretamente; use backend_name como string.

%%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")

Adicionar código que chama o backend​

Adicione o código a seguir ao seu arquivo de programa, que obtém um serviço de runtime e o utiliza para selecionar seu backend.

Use get_runtime_service em programas do Qiskit Serverless

Dentro de código que é executado no Qiskit Serverless, crie seu serviço de runtime com get_runtime_service() (importado de qiskit_serverless) em vez de instanciar QiskitRuntimeService() diretamente.

get_runtime_service() retorna um wrapper substituto direto para QiskitRuntimeService que registra cada job e sessão de primitiva do IBM Quantum que ele inicia, vinculando-os ao job pai do Qiskit Serverless. Essa vinculação é o que permite que a plataforma associe um job do Serverless aos jobs e sessões de QPU que ele gera, para rastreamento de status, logs e uso e contabilização. Um QiskitRuntimeService puro envia jobs que a plataforma nunca associa ao seu job do Serverless, portanto essa vinculação é perdida.

Todos os argumentos são opcionais. Dentro do código-fonte do programa, a forma recomendada é get_runtime_service() sem argumentos, que obtém seus dados de autenticação a partir do ambiente. Ele aceita os mesmos argumentos opcionais channel, token, instance e url que QiskitRuntimeService.

O código a seguir pressupõe que você já seguiu o processo para salvar suas credenciais usando QiskitRuntimeService.save_account e carregará sua conta padrão salva, a menos que você especifique de outra forma. Consulte Salvar suas credenciais de login e Inicializar sua conta IBM Quantum Compute Service para mais informações.

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

Adicionar código para transpilar​

Por fim, adicione o seguinte código ao seu arquivo de programa. Este código executa transpile_remote() em todos os circuits passados e retorna os 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
})

Autenticar no Qiskit Serverless​

Use qiskit-ibm-catalog para autenticar no QiskitServerless com sua chave de API (você pode usar sua chave de API do QiskitRuntimeService ou criar uma nova chave de API no painel da IBM Quantum Platform).

from qiskit_ibm_catalog import QiskitServerless, QiskitFunction

# Authenticate to the remote cluster and submit the pattern for remote execution
serverless = QiskitServerless()

Executar o código para fazer o upload​

Execute o código a seguir para fazer o upload do programa. O Qiskit Serverless comprime o conteúdo de working_dir (neste caso, source_files) em um arquivo tar, que é enviado e removido após o upload. O entrypoint identifica o executável principal do programa para que o Qiskit Serverless execute.

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)

Verificar o upload​

Para verificar se o upload foi bem-sucedido, use serverless.list(), como no código a seguir:

# 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 passos​

Recomendações