Definice vstupů a výstupů
Spravovaný workflow funguje jako funkce Pythonu, která běží na vzdáleném výpočetním prostředí. Porovnej lokální funkci se stejným kódem jako workflow:
Local Python
def my_workflow(circuits, shots=4096):
...
return {"counts": counts}
result = my_workflow(circuits=circuits, shots=1024)
Ve spravovaném workflow je run() volání, get_arguments() poskytuje workflow jeho parametry a save_result() je jeho příkaz return. Protože workflow běží jako samostatný job na vzdáleném výpočetním prostředí, liší se od volání lokální funkce ve třech ohledech:
-
Klient kóduje argumenty a výsledky. Každá hodnota musí být taková, kterou klient dokáže zakódovat, a některé typy se mění. Viz Čtení argumentů ve workflow.
-
Volání nečeká.
run()okamžitě vrátí job a výsledek přečteš později pomocíjob.result(). Viz Uložení výsledků. -
Nic volání nekontroluje. Funkce Pythonu odmítne neznámý pojmenovaný argument, ale workflow ho ignoruje, pokud nepřipojíš schéma. Viz Osvědčený postup: ověřuj argumenty pomocí schématu.
Čtení argumentů ve workflow
Předej vstupy do workflow z lokálního notebooku:
run_workflow_remotely.ipynb
job = my_workflow.run(circuits=circuits, shots=1024)
Aby to fungovalo, uprav kód workflow tak, aby načítal argumenty pomocí get_arguments(), které vrací slovník, jehož klíče jsou názvy argumentů:
source_files/my_workflow.py
from qiskit_serverless import get_arguments
arguments = get_arguments()
circuits = arguments["circuits"]
shots = arguments.get("shots", 4096)
Slovník obsahuje pouze argumenty, které běh předal, proto pro volitelné argumenty používej arguments.get() s výchozí hodnotou. Můžeš použít libovolný název argumentu kromě chráněných klíčových slov config a function_size, protože run() tato klíčová slova používá přímo. run() také odmítá compute_profile. Chceš-li vybrat výpočetní zdroje, předej function_size.
Chceš-li zjistit velikost, ve které job běží, zavolej get_function_size() v kódu workflow:
source_files/my_workflow.py
from qiskit_serverless import get_function_size
size = get_function_size() # For example, "M"
Pokud běh nepředá function_size, get_function_size() vrátí výchozí velikost workflow. Viz Výběr velikosti pro každý běh.
Podporované typy argumentů
Každá hodnota musí být serializovatelná do JSON, nebo to musí být objekt, který klient dokáže zakódovat, například obvod Qiskit nebo pole NumPy. Protože klient každý argument před odesláním jobu zakóduje a get_arguments() ho uvnitř workflow dekóduje, workflow obdrží původní objekt Pythonu.
Klient posílá int, float, str, bool, None a seznamy či slovníky těchto typů beze změny. Jiné objekty, například QuantumCircuit, numpy.ndarray nebo číslo typu complex, zakóduje jako slovník se značkou __type__ a hodnotou __value__. Tuto podobu potřebuješ, když píšeš schéma argumentů.
Protože JSON pro některé typy nemá ekvivalent, tyto typy se při kódování mění. N-tice dorazí jako seznamy, klíče slovníků dorazí jako řetězce a celá čísla NumPy, například np.int64, dorazí jako int. Pokud klient hodnotu nedokáže zakódovat, například bytes nebo np.float32, run() vyvolá TypeError a job nevytvoří.
Některé objekty nelze předat jako argumenty. Například místo objektu Backend předej název backendu jako řetězec a backend vytvoř uvnitř workflow. Viz Spouštění kvantových jobů z workflow.
Limity velikosti
Argumenty jednoho běhu mohou mít po zakódování až 32 MB. Například jeden 100qubitový obvod s hloubkou 100 se zakóduje na přibližně 39 KB, takže jeden běh může přijmout dávku asi 800 takových obvodů. U větších vstupů nahraj soubor a předej jeho název jako argument.
Uložení výsledků
Použij save_result() na konci workflow, abys vrátil výsledek do svého notebooku. Výsledek přečteš v notebooku pomocí job.result():
run_workflow_remotely.ipynb
result = job.result()
Aby to fungovalo, zavolej save_result() v kódu workflow:
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() kóduje výsledek stejným způsobem, jakým klient kóduje argumenty, a job.result() ho dekóduje. Výsledek proto může obsahovat podporované typy argumentů, například obvody, pole NumPy a výsledek jobu primitiv, se stejnými změnami typů.
-
Zkontroluj návratovou hodnotu. Pokud
save_result()hodnotu nedokáže zakódovat, zaznamená varování a místo vyvolání chyby vrátíFalse. Bez kontroly se může job ukončit se stavemDONEa bez výsledku. -
Uloží se jen poslední
save_result(). Každé volání nahradí uložený výsledek. Chceš-li vrátit více hodnot, ulož je do jednoho slovníku nebo je zapiš do logů. -
Prázdný slovník znamená žádný výsledek. Pokud workflow nikdy nezavolá
save_result(),job.result()vrátí{}.
Chceš-li vrátit soubory, například velká pole nebo grafy, ulož je do souborového úložiště a ve výsledku vrať jejich názvy.
Osvědčený postup: ověřuj argumenty pomocí schématu
Jako osvědčený postup připoj JSON Schema ke každému workflow, které přijímá argumenty. Schéma popisuje argumenty, které workflow přijímá, a workflow před vytvořením jobu zkontroluje argumenty každého běhu podle něj. Pokud argumenty neodpovídají, run() okamžitě selže s chybou, která pojmenuje chybné pole, a workflow job nevytvoří. Bez schématu se chybné argumenty dostanou do workflow až po spuštění jobu a workflow chybně napsaný název argumentu ignoruje.
Schéma nastav pomocí arguments_schema při nahrávání workflow. Předej slovník, nikoli řetězec 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,
)
)
Při psaní schématu mysli na následující body:
-
Popiš zakódovanou podobu objektů Qiskit a NumPy. Schéma kontroluje argumenty v podobě, v jaké je klient posílá, takže obvod je objekt jako
{"__type__": "QuantumCircuit", "__value__": "<base64-encoded QPY>"}, nikoli řetězec ani pole. Zkontroluj značku__type__a s__value__zacházej jako s neprůhledným řetězcem. Schéma, které popisuje obvod jako řetězec, odmítne každý platný běh. -
Nastav
"additionalProperties": false. Bez tohoto nastavení workflow ignoruje chybně napsaný název argumentu, napříkladshotz, bez varování a běží s jeho výchozí hodnotou. Dříve, než toto nastavení zapneš, deklaruj každý argument, který workflow přijímá. -
Označ argumenty jako povinné. Přidej do
requiredkaždý argument, který workflow čte bez výchozí hodnoty.
Pokud argumenty neodpovídají schématu, chybová zpráva pojmenuje pravidlo a umístění chybné hodnoty:
'type' validation failed, schema requires 'integer': rejected value '4096'
path: ['shots']
Schéma kontroluje typ, tvar a rozsah každého argumentu. Schéma nedokáže zkontrolovat, zda dva platné argumenty nejsou v konfliktu, ani zda se obvod hodí pro backend. Tyto kontroly ponech v kódu workflow.
Aktualizace nebo odstranění schématu
-
Chceš-li schéma nahradit, nastav nový
arguments_schemaa nahraj workflow znovu. -
Chceš-li schéma odstranit, nahraj workflow s
arguments_schema={}. -
Pokud nahraješ workflow bez
arguments_schema, workflow si ponechá uložené schéma.
Chceš-li zobrazit schéma, které platí, přečti my_workflow.arguments_schema. Hodnota None znamená, že workflow nemá žádné schéma.
Zkontroluj argumenty před během
Zavolej validate_arguments(), abys zkontroloval sadu argumentů podle schématu bez spuštění jobu:
run_workflow_remotely.ipynb
my_workflow.validate_arguments({"circuits": [circuit], "shots": 1024})
# {'valid': True}
Pokud argumenty nejsou platné, validate_arguments() vyvolá QiskitServerlessException se stejnou zprávou, jakou run() vrací pro tyto argumenty. Pokud workflow nemá schéma, jsou platné jakékoli argumenty. Platný výsledek nezaručuje, že run() uspěje, protože run() kontroluje i další limity, například počet aktivních jobů.
Pravidla schématu
Spravovaný workflow odmítne nahrání, pokud schéma porušuje některé z následujících pravidel:
-
Schéma může mít až 64 KiB, až 64 úrovní vnoření a až 200 podschémat.
-
Odkazy musí ukazovat dovnitř téhož schématu, například
#/$defs/circuit, a každý odkaz musí být možné rozřešit. Odkazy na adresy URL nebo soubory nejsou povoleny. -
Schéma musí být objekt nebo boolean.
Vyhni se také následujícím problémům, které nahrání nezachytí:
-
Vnořené kvantifikátory v
pattern. Vzor jako^(a+)+$může vyhodnocování trvat velmi dlouho. Workflow ukončí validaci po překročení limitu času CPU a běh odmítne. Piš vzory bez kvantifikátoru kolem skupiny, která už nějaký obsahuje, například^ibm_[a-z0-9_]{1,40}$. -
falsejako schéma. Schémafalseodmítne každý běh. Chceš-li validaci odstranit, použij{}.
Řešení potíží se schématem
| Problém | Příčina |
|---|---|
| Každý běh je odmítnut kvůli argumentu s obvodem. | Schéma popisuje obvod jako řetězec nebo pole. Popiš ho jako objekt se značkou __type__. |
| Platné běhy jsou odmítány. | additionalProperties je false a schéma nedeklaruje argument, který běh předává. Chybová path pojmenuje argument. |
| Neplatné běhy nejsou odmítány. | Workflow nemá žádné schéma. Zkontroluj my_workflow.arguments_schema. |
| Žádný běh se nekontroluje, ačkoli jsi schéma nastavil. | Schéma bylo předáno jako řetězec JSON. Předej slovník. |
Nahrání selže s chybou 400. | Schéma porušuje jedno z pravidel schématu. |
| Chyba říká, že validace zabrala příliš mnoho času CPU. | pattern obsahuje vnořené kvantifikátory. Přepiš vzor. |