Zdefiniuj dane wejściowe i wyjściowe
Zarządzany przepływ pracy działa jak funkcja Pythona uruchamiana na zdalnych zasobach obliczeniowych. Porównaj funkcję lokalną z tym samym kodem jako przepływem pracy:
Local Python
def my_workflow(circuits, shots=4096):
...
return {"counts": counts}
result = my_workflow(circuits=circuits, shots=1024)
W zarządzanym przepływie pracy run() jest wywołaniem, get_arguments() dostarcza przepływowi pracy jego parametry, a save_result() pełni rolę jego instrukcji return. Ponieważ przepływ pracy działa jako osobne zadanie na zdalnych zasobach obliczeniowych, różni się od lokalnego wywołania funkcji pod trzema względami:
-
Klient koduje argumenty i wyniki. Każda wartość musi być taka, którą klient potrafi zakodować, a niektóre typy ulegają zmianie. Zobacz Odczytaj argumenty w przepływie pracy.
-
Wywołanie nie czeka.
run()natychmiast zwraca zadanie, a wynik odczytasz później za pomocąjob.result(). Zobacz Zapisz wyniki. -
Nic nie sprawdza wywołania. Funkcja Pythona odrzuca nieznany argument nazwany, ale przepływ pracy go ignoruje, chyba że dołączysz schemat. Zobacz Najlepsza praktyka: weryfikuj argumenty za pomocą schematu.
Odczytaj argumenty w przepływie pracy
Przekaż dane wejściowe do przepływu pracy z lokalnego notatnika:
run_workflow_remotely.ipynb
job = my_workflow.run(circuits=circuits, shots=1024)
Aby to umożliwić, zmodyfikuj kod przepływu pracy tak, aby pobierał argumenty za pomocą get_arguments(), które zwraca słownik, w którym kluczami są nazwy argumentów:
source_files/my_workflow.py
from qiskit_serverless import get_arguments
arguments = get_arguments()
circuits = arguments["circuits"]
shots = arguments.get("shots", 4096)
Słownik zawiera tylko argumenty przekazane w danym uruchomieniu, więc dla argumentów opcjonalnych używaj arguments.get() z wartością domyślną. Możesz użyć dowolnej nazwy argumentu poza zastrzeżonymi słowami kluczowymi config i function_size, ponieważ run() używa ich bezpośrednio. run() odrzuca też compute_profile. Aby wybrać zasoby obliczeniowe, przekaż function_size.
Aby odczytać rozmiar, w jakim działa zadanie, wywołaj get_function_size() w kodzie przepływu pracy:
source_files/my_workflow.py
from qiskit_serverless import get_function_size
size = get_function_size() # For example, "M"
Jeśli uruchomienie nie przekazuje function_size, get_function_size() zwraca domyślny rozmiar przepływu pracy. Zobacz Wybierz rozmiar dla każdego uruchomienia.
Obsługiwane typy argumentów
Każda wartość musi być serializowalna do JSON lub być obiektem, który klient potrafi zakodować, takim jak obwód Qiskit lub tablica NumPy. Ponieważ klient koduje każdy argument przed wysłaniem zadania, a get_arguments() dekoduje go wewnątrz przepływu pracy, przepływ pracy otrzymuje oryginalny obiekt Pythona.
Klient wysyła int, float, str, bool, None oraz listy lub słowniki tych typów bez zmian. Inne obiekty, takie jak QuantumCircuit, numpy.ndarray czy liczba complex, koduje jako słownik ze znacznikiem __type__ i polem __value__. Ta postać jest potrzebna, gdy piszesz schemat argumentów.
Ponieważ JSON nie ma odpowiedników dla niektórych typów, typy te zmieniają się podczas kodowania. Krotki docierają jako listy, klucze słowników jako ciągi znaków, a liczby całkowite NumPy, takie jak np.int64, jako int. Jeśli klient nie potrafi zakodować wartości, takiej jak bytes lub np.float32, run() zgłasza TypeError i nie tworzy zadania.
Niektórych obiektów nie można przekazać jako argumentów. Na przykład przekaż nazwę backendu jako ciąg znaków zamiast obiektu Backend i utwórz backend wewnątrz przepływu pracy. Zobacz Uruchamiaj zadania kwantowe z przepływu pracy.
Limity rozmiaru
Argumenty jednego uruchomienia mogą mieć po zakodowaniu do 32 MB. Na przykład jeden 100-kubitowy obwód o głębokości 100 koduje się do około 39 KB, więc pojedyncze uruchomienie może przyjąć batch około 800 takich obwodów. W przypadku większych danych wejściowych prześlij plik i przekaż jego nazwę jako argument.
Zapisz wyniki
Użyj save_result() na końcu przepływu pracy, aby zwrócić wynik do notatnika. Odczytaj wynik w notatniku za pomocą job.result():
run_workflow_remotely.ipynb
result = job.result()
Aby to umożliwić, wywołaj save_result() w kodzie przepływu pracy:
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() koduje wynik w taki sam sposób, w jaki klient koduje argumenty, a job.result() go dekoduje. Wynik może więc zawierać obsługiwane typy argumentów, takie jak obwody, tablice NumPy i wynik zadania prymitywu, z tymi samymi zmianami typów.
-
Sprawdź zwracaną wartość. Jeśli
save_result()nie potrafi zakodować wartości, zapisuje ostrzeżenie w logach i zwracaFalsezamiast zgłaszać błąd. Bez sprawdzenia zadanie może zakończyć się statusemDONEi bez wyniku. -
Przechowywany jest tylko ostatni
save_result(). Każde wywołanie zastępuje zapisany wynik. Aby zwrócić kilka wartości, zapisz je w jednym słowniku lub zapisz je w logach. -
Pusty słownik oznacza brak wyniku. Jeśli przepływ pracy nigdy nie wywoła
save_result(),job.result()zwraca{}.
Aby zwrócić pliki, takie jak duże tablice lub wykresy, zapisz je w magazynie plików i zwróć ich nazwy w wyniku.
Najlepsza praktyka: weryfikuj argumenty za pomocą schematu
Zgodnie z najlepszą praktyką dołącz schemat JSON do każdego przepływu pracy, który przyjmuje argumenty. Schemat opisuje argumenty akceptowane przez przepływ pracy, a przepływ pracy sprawdza z nim argumenty każdego uruchomienia, zanim utworzy zadanie. Jeśli argumenty nie pasują, run() natychmiast kończy się błędem wskazującym nieprawidłowe pole, a przepływ pracy nie tworzy zadania. Bez schematu błędne argumenty docierają do przepływu pracy po starcie zadania, a przepływ pracy ignoruje błędnie wpisaną nazwę argumentu.
Ustaw schemat za pomocą arguments_schema podczas przesyłania przepływu pracy. Przekaż słownik, a nie ciąg 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,
)
)
Podczas pisania schematu pamiętaj o następujących kwestiach:
-
Opisz zakodowaną postać obiektów Qiskit i NumPy. Schemat sprawdza argumenty w takiej postaci, w jakiej wysyła je klient, więc obwód jest obiektem takim jak
{"__type__": "QuantumCircuit", "__value__": "<base64-encoded QPY>"}, a nie ciągiem znaków ani tablicą. Sprawdzaj znacznik__type__, a__value__traktuj jako nieprzejrzysty ciąg znaków. Schemat opisujący obwód jako ciąg znaków odrzuca każde poprawne uruchomienie. -
Ustaw
"additionalProperties": false. Bez tego ustawienia przepływ pracy bez ostrzeżenia ignoruje błędnie wpisaną nazwę argumentu, taką jakshotz, i działa z wartością domyślną. Zadeklaruj każdy argument akceptowany przez przepływ pracy, zanim włączysz to ustawienie. -
Oznacz argumenty jako wymagane. Dodaj do
requiredkażdy argument, który przepływ pracy odczytuje bez wartości domyślnej.
Jeśli argumenty nie pasują do schematu, komunikat o błędzie wskazuje regułę i położenie błędnej wartości:
'type' validation failed, schema requires 'integer': rejected value '4096'
path: ['shots']
Schemat sprawdza typ, kształt i zakres każdego argumentu. Nie potrafi sprawdzić, czy dwa poprawne argumenty ze sobą kolidują ani czy obwód pasuje do backendu. Takie kontrole umieść w kodzie przepływu pracy.
Zaktualizuj lub usuń schemat
-
Aby zastąpić schemat, ustaw nowy
arguments_schemai prześlij przepływ pracy ponownie. -
Aby usunąć schemat, prześlij przepływ pracy z
arguments_schema={}. -
Jeśli prześlesz przepływ pracy bez
arguments_schema, przepływ pracy zachowa zapisany schemat.
Aby zobaczyć obowiązujący schemat, odczytaj my_workflow.arguments_schema. Wartość None oznacza, że przepływ pracy nie ma schematu.
Sprawdź argumenty przed uruchomieniem
Wywołaj validate_arguments(), aby sprawdzić zestaw argumentów ze schematem bez uruchamiania zadania:
run_workflow_remotely.ipynb
my_workflow.validate_arguments({"circuits": [circuit], "shots": 1024})
# {'valid': True}
Jeśli argumenty są nieprawidłowe, validate_arguments() zgłasza QiskitServerlessException z tym samym komunikatem, który run() zwraca dla tych argumentów. Jeśli przepływ pracy nie ma schematu, wszystkie argumenty są poprawne. Pozytywny wynik nie gwarantuje, że run() się powiedzie, ponieważ run() sprawdza także inne limity, takie jak liczba aktywnych zadań.
Reguły schematu
Zarządzany przepływ pracy odrzuca przesłanie, jeśli schemat łamie którąkolwiek z poniższych reguł:
-
Schemat może mieć do 64 KiB, do 64 poziomów zagnieżdżenia i do 200 podschematów.
-
Odwołania muszą wskazywać wewnątrz tego samego schematu, na przykład
#/$defs/circuit, a każde odwołanie musi się rozwiązywać. Odwołania do adresów URL lub plików są niedozwolone. -
Schemat musi być obiektem lub wartością logiczną.
Unikaj także następujących problemów, których przesyłanie nie wychwytuje:
-
Zagnieżdżone kwantyfikatory w
pattern. Wzorzec taki jak^(a+)+$może być oceniany bardzo długo. Przepływ pracy przerywa walidację po przekroczeniu limitu czasu CPU i odrzuca uruchomienie. Pisz wzorce bez kwantyfikatora wokół grupy, która już go zawiera, takie jak^ibm_[a-z0-9_]{1,40}$. -
falsejako schemat. Schematfalseodrzuca każde uruchomienie. Aby usunąć walidację, użyj{}.
Rozwiązywanie problemów ze schematem
| Problem | Przyczyna |
|---|---|
| Każde uruchomienie jest odrzucane z powodu argumentu będącego obwodem. | Schemat opisuje obwód jako ciąg znaków lub tablicę. Opisz go jako obiekt ze znacznikiem __type__. |
| Poprawne uruchomienia są odrzucane. | additionalProperties ma wartość false, a schemat nie deklaruje argumentu przekazywanego w uruchomieniu. path w błędzie wskazuje ten argument. |
| Nieprawidłowe uruchomienia nie są odrzucane. | Przepływ pracy nie ma schematu. Sprawdź my_workflow.arguments_schema. |
| Żadne uruchomienie nie jest sprawdzane, choć ustawiono schemat. | Schemat został przekazany jako ciąg JSON. Przekaż słownik. |
Przesyłanie kończy się błędem 400. | Schemat łamie jedną z reguł schematu. |
| Błąd informuje, że walidacja zajęła zbyt dużo czasu CPU. | pattern zawiera zagnieżdżone kwantyfikatory. Przepisz wzorzec. |