Gestisci le risorse di elaborazione e dati dell' Qiskit Serverless
Il codice di questa pagina è stato sviluppato in base ai seguenti requisiti. Si consiglia di utilizzare queste versioni o versioni più recenti.
qiskit[all]~=2.0.0 qiskit-ibm-runtime~=0.37.0 qiskit-serverless~=0.22.0
Qiskit Serverless sta subendo un aggiornamento e le sue caratteristiche stanno cambiando rapidamente. Durante questa fase di sviluppo, è possibile trovare le note di rilascio e la documentazione più recente alla pagina Qiskit ServerlessGitHub.
Con Qiskit Serverless, è possibile gestire l'elaborazione e i dati attraverso il modello Qiskit, comprese le CPU, le QPU e altri acceleratori di calcolo.
Imposta stati dettagliati
I carichi di lavoro serverless hanno diverse fasi in un flusso di lavoro. Per impostazione predefinita, i seguenti stati sono visualizzabili con job.status():
QUEUED: il carico di lavoro è in coda per le risorse classicheINITIALIZING: il carico di lavoro è impostatoRUNNING: il carico di lavoro è attualmente in esecuzione su risorse classicheDONE: il carico di lavoro è stato completato con successo
È inoltre possibile impostare stati personalizzati che descrivono ulteriormente la fase specifica del flusso di lavoro, come segue.
Se stai leggendo le celle di codice localmente in un notebook, vedrai il comando %%writefile magico. L'esecuzione delle celle con questo comando speciale le salva su disco invece di eseguirle.
# If you include the preceding `%%writefile` command (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.
from qiskit_serverless import update_status, Job
# # If your function has a mapping stage, particularly application functions, you can set the status
# to "RUNNING: MAPPING" as follows:
update_status(Job.MAPPING)
# # While handling transpilation, error suppression, and so forth, you can set the status to
# "RUNNING: OPTIMIZING_FOR_HARDWARE":
update_status(Job.OPTIMIZING_HARDWARE)
# # After you submit jobs to IBM Quantum Compute Service, the underlying quantum job will be queued. You can set
# status to "RUNNING: WAITING_FOR_QPU":
update_status(Job.WAITING_QPU)
# # When the Quantum Compute job starts running on the QPU, set the following status
# "RUNNING: EXECUTING_QPU":
update_status(Job.EXECUTING_QPU)
## Once QPU is completed and post-processing has begun, set the status "RUNNING: POST_PROCESSING":
update_status(Job.POST_PROCESSING)Dopo aver completato con successo questo carico di lavoro (con save_result()), questo stato verrà aggiornato automaticamente a DONE .
Flussi di lavoro paralleli
Per le attività classiche che possono essere parallelizzate, usa il @distribute_task decoratore per definire i requisiti di calcolo necessari per eseguire un'attività. Inizia ricordando transpile_remote.py l'esempio dell'argomento " Scrivi il tuo primo programma in Qiskit Serverless " con il codice seguente.
Il codice seguente richiede che tu abbia già salvato le tue credenziali.
# If you include the preceding `%%writefile` command (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_serverless import distribute_task
service = QiskitRuntimeService()
@distribute_task(target={"cpu": 1})
def transpile_remote(circuit, optimization_level, backend):
"""
Transpiles an abstract circuit (or list of circuits)
into an ISA circuit for a given backend.
"""
pass_manager = generate_preset_pass_manager(
optimization_level=optimization_level,
backend=service.backend(backend)
)
isa_circuit = pass_manager.run(circuit)
return isa_circuitIn questo esempio, si è decorata la funzione transpile_remote() con @distribute_task(target={"cpu": 1}). Quando viene eseguito, crea un task worker parallelo asincrono con un singolo core della CPU e restituisce un riferimento per tracciare il worker. Per recuperare il risultato, passare il riferimento alla funzione get() . Possiamo usarlo per eseguire più task in parallelo:
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than
# executing the code.
from time import time
from qiskit_serverless import get, get_arguments, save_result, update_status, Job
# Get arguments
arguments = get_arguments()
circuit = arguments.get("circuit")
optimization_level = arguments.get("optimization_level")
backend = arguments.get("backend")# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.
# Start distributed transpilation
update_status(Job.OPTIMIZING_HARDWARE)
start_time = time()
transpile_worker_references = [
transpile_remote(circuit, optimization_level, backend)
for circuit in arguments.get("circuit_list")
]
transpiled_circuits = get(transpile_worker_references)
end_time = time()# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.
# Save result, with metadata
result = {
"circuits": transpiled_circuits,
"metadata": {
"resource_usage": {
"RUNNING: OPTIMIZING_FOR_HARDWARE": {
"CPU_TIME": end_time - start_time,
"QPU_TIME": 0,
},
}
},
}
save_result(result)Esplora diverse configurazioni delle attività
È possibile allocare in modo flessibile la CPU, la GPU e la memoria per i propri compiti tramite @distribute_task(). Per Qiskit Serverless su IBM Quantum® Platform, ogni programma è dotato di 16 core di CPU e 32 GB di RAM, che possono essere allocati dinamicamente secondo le necessità.
I core della CPU possono essere allocati come core completi o anche in modo frazionario, come mostrato di seguito.
La memoria viene allocata in numero di byte. Ricordiamo che ci sono 1024 byte in un kilobyte, 1024 kilobyte in un megabyte e 1024 megabyte in un gigabyte. Per allocare 2 GB di memoria per il worker, è necessario allocare "mem": 2 * 1024 * 1024 * 1024.
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.
@distribute_task(target={
"cpu": 16,
"mem": 2 * 1024 * 1024 * 1024
})
def transpile_remote(circuit, optimization_level, backend):
return NoneGestisci i dati in tutto il tuo programma
Qiskit Serverless consente di gestire i file nella directory /data in tutti i programmi. Ciò comporta diverse limitazioni:
- Oggi sono supportati solo i file
tareh5 - Si tratta solo di una memoria piatta
/datae non può avere sottodirectory/data/folder/
Di seguito viene illustrato come caricare i file. Assicurati di aver effettuato l'autenticazione su Qiskit Serverless con il tuo account IBM Quantum (vedi Carica su Qiskit Serverless per le istruzioni).
import tarfile
from qiskit_serverless import IBMServerlessClient
# Create a tar
filename = "transpile_demo.tar"
file = tarfile.open(filename, "w")
file.add("./source_files/transpile_remote.py")
file.close()
# Get a reference to a QiskitFunction
serverless = IBMServerlessClient()
transpile_remote_demo = next(
program
for program in serverless.list()
if program.title == "transpile_remote_serverless"
)
# Upload the tar to Serverless data directory
serverless.file_upload(file=filename, function=transpile_remote_demo)Output:
'{"message":"/usr/src/app/media/5e1f442128cdf60018496a04/transpile_demo.tar"}'
Successivamente, è possibile elencare tutti i file presenti nella directory data . Questi dati sono accessibili a tutti i programmi.
serverless.files(function=transpile_remote_demo)Output:
['classifier_name.pkl.tar', 'output.json.tar', 'transpile_demo.tar']
Questo può essere fatto da un programma usando file_download() per scaricare il file nell'ambiente del programma e decomprimendo tar.
# If you include the preceding `%%writefile` command
# (visible only when you read this locally in a
# notebook), running this cell saves to disk rather than executing the code.
import tarfile
from qiskit_serverless import IBMServerlessClient
# For `token`, use the 44-character API_KEY you created
# and saved from the IBM Quantum Platform Home dashboard
serverless = IBMServerlessClient(token="<YOUR_API_KEY>")
files = serverless.files()
demo_file = files[0]
downloaded_tar = serverless.file_download(demo_file)
with tarfile.open(downloaded_tar, 'r') as tar:
tar.extractall()A questo punto, il programma può interagire con i file come se fosse un esperimento locale. file_upload() i file file_download() e file_delete() possono essere richiamati dall'esperimento locale o dal programma caricato, per una gestione dei dati coerente e flessibile.
Passi successivi
- Guarda un esempio completo che illustra come trasferire il codice esistente su Qiskit Serverless.
- Leggete un articolo in cui i ricercatori hanno utilizzato Qiskit Serverless e il supercomputing quantum-centrico per esplorare la chimica quantistica.