Vai al contenuto principale
Questo progetto è in fase beta. Hai trovato un bug? Apri una issue su GitHub. Hai una domanda o un'idea? Chiedi su GitHub Discussions — apprezziamo il tuo feedback!
Com'è la qualità della traduzione su questa pagina?

Definisci input e output

Un workflow gestito funziona come una funzione Python eseguita su calcolo remoto. Confronta una funzione locale con lo stesso codice come workflow:

Local Python

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

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

In un workflow gestito, run() è la chiamata, get_arguments() fornisce al workflow i suoi parametri e save_result() è la sua istruzione return. Poiché il workflow viene eseguito come job separato su calcolo remoto, differisce da una chiamata di funzione locale in tre modi:

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

Leggi gli argomenti nel tuo workflow​

Passa gli input al tuo workflow dal tuo notebook locale:

run_workflow_remotely.ipynb

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

Per abilitarlo, modifica il codice del tuo workflow in modo che recuperi gli argomenti con get_arguments(), che restituisce un dizionario le cui chiavi sono i nomi degli argomenti:

source_files/my_workflow.py

from qiskit_serverless import get_arguments

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

Il dizionario contiene solo gli argomenti passati dall'esecuzione, quindi usa arguments.get() con un valore predefinito per gli argomenti opzionali. Puoi usare qualsiasi nome di argomento tranne le parole chiave protette config e function_size, perché run() usa direttamente queste parole chiave. run() rifiuta anche compute_profile. Per scegliere le risorse di calcolo, passa function_size.

Per leggere la dimensione con cui viene eseguito il job, chiama get_function_size() nel codice del tuo workflow:

source_files/my_workflow.py

from qiskit_serverless import get_function_size

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

Se l'esecuzione non passa function_size, get_function_size() restituisce la dimensione predefinita del workflow. Vedi Scegli una dimensione per ogni esecuzione.

Tipi di argomento supportati​

Ogni valore deve essere serializzabile in JSON, oppure un oggetto che il client sia in grado di codificare, come un circuito Qiskit o un array NumPy. Poiché il client codifica ogni argomento prima di inviare il job e get_arguments() lo decodifica all'interno del workflow, il workflow riceve l'oggetto Python originale.

Il client invia int, float, str, bool, None e liste o dizionari di questi senza modifiche. Codifica altri oggetti, come un QuantumCircuit, un numpy.ndarray o un numero complex, come un dizionario con un tag __type__ e un __value__. Hai bisogno di questa forma quando scrivi uno schema degli argomenti.

Poiché JSON non ha un equivalente per alcuni tipi, questi tipi cambiano durante la codifica. Le tuple arrivano come liste, le chiavi dei dizionari arrivano come stringhe e gli interi NumPy come np.int64 arrivano come int. Se il client non riesce a codificare un valore, come bytes o np.float32, run() solleva un TypeError e non crea un job.

Alcuni oggetti non possono essere passati come argomenti. Ad esempio, passa il nome di un backend come stringa invece di un oggetto Backend, e crea il backend all'interno del workflow. Vedi Esegui job quantistici da un workflow.

Limiti di dimensione​

Gli argomenti di una singola esecuzione possono arrivare a 32 MB dopo la codifica. Ad esempio, un circuito da 100 qubit con una profondità di 100 si codifica in circa 39 KB, quindi una singola esecuzione può accettare un batch di circa 800 circuiti di questo tipo. Per input più grandi, carica un file e passa il suo nome come argomento.

Salva i risultati​

Usa save_result() alla fine del tuo workflow per restituire un risultato al tuo notebook. Leggi il risultato nel tuo notebook con job.result():

run_workflow_remotely.ipynb

result = job.result()

Per abilitarlo, chiama save_result() nel codice del tuo 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() codifica il risultato allo stesso modo in cui il client codifica gli argomenti, e job.result() lo decodifica. Un risultato può quindi contenere i tipi di argomento supportati, come circuiti, array NumPy e il risultato di un job primitivo, con le stesse modifiche di tipo.

  • Controlla il valore restituito. Se save_result() non riesce a codificare il valore, registra un avviso e restituisce False invece di sollevare un errore. Senza un controllo, il job può terminare con lo stato DONE e nessun risultato.

  • Viene archiviato solo l'ultimo save_result(). Ogni chiamata sostituisce il risultato salvato. Per restituire più valori, salvali in un unico dizionario, oppure scrivili nei log.

  • Un dizionario vuoto significa nessun risultato. Se il workflow non chiama mai save_result(), job.result() restituisce {}.

Per restituire file, come array di grandi dimensioni o grafici, salvali nell'archiviazione file e restituisci i loro nomi nel risultato.

Buona pratica: convalida gli argomenti con uno schema​

Come buona pratica, allega uno JSON Schema a ogni workflow che accetta argomenti. Lo schema descrive gli argomenti che il workflow accetta, e il workflow controlla gli argomenti di ogni esecuzione rispetto a esso prima di creare il job. Se gli argomenti non corrispondono, run() fallisce immediatamente con un errore che indica il campo errato, e il workflow non crea un job. Senza uno schema, gli argomenti errati raggiungono il workflow dopo l'avvio del job, e il workflow ignora il nome di un argomento scritto in modo errato.

Imposta lo schema con arguments_schema quando carichi il workflow. Passa un dizionario, non una stringa 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,
)
)

Tieni presenti i seguenti punti quando scrivi uno schema:

  • Descrivi la forma codificata degli oggetti Qiskit e NumPy. Lo schema controlla gli argomenti così come li invia il client, quindi un circuito è un oggetto come {"__type__": "QuantumCircuit", "__value__": "<base64-encoded QPY>"}, non una stringa o un array. Controlla il tag __type__ e tratta __value__ come una stringa opaca. Uno schema che descrive un circuito come stringa rifiuta ogni esecuzione valida.

  • Imposta "additionalProperties": false. Senza questa impostazione, il workflow ignora senza avviso il nome di un argomento scritto in modo errato, come shotz, ed esegue con il suo valore predefinito. Dichiara ogni argomento che il workflow accetta prima di abilitare questa impostazione.

  • Contrassegna gli argomenti come obbligatori. Aggiungi a required ogni argomento che il workflow legge senza un valore predefinito.

Se gli argomenti non corrispondono allo schema, il messaggio di errore indica la regola e la posizione del valore errato:

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

Uno schema controlla il tipo, la forma e l'intervallo di ogni argomento. Uno schema non può controllare se due argomenti validi sono in conflitto, o se un circuito si adatta a un backend. Mantieni questi controlli nel codice del workflow.

Aggiorna o rimuovi uno schema​

  • Per sostituire lo schema, imposta un nuovo arguments_schema e carica di nuovo il workflow.

  • Per rimuovere lo schema, carica il workflow con arguments_schema={}.

  • Se carichi il workflow senza arguments_schema, il workflow mantiene lo schema archiviato.

Per vedere lo schema in vigore, leggi my_workflow.arguments_schema. Un valore None significa che il workflow non ha schema.

Controlla gli argomenti prima di eseguire​

Chiama validate_arguments() per controllare un insieme di argomenti rispetto allo schema senza avviare un job:

run_workflow_remotely.ipynb

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

Se gli argomenti non sono validi, validate_arguments() solleva una QiskitServerlessException con lo stesso messaggio che run() restituisce per quegli argomenti. Se il workflow non ha uno schema, qualsiasi argomento è valido. Un risultato valido non garantisce che run() abbia successo, perché run() controlla anche altri limiti, come il numero di job attivi.

Regole dello schema​

Un workflow gestito rifiuta il caricamento se lo schema viola una qualsiasi delle seguenti regole:

  • Lo schema può essere grande fino a 64 KiB, con fino a 64 livelli di annidamento e fino a 200 sottoschemi.

  • I riferimenti devono puntare all'interno dello stesso schema, come #/$defs/circuit, e ogni riferimento deve essere risolvibile. I riferimenti a URL o file non sono consentiti.

  • Lo schema deve essere un oggetto o un booleano.

Evita anche i seguenti problemi, che il caricamento non rileva:

  • Quantificatori annidati in pattern. Un pattern come ^(a+)+$ può richiedere moltissimo tempo per essere valutato. Un workflow interrompe la convalida dopo un limite di tempo CPU e rifiuta l'esecuzione. Scrivi pattern senza un quantificatore attorno a un gruppo che ne contiene già uno, come ^ibm_[a-z0-9_]{1,40}$.

  • false come schema. Lo schema false rifiuta ogni esecuzione. Per rimuovere la convalida, usa {}.

Risolvi i problemi di uno schema​

ProblemaCausa
Ogni esecuzione viene rifiutata per un argomento circuito.Lo schema descrive il circuito come una stringa o un array. Descrivilo come un oggetto con un tag __type__.
Esecuzioni valide vengono rifiutate.additionalProperties è false, e lo schema non dichiara un argomento che l'esecuzione passa. Il path dell'errore indica l'argomento.
Esecuzioni non valide non vengono rifiutate.Il workflow non ha uno schema. Controlla my_workflow.arguments_schema.
Nessuna esecuzione viene controllata, anche se hai impostato uno schema.Lo schema è stato passato come stringa JSON. Passa un dizionario.
Il caricamento fallisce con un errore 400.Lo schema viola una delle regole dello schema.
L'errore dice che la convalida ha richiesto troppo tempo CPU.Un pattern ha quantificatori annidati. Riscrivi il pattern.