Condividi tramite


Come gestire le sessioni

In Azure Quantum è possibile raggruppare più processi in un'unica target, che consente di gestire in modo efficace i processi. Questa operazione è chiamata una sessione . Per altre informazioni, vedere Introduzione alle sessioni.

In questo articolo scoprirai come gestire manualmente i tuoi lavori utilizzando le sessioni, quali sono le politiche di gestione degli errori dei lavori e come evitare i timeout delle sessioni.

Prerequisiti

  • Un account Azure con una sottoscrizione attiva. Se non si ha un account Azure, registrarsi gratuitamente e iscriversi per ottenere una sottoscrizione con pagamento in base al consumo.

  • Un'area di lavoro di Azure Quantum. Per altre informazioni, vedere Creare un'area di lavoro di Azure Quantum.

  • Un ambiente Python con Python e Pip installati.

  • Pacchetto azure-quantum di Azure Quantum. Se si vuole usare Qiskit o Cirq, è necessario installare il pacchetto azure-quantum con i tag [qiskit] o [cirq].

    pip install --upgrade azure-quantum[qiskit] 
    

Nota

Le sessioni vengono gestite con Python, anche quando si esegue Q# codice inline.

Sessioni di monitoraggio

È possibile usare il pannello gestione dei processi nell'area di lavoro Quantum per visualizzare tutti gli elementi inviati di primo livello, comprese le sessioni e i singoli processi non associati ad alcuna sessione.

  1. Selezionare il pannello gestione dei lavori nell'area di lavoro Quantum.
  2. Identificare i lavori di tipo Session. In questa vista è possibile visualizzare l'ID univoco di una sessione nella colonna ID e monitorare il relativo stato . Gli stati di una sessione sono:
    • In attesa: I compiti all'interno della sessione vengono eseguiti.
    • Operazione riuscita: la sessione è stata conclusa correttamente.
    • TimeOut: se non viene inviato alcun nuovo processo all'interno della sessione per 10 minuti, la sessione terminerà. Per altre informazioni, vedere Timeout della sessione.
    • Non riuscito: se un processo all'interno di una sessione non riesce, la sessione termina e segnala lo stato Non riuscito. Per ulteriori informazioni, vedere Politica di fallimento dei processi nelle sessioni.
  3. Fare clic sul nome di una sessione per altri dettagli.
  4. È possibile visualizzare l'elenco di tutti i lavori all'interno della sessione e monitorarne lo stato.

Recupero ed elenco di sessioni

La tabella seguente illustra i comandi Python per ottenere l'elenco di tutte le sessioni e di tutti i processi per una determinata sessione.

Comando Descrizione
workspace.list_sessions() o session.list_sessions() Recuperare un elenco di tutte le sessioni in un'area di lavoro quantistica.
workspace.get_session(sessionId) o session.get_session(sessionId) Recuperare la sessione con ID sessionId. Ogni sessione ha un ID univoco.
workspace.list_session_jobs(sessionId) o session.list_session_jobs(sessionId) Recupera l'elenco di tutti i processi nella sessione con ID sessionId. Ogni sessione ha un ID univoco.

Ad esempio, il codice seguente definisce una funzione che ottiene una sessione con un numero minimo di processi. Quindi, in quella sessione, elenca tutti i lavori, il numero totale e i primi 10.

def get_a_session_with_jobs(min_jobs):
    all_sessions = workspace.list_sessions() # list of all sessions
    for session in all_sessions:
        if len(workspace.list_session_jobs(session.id)) >= min_jobs:
            return session

session = get_a_session_with_jobs(min_jobs=3) # Get a Session with at least 3 jobs

session_jobs = workspace.list_session_jobs(session.id) # List of all jobs within Session ID

print(f"Job count: {len(session_jobs)} \n")
print(f"First 10 jobs for session {session.id}:")
for job in session_jobs[0:10]:
    print(f"Id: {job.id}, Name={job.details.name}")

Metodi manuali di apertura/chiusura di sessioni

È consigliabile seguire i passaggi descritti in Introduzione alle sessioni per creare una nuova sessione. È anche possibile creare manualmente sessioni.

  1. Creare prima di tutto un oggetto Session .

    from azure.quantum.job.session import Session, SessionDetails, SessionJobFailurePolicy
    import uuid
    
    session = Session(
        workspace=workspace, # required
        id=f"{uuid.uuid1()}", # optional, if not passed will use uuid.uuid1()
        name="", # optional, will be blank if not passed
        provider_id="ionq", # optional, if not passed will try to parse from the target
        target="ionq.simulator", # required
        job_failure_policy=SessionJobFailurePolicy.ABORT # optional, defaults to abort
        )
    
    print(f"Session status: {session.details.status}")
    

    Nota

    A questo punto, la sessione esiste solo nel client ed è possibile notare che lo stato è Nessuno. Per visualizzare lo stato della sessione, è anche necessario creare la sessione nel servizio.

  2. Per creare una sessione nel servizio, è possibile usare workspace.open_session(session) o session.open().

  3. È possibile aggiornare lo stato e i dettagli della sessione con session.refresh()oppure ottenendo un nuovo oggetto sessione da un ID sessione.

    same_session = workspace.get_session(session.id) 
    print(f"Session: {session.details} \n")
    print(f"Session: {same_session.details} \n")
    
  4. È possibile chiudere una sessione con session.close() o workspace.close_session(session).

  5. Per allegare la sessione a un target, è possibile usare target.latest_session.

  6. È possibile attendere per il completamento di una sessione:

    session_jobs = session.list_jobs()
    [session_job.id for session_job in session_jobs]
    
    import time
    while (session.details.status != "Succeeded" and session.details.status != "Failed" and session.details.status != "TimedOut"):
      session.refresh()
      time.sleep(5)
    

Passaggio di argomenti in Q#

Se l'operazione Q# richiede argomenti di input, tali argomenti vengono forniti durante la fase di invio del processo, che avviene tramite codice Python. Ciò significa che è necessario prestare attenzione a formattare gli argomenti come oggetti Q#.

Quando si passano argomenti come parametri al processo, questi vengono formattati come codice Q# quando si chiama qsharp.compile, quindi i valori di Python devono essere formattati in una stringa come sintassi Q# valida.

Si consideri il programma di Q# seguente, che accetta un numero intero, ne una matrice di angoli, angle, come input.

import Std.Measurement.*;
import Std.Arrays.*;

operation GenerateRandomBits(n: Int, angle: Double[]) : Result[] {
   use qubits = Qubit[n]; // n parameter as the size of the qubit array
   for q in qubits {
       H(q);
   }
   R(PauliZ, angle[0], qubits[0]); // arrays as entry-points parameters
   R(PauliZ, angle[1], qubits[1]);
   let results = MeasureEachZ(qubits);
   ResetAll(qubits);
   return results;
}

Si vuole eseguire l'operazione GenerateRandomBits tre volte con n=2 e angoli diversi. È possibile usare il codice Python seguente per inviare tre job con angoli diversi.

angle = [0.0, 0.0]
with target.open_session(name="Q# session of three jobs") as session:
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 1", shots=100) # First job submission
    angle[0] += 1
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 2", shots=100) # Second job submission
    angle[1] += 1
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 3", shots=100) # Third job submission

session_jobs = session.list_jobs()
[session_job.details.name for session_job in session_jobs]

In questo esempio, poiché le matrici in Python sono già stampate come [item0, item1, ...], gli argomenti di input corrispondono alla formattazione Q#. Per altre strutture di dati Python potrebbe essere necessaria una gestione maggiore per ottenere i valori stringa inseriti nella Q# in modo compatibile. Ad esempio, una tupla Q# deve essere racchiusa tra parentesi con valori delimitati da virgole.

Timeout di sessione

Si verifica il timeout di una sessione se non viene inviato alcun nuovo processo all'interno della sessione per 10 minuti. La sessione segnala lo stato di TimedOut. Per evitare questa situazione, aggiungere un blocco with usando backend.open_session(name="Name"), in modo che la sessione close() venga richiamata dal servizio alla fine del blocco di codice.

Nota

Se sono presenti errori o bug nel programma, potrebbero essere necessari più di 10 minuti per inviare un nuovo processo dopo il completamento dei processi precedenti nella sessione.

I frammenti di codice seguenti mostrano un esempio di sessione che scade dopo 10 minuti perché non vengono sottoposti nuovi lavori. Per evitare questo problema, il frammento di codice successivo mostra come usare un blocco with per creare una sessione.

#Example of a session that times out 

session = backend.open_session(name="Qiskit circuit session") # Session times out because only contains one job
backend.run(circuit=circuit, shots=100, job_name="Job 1")
#Example of a session that includes a with block to avoid timeout

with backend.open_session(name="Qiskit circuit session") as session:  # Use a with block to submit multiple jobs within a session
    job1 = backend.run(circuit=circuit, shots=100, job_name="Job 1") # First job submission
    job1.wait_for_final_state()
    job2 = backend.run(circuit=circuit, shots=100, job_name="Job 2") # Second job submission
    job2.wait_for_final_state()
    job3 = backend.run(circuit=circuit, shots=100, job_name="Job 3") # Third job submission
    job3.wait_for_final_state()

Politica di errore del lavoro all'interno delle sessioni

Il criterio predefinito per una sessione quando un lavoro non riesce è di terminare quella sessione. Se si invia un lavoro aggiuntivo all'interno della stessa sessione, il servizio lo rifiuta e la sessione segnala lo stato Non riuscito. Eventuali processi in corso vengono annullati.

Tuttavia, durante la creazione della sessione, questo comportamento può essere modificato specificando un criterio di errore del lavoro di job_failure_policy=SessionJobFailurePolicy.CONTINUEanziché il predefinito SessionJobFailurePolicy.ABORT. Quando il criterio di errore del lavoro è CONTINUE, il servizio continua ad accettare lavori. La sessione indica un stato di Errore/i in questo caso, che verrà cambiato in Errore una volta chiusa la sessione.

La sessione non viene mai chiusa e va in timeout, lo stato è TimedOut anche se le operazioni non sono riuscite.

Ad esempio, il programma seguente crea una sessione con tre job. Il primo lavoro fallisce perché specifica "garbage" come dati di input. Per evitare la fine della sessione a questo punto, il programma mostra come aggiungere job_failure_policy=SessionJobFailurePolicy.CONTINUE durante la creazione della sessione.

#Example of a session that does not close but reports Failure(s) when a jobs fails

with target.open_session(name="JobFailurePolicy Continue", job_failure_policy=SessionJobFailurePolicy.CONTINUE) as session:
    target.submit(input_data="garbage", name="Job 1") #Input data is missing, this job fails
    target.submit(input_data=quil_program, name="Job 2") #Subsequent jobs are accepted because of CONTINUE policy
    target.submit(input_data=quil_program, name="Job 3")