Sari la conținutul principal
Acest proiect este în versiune beta. Ai găsit o eroare? Deschide un issue pe GitHub. Ai o întrebare sau o idee? Întreabă în Discussions — ne-ar plăcea să aflăm părerea ta!
Cum este calitatea traducerii pe această pagină?

Definește intrările și ieșirile

Un workflow gestionat funcționează ca o funcție Python care rulează pe resurse de calcul la distanță. Compară o funcție locală cu același cod ca workflow:

Local Python

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

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

Într-un workflow gestionat, run() este apelul, get_arguments() oferă workflow-ului parametrii săi, iar save_result() este instrucțiunea sa return. Deoarece workflow-ul rulează ca un job separat pe resurse de calcul la distanță, diferă de un apel local de funcție în trei moduri:

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().

Citește argumentele în workflow-ul tău​

Transmite intrări workflow-ului tău din notebookul tău local:

run_workflow_remotely.ipynb

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

Pentru a activa acest lucru, modifică codul workflow-ului ca să preia argumentele cu get_arguments(), care returnează un dicționar ale cărui chei sunt numele argumentelor:

source_files/my_workflow.py

from qiskit_serverless import get_arguments

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

Dicționarul conține doar argumentele transmise de rulare, deci folosește arguments.get() cu o valoare implicită pentru argumentele opționale. Poți folosi orice nume de argument, cu excepția cuvintelor cheie protejate config și function_size, deoarece run() folosește direct aceste cuvinte cheie. run() respinge și compute_profile. Pentru a alege resursele de calcul, transmite function_size.

Pentru a citi dimensiunea la care rulează jobul, apelează get_function_size() în codul workflow-ului tău:

source_files/my_workflow.py

from qiskit_serverless import get_function_size

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

Dacă rularea nu transmite function_size, get_function_size() returnează dimensiunea implicită a workflow-ului. Vezi Alege o dimensiune pentru fiecare rulare.

Tipuri de argumente suportate​

Fiecare valoare trebuie să fie serializabilă JSON sau un obiect pe care clientul îl poate codifica, precum un circuit Qiskit sau un tablou NumPy. Deoarece clientul codifică fiecare argument înainte de a trimite jobul, iar get_arguments() îl decodifică în interiorul workflow-ului, workflow-ul primește obiectul Python original.

Clientul trimite int, float, str, bool, None și liste sau dicționare ale acestora neschimbate. Codifică alte obiecte, precum un QuantumCircuit, un numpy.ndarray sau un număr complex, ca dicționar cu o etichetă __type__ și o __value__. Ai nevoie de această formă când scrii o schemă de argumente.

Deoarece JSON nu are echivalent pentru unele tipuri, acestea se schimbă în timpul codificării. Tuplurile ajung ca liste, cheile dicționarelor ajung ca șiruri, iar întregii NumPy precum np.int64 ajung ca int. Dacă clientul nu poate codifica o valoare, precum bytes sau np.float32, run() ridică o TypeError și nu creează un job.

Unele obiecte nu pot fi transmise ca argumente. De exemplu, transmite numele unui backend ca șir, nu un obiect Backend, și creează backendul în interiorul workflow-ului. Vezi Rulează joburi cuantice dintr-un workflow.

Limite de dimensiune​

Argumentele unei rulări pot avea până la 32 MB după codificare. De exemplu, un circuit de 100 de qubiți cu adâncimea 100 se codifică la aproximativ 39 KB, deci o singură rulare poate primi un batch de aproximativ 800 de astfel de circuite. Pentru intrări mai mari, încarcă un fișier și transmite numele lui ca argument.

Salvează rezultatele​

Folosește save_result() la sfârșitul workflow-ului pentru a returna un rezultat în notebookul tău. Citește rezultatul în notebook cu job.result():

run_workflow_remotely.ipynb

result = job.result()

Pentru a activa acest lucru, apelează save_result() în codul workflow-ului tău:

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() codifică rezultatul în același mod în care clientul codifică argumentele, iar job.result() îl decodifică. Un rezultat poate deci conține tipurile de argumente suportate, precum circuite, tablouri NumPy și rezultatul unui job primitiv, cu aceleași schimbări de tip.

  • Verifică valoarea returnată. Dacă save_result() nu poate codifica valoarea, înregistrează un avertisment și returnează False în loc să ridice o eroare. Fără verificare, jobul se poate încheia cu statusul DONE și fără rezultat.

  • Se stochează doar ultimul save_result(). Fiecare apel înlocuiește rezultatul salvat. Pentru a returna mai multe valori, salvează-le într-un singur dicționar sau scrie-le în loguri.

  • Un dicționar gol înseamnă lipsa rezultatului. Dacă workflow-ul nu apelează niciodată save_result(), job.result() returnează {}.

Pentru a returna fișiere, precum tablouri mari sau grafice, salvează-le în stocarea de fișiere și returnează numele lor în rezultat.

Bună practică: validează argumentele cu o schemă​

Ca bună practică, atașează o schemă JSON fiecărui workflow care primește argumente. Schema descrie argumentele pe care le acceptă workflow-ul, iar workflow-ul verifică argumentele fiecărei rulări în raport cu ea înainte de a crea jobul. Dacă argumentele nu se potrivesc, run() eșuează imediat cu o eroare care numește câmpul greșit, iar workflow-ul nu creează un job. Fără schemă, argumentele greșite ajung la workflow după pornirea jobului, iar workflow-ul ignoră un nume de argument scris greșit.

Setează schema cu arguments_schema când încarci workflow-ul. Transmite un dicționar, nu un șir 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,
)
)

Ține cont de următoarele puncte când scrii o schemă:

  • Descrie forma codificată a obiectelor Qiskit și NumPy. Schema verifică argumentele așa cum le trimite clientul, deci un circuit este un obiect precum {"__type__": "QuantumCircuit", "__value__": "<base64-encoded QPY>"}, nu un șir sau un tablou. Verifică eticheta __type__ și tratează __value__ ca un șir opac. O schemă care descrie un circuit ca șir respinge fiecare rulare validă.

  • Setează "additionalProperties": false. Fără această setare, workflow-ul ignoră fără avertisment un nume de argument scris greșit, precum shotz, și rulează cu valoarea implicită. Declară fiecare argument pe care îl acceptă workflow-ul înainte de a activa această setare.

  • Marchează argumentele ca obligatorii. Adaugă în required fiecare argument pe care workflow-ul îl citește fără valoare implicită.

Dacă argumentele nu se potrivesc cu schema, mesajul de eroare numește regula și locația valorii greșite:

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

O schemă verifică tipul, forma și intervalul fiecărui argument. O schemă nu poate verifica dacă două argumente valide intră în conflict sau dacă un circuit se potrivește unui backend. Păstrează aceste verificări în codul workflow-ului.

Actualizează sau elimină o schemă​

  • Pentru a înlocui schema, setează un nou arguments_schema și încarcă din nou workflow-ul.

  • Pentru a elimina schema, încarcă workflow-ul cu arguments_schema={}.

  • Dacă încarci workflow-ul fără arguments_schema, workflow-ul păstrează schema stocată.

Pentru a vedea schema aflată în vigoare, citește my_workflow.arguments_schema. O valoare None înseamnă că workflow-ul nu are schemă.

Verifică argumentele înainte de rulare​

Apelează validate_arguments() pentru a verifica un set de argumente în raport cu schema, fără a porni un job:

run_workflow_remotely.ipynb

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

Dacă argumentele nu sunt valide, validate_arguments() ridică o QiskitServerlessException cu același mesaj pe care run() îl returnează pentru acele argumente. Dacă workflow-ul nu are schemă, orice argumente sunt valide. Un rezultat valid nu garantează că run() reușește, deoarece run() verifică și alte limite, precum numărul de joburi active.

Reguli pentru schemă​

Un workflow gestionat respinge încărcarea dacă schema încalcă oricare dintre următoarele reguli:

  • Schema poate avea până la 64 KiB, cu până la 64 de niveluri de imbricare și până la 200 de subscheme.

  • Referințele trebuie să indice în interiorul aceleiași scheme, precum #/$defs/circuit, iar fiecare referință trebuie să se rezolve. Referințele la URL-uri sau fișiere nu sunt permise.

  • Schema trebuie să fie un obiect sau un boolean.

Evită și următoarele probleme, pe care încărcarea nu le detectează:

  • Cuantificatori imbricați în pattern. Un tipar precum ^(a+)+$ poate dura foarte mult la evaluare. Un workflow oprește validarea după o limită de timp CPU și respinge rularea. Scrie tipare fără cuantificator în jurul unui grup care conține deja unul, precum ^ibm_[a-z0-9_]{1,40}$.

  • false ca schemă. Schema false respinge fiecare rulare. Pentru a elimina validarea, folosește {}.

Depanează o schemă​

ProblemăCauză
Fiecare rulare este respinsă pe un argument de tip circuit.Schema descrie circuitul ca șir sau tablou. Descrie-l ca obiect cu o etichetă __type__.
Rulări valide sunt respinse.additionalProperties este false, iar schema nu declară un argument pe care îl transmite rularea. path din eroare numește argumentul.
Rulări invalide nu sunt respinse.Workflow-ul nu are schemă. Verifică my_workflow.arguments_schema.
Nicio rulare nu este verificată, deși ai setat o schemă.Schema a fost transmisă ca șir JSON. Transmite un dicționar.
Încărcarea eșuează cu o eroare 400.Schema încalcă una dintre regulile pentru schemă.
Eroarea spune că validarea a durat prea mult timp CPU.Un pattern are cuantificatori imbricați. Rescrie tiparul.