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?

Defina entradas e saídas

Um fluxo de trabalho gerenciado funciona como uma função Python executada em computação remota. Compare uma função local com o mesmo código como um fluxo de trabalho:

Local Python

def my_workflow(circuits, shots=4096):
...
return {"counts": counts}

result = my_workflow(circuits=circuits, shots=1024)

Em um fluxo de trabalho gerenciado, run() é a chamada, get_arguments() fornece ao fluxo de trabalho seus parâmetros e save_result() é a instrução return dele. Como o fluxo de trabalho é executado como um job separado em computação remota, ele difere de uma chamada de função local em três aspectos:

Your local notebook, run_workflow_remotely.ipynb, calls run(args). A workflow runs an optional schema check, then creates the managed workflow job, source_files/my_workflow.py. The job reads its arguments with get_arguments(), runs your code, such as mapping, transpiling circuits, running primitives, and post-processing, and returns a result with save_result(). A workflow stores the result, and your notebook reads it with job.result().

Leia argumentos no seu fluxo de trabalho​

Passe entradas para o seu fluxo de trabalho a partir do seu notebook local:

run_workflow_remotely.ipynb

job = my_workflow.run(circuits=circuits, shots=1024)

Para habilitar isso, edite o código do seu fluxo de trabalho para obter os argumentos com get_arguments(), que retorna um dicionário cujas chaves são os nomes dos argumentos:

source_files/my_workflow.py

from qiskit_serverless import get_arguments

arguments = get_arguments()
circuits = arguments["circuits"]
shots = arguments.get("shots", 4096)

O dicionário contém apenas os argumentos que a execução passou, então use arguments.get() com um valor padrão para argumentos opcionais. Você pode usar qualquer nome de argumento, exceto as palavras-chave protegidas config e function_size, porque run() usa essas palavras-chave diretamente. run() também rejeita compute_profile. Para escolher recursos de computação, passe function_size.

Para ler o tamanho com que o job é executado, chame get_function_size() no código do seu fluxo de trabalho:

source_files/my_workflow.py

from qiskit_serverless import get_function_size

size = get_function_size() # For example, "M"

Se a execução não passar function_size, get_function_size() retorna o tamanho padrão do fluxo de trabalho. Consulte Escolha um tamanho para cada execução.

Tipos de argumento compatíveis​

Cada valor precisa ser serializável em JSON ou um objeto que o cliente consiga codificar, como um circuito do Qiskit ou um array NumPy. Como o cliente codifica cada argumento antes de enviar o job e get_arguments() o decodifica dentro do fluxo de trabalho, o fluxo de trabalho recebe o objeto Python original.

O cliente envia int, float, str, bool, None e listas ou dicionários desses tipos sem alterações. Ele codifica outros objetos, como um QuantumCircuit, um numpy.ndarray ou um número complex, como um dicionário com uma tag __type__ e um __value__. Você precisa dessa forma quando escrever um esquema de argumentos.

Como o JSON não tem equivalente para alguns tipos, esses tipos mudam durante a codificação. Tuplas chegam como listas, chaves de dicionário chegam como strings e inteiros NumPy, como np.int64, chegam como int. Se o cliente não conseguir codificar um valor, como bytes ou np.float32, run() gera um TypeError e não cria um job.

Alguns objetos não podem ser passados como argumentos. Por exemplo, passe o nome de um Backend como string em vez de um objeto Backend, e crie o Backend dentro do fluxo de trabalho. Consulte Execute jobs quânticos a partir de um fluxo de trabalho.

Limites de tamanho​

Os argumentos de uma execução podem ter até 32 MB após a codificação. Por exemplo, um circuito de 100 Qubits com profundidade 100 é codificado em cerca de 39 KB, então uma única execução pode receber um lote de cerca de 800 circuitos desse tipo. Para entradas maiores, envie um arquivo e passe o nome dele como argumento.

Salve resultados​

Use save_result() no final do seu fluxo de trabalho para retornar um resultado ao seu notebook. Leia o resultado no seu notebook com job.result():

run_workflow_remotely.ipynb

result = job.result()

Para habilitar isso, chame save_result() no código do seu fluxo de trabalho:

source_files/my_workflow.py

from qiskit_serverless import save_result

if not save_result({"counts": counts, "circuit": isa_circuit}):
raise ValueError("The result could not be encoded.")

save_result() codifica o resultado da mesma forma que o cliente codifica os argumentos, e job.result() o decodifica. Portanto, um resultado pode conter os tipos de argumento compatíveis, como circuitos, arrays NumPy e o resultado de um job de primitiva, com as mesmas mudanças de tipo.

  • Verifique o valor de retorno. Se save_result() não conseguir codificar o valor, ele registra um aviso e retorna False em vez de gerar um erro. Sem uma verificação, o job pode terminar com o status DONE e sem resultado.

  • Apenas o último save_result() é armazenado. Cada chamada substitui o resultado salvo. Para retornar vários valores, salve-os em um único dicionário ou grave-os nos logs.

  • Um dicionário vazio significa nenhum resultado. Se o fluxo de trabalho nunca chamar save_result(), job.result() retorna {}.

Para retornar arquivos, como arrays grandes ou gráficos, salve-os no armazenamento de arquivos e retorne os nomes deles no resultado.

Prática recomendada: valide argumentos com um esquema​

Como prática recomendada, anexe um JSON Schema a todo fluxo de trabalho que recebe argumentos. O esquema descreve os argumentos que o fluxo de trabalho aceita, e o fluxo de trabalho verifica os argumentos de cada execução em relação a ele antes de criar o job. Se os argumentos não corresponderem, run() falha imediatamente com um erro que nomeia o campo incorreto, e o fluxo de trabalho não cria um job. Sem um esquema, argumentos incorretos chegam ao fluxo de trabalho depois que o job começa, e o fluxo de trabalho ignora um nome de argumento digitado errado.

Defina o esquema com arguments_schema ao enviar o fluxo de trabalho. Passe um dicionário, não uma string JSON:

run_workflow_remotely.ipynb

from qiskit_ibm_catalog import ManagedWorkflow, ManagedWorkflowClient

arguments_schema = {
"type": "object",
"additionalProperties": False,
"required": ["circuits"],
"properties": {
"circuits": {
"type": "array",
"minItems": 1,
"items": {"$ref": "#/$defs/circuit"},
},
"shots": {"type": "integer", "minimum": 1, "maximum": 100000},
"backend_name": {"type": "string", "minLength": 1},
},
"$defs": {
"circuit": {
"type": "object",
"required": ["__type__", "__value__"],
"properties": {
"__type__": {"const": "QuantumCircuit"},
"__value__": {"type": "string"},
},
}
},
}

client = ManagedWorkflowClient()

my_workflow = client.upload(
ManagedWorkflow(
title="my-workflow",
entrypoint="my_workflow.py",
working_dir="./source_files/",
arguments_schema=arguments_schema,
)
)

Tenha em mente os seguintes pontos ao escrever um esquema:

  • Descreva a forma codificada de objetos Qiskit e NumPy. O esquema verifica os argumentos como o cliente os envia, então um circuito é um objeto como {"__type__": "QuantumCircuit", "__value__": "<base64-encoded QPY>"}, e não uma string ou um array. Verifique a tag __type__ e trate __value__ como uma string opaca. Um esquema que descreve um circuito como uma string rejeita toda execução válida.

  • Defina "additionalProperties": false. Sem essa configuração, o fluxo de trabalho ignora, sem aviso, um nome de argumento digitado errado, como shotz, e é executado com o valor padrão. Declare todos os argumentos que o fluxo de trabalho aceita antes de habilitar essa configuração.

  • Marque os argumentos como obrigatórios. Adicione a required cada argumento que o fluxo de trabalho lê sem um valor padrão.

Se os argumentos não corresponderem ao esquema, a mensagem de erro nomeia a regra e o local do valor incorreto:

'type' validation failed, schema requires 'integer': rejected value '4096'
path: ['shots']

Um esquema verifica o tipo, o formato e o intervalo de cada argumento. Um esquema não consegue verificar se dois argumentos válidos entram em conflito, nem se um circuito cabe em um Backend. Mantenha essas verificações no código do fluxo de trabalho.

Atualize ou remova um esquema​

  • Para substituir o esquema, defina um novo arguments_schema e envie o fluxo de trabalho novamente.

  • Para remover o esquema, envie o fluxo de trabalho com arguments_schema={}.

  • Se você enviar o fluxo de trabalho sem arguments_schema, o fluxo de trabalho mantém o esquema armazenado.

Para ver o esquema em vigor, leia my_workflow.arguments_schema. Um valor None significa que o fluxo de trabalho não tem esquema.

Verifique os argumentos antes de executar​

Chame validate_arguments() para verificar um conjunto de argumentos em relação ao esquema sem iniciar um job:

run_workflow_remotely.ipynb

my_workflow.validate_arguments({"circuits": [circuit], "shots": 1024})
# {'valid': True}

Se os argumentos não forem válidos, validate_arguments() gera uma QiskitServerlessException com a mesma mensagem que run() retorna para esses argumentos. Se o fluxo de trabalho não tiver esquema, quaisquer argumentos são válidos. Um resultado válido não garante que run() seja bem-sucedido, porque run() também verifica outros limites, como o número de jobs ativos.

Regras de esquema​

Um fluxo de trabalho gerenciado rejeita o envio se o esquema violar qualquer uma das seguintes regras:

  • O esquema pode ter até 64 KiB, com até 64 níveis de aninhamento e até 200 subesquemas.

  • As referências precisam apontar para dentro do mesmo esquema, como #/$defs/circuit, e toda referência precisa ser resolvida. Referências a URLs ou arquivos não são permitidas.

  • O esquema precisa ser um objeto ou um booleano.

Evite também os seguintes problemas, que o envio não detecta:

  • Quantificadores aninhados em pattern. Um padrão como ^(a+)+$ pode levar muito tempo para ser avaliado. Um fluxo de trabalho interrompe a validação após um limite de tempo de CPU e rejeita a execução. Escreva padrões sem um quantificador em torno de um grupo que já contém um, como ^ibm_[a-z0-9_]{1,40}$.

  • false como esquema. O esquema false rejeita toda execução. Para remover a validação, use {}.

Solucione problemas de um esquema​

ProblemaCausa
Toda execução é rejeitada em um argumento de circuito.O esquema descreve o circuito como uma string ou um array. Descreva-o como um objeto com uma tag __type__.
Execuções válidas são rejeitadas.additionalProperties é false, e o esquema não declara um argumento que a execução passa. O path do erro nomeia o argumento.
Execuções inválidas não são rejeitadas.O fluxo de trabalho não tem esquema. Verifique my_workflow.arguments_schema.
Nenhuma execução é verificada, embora você tenha definido um esquema.O esquema foi passado como uma string JSON. Passe um dicionário.
O envio falha com um erro 400.O esquema viola uma das regras de esquema.
O erro diz que a validação levou tempo de CPU demais.Um pattern tem quantificadores aninhados. Reescreva o padrão.