Udostępnij za pośrednictwem


Jak zarządzać sesjami

Z tego artykułu dowiesz się, jak zarządzać sesjami. W przypadku sesji można grupować jedno lub więcej zadań względem jednego targetzadania, co pozwala efektywnie zarządzać zadaniami. Aby uzyskać więcej informacji, zobacz Wprowadzenie do sesji.

Wymagania wstępne

  • Konto platformy Azure z aktywną subskrypcją. Jeśli nie masz konta platformy Azure, zarejestruj się bezpłatnie i zarejestruj się w celu korzystania z subskrypcji z płatnością zgodnie z rzeczywistym użyciem.

  • Obszar roboczy usługi Azure Quantum. Aby uzyskać więcej informacji, zobacz Tworzenie obszaru roboczego usługi Azure Quantum.

  • Środowisko języka Python z zainstalowanym językiem Python i programem .

  • Pakiet Azure Quantum azure-quantum . Jeśli chcesz użyć zestawu Qiskit lub Cirq, musisz zainstalować azure-quantum pakiet przy użyciu tagów [qiskit] lub [cirq].

    pip install --upgrade azure-quantum[qiskit] 
    

Uwaga

Sesje są zarządzane przy użyciu języka Python, nawet w przypadku uruchamiania Q# kodu wbudowanego.

Sesje monitorowania

Możesz użyć bloku Zarządzanie zadaniami w obszarze roboczym Quantum, aby wyświetlić wszystkie przesłane elementy najwyższego poziomu, w tym sesje i poszczególne zadania, które nie są skojarzone z żadną sesją.

  1. Wybierz blok Zarządzanie zadaniami w obszarze roboczym Quantum.
  2. Zidentyfikuj zadania typu Sesja. W tym widoku można zobaczyć unikatowy identyfikator sesji w kolumnie Id i monitorować jego stan. Stany sesji to:
    • Oczekiwanie: zadania w ramach sesji są wykonywane.
    • Powodzenie: sesja zakończyła się pomyślnie.
    • Limit czasu: jeśli w sesji nie zostanie przesłane żadne nowe zadanie przez 10 minut, limit czasu tej sesji jest przekroczony. Aby uzyskać więcej informacji, zobacz Limity czasu sesji.
    • Niepowodzenie: jeśli zadanie w sesji zakończy się niepowodzeniem, ta sesja zakończy się i zgłosi stan Niepowodzenie. Aby uzyskać więcej informacji, zobacz Zasady niepowodzenia zadań w ramach sesji.
  3. Kliknij nazwę sesji, aby uzyskać więcej szczegółów.
  4. Możesz wyświetlić listę Wszystkie zadania w ramach sesji i monitorować ich stan.

Pobieranie i wyświetlanie listy sesji

W poniższej tabeli przedstawiono polecenia języka Python umożliwiające pobranie listy wszystkich sesji i wszystkich zadań dla danej sesji.

Polecenie opis
workspace.list_sessions() lub session.list_sessions() Pobierz listę wszystkich sesji w obszarze roboczym kwantowym.
workspace.get_session(sessionId) lub session.get_session(sessionId) Pobierz sesję o identyfikatorze sessionId. Każda sesja ma unikatowy identyfikator.
workspace.list_session_jobs(sessionId) lub session.list_session_jobs(sessionId) Pobierz listę wszystkich zadań w sesji o identyfikatorze sessionId. Każda sesja ma unikatowy identyfikator.

Na przykład poniższy kod definiuje funkcję, która pobiera sesję z minimalną liczbą zadań. Następnie dla tej sesji wyświetla listę wszystkich zadań, łączną liczbę zadań i pierwsze 10 zadań.

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}")

Ręczne metody otwierania/zamykania sesji

Zalecamy wykonanie czynności opisanych w temacie Rozpoczynanie pracy z sesjami w celu utworzenia nowej sesji. Można również ręcznie tworzyć sesje.

  1. Najpierw utwórz obiekt Sesja.

    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}")
    

    Uwaga

    W tym momencie sesja istnieje tylko na kliencie i widać, że stan to Brak. Aby wyświetlić stan sesji, należy również utworzyć sesję w usłudze.

  2. Aby utworzyć sesję w usłudze, możesz użyć polecenia workspace.open_session(session) lub session.open().

  3. Możesz odświeżyć stan i szczegóły sesji za pomocą session.refresh()polecenia lub uzyskać nowy obiekt sesji z identyfikatora sesji.

    same_session = workspace.get_session(session.id) 
    print(f"Session: {session.details} \n")
    print(f"Session: {same_session.details} \n")
    
  4. Możesz zamknąć sesję za pomocą session.close() polecenia lub workspace.close_session(session).

  5. Aby dołączyć sesję do elementu target , możesz użyć polecenia target.latest_session.

  6. Możesz poczekać na ukończenie sesji:

    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)
    

Przekazywanie argumentów w Q#

Q# Jeśli operacja przyjmuje argumenty wejściowe, te argumenty są przekazywane podczas przesyłania zadania, czyli kodu w języku Python. Oznacza to, że należy zachować ostrożność, aby sformatować argumenty jako Q# obiekty.

Podczas przekazywania argumentów jako parametrów do zadania są one formatowane jako Q# kod podczas wywoływania qsharp.compilemetody , więc wartości z języka Python muszą być sformatowane w ciągu jako prawidłową Q# składnię.

Rozważmy następujący Q# program, który przyjmuje liczbę całkowitą, ni tablicę kątów, angle, jako dane wejściowe.

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;
}

Chcesz uruchomić GenerateRandomBits operację trzy razy z różnymi kątami n=2 i różnymi kątami. Możesz użyć następującego kodu w języku Python, aby przesłać trzy zadania z różnymi kątami.

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]

W tym przykładzie, ponieważ tablice w języku Python są już drukowane jako [item0, item1, ...], argumenty wejściowe są zgodne z formatowaniem Q# . W przypadku innych struktur danych języka Python może być potrzebna większa obsługa, aby uzyskać wartości ciągów wstawione w Q# zgodny sposób. Na przykład Q# krotka musi znajdować się w nawiasach z wartościami rozdzielanymi przecinkami.

Limity czasu sesji

Limit czasu sesji, jeśli w sesji nie zostanie przesłane żadne nowe zadanie przez 10 minut. Sesja zgłasza stan limitu czasu. Aby uniknąć tej sytuacji, dodaj with blok przy użyciu metody backend.open_session(name="Name"), więc sesja close() jest wywoływana przez usługę na końcu bloku kodu.

Uwaga

Jeśli w programie występują błędy lub błędy, przesłanie nowego zadania w sesji może potrwać ponad 10 minut po zakończeniu wszystkich poprzednich zadań w sesji.

Poniższe fragmenty kodu pokazują przykład przekroczenia limitu czasu sesji po 10 minutach, ponieważ nie są przesyłane żadne nowe zadania. Aby tego uniknąć, następny fragment kodu pokazuje, jak utworzyć sesję za with pomocą bloku.

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

Zasady niepowodzenia zadania w ramach sesji

Domyślne zasady dla sesji, gdy zadanie zakończy się niepowodzeniem, to zakończenie tej sesji. Jeśli przesyłasz dodatkowe zadanie w ramach tej samej sesji, usługa ją odrzuca, a sesja zgłasza stan Niepowodzenie. Wszystkie zadania w toku są anulowane.

To zachowanie można jednak zmienić, określając zasady job_failure_policy=SessionJobFailurePolicy.CONTINUEniepowodzenia zadania zamiast domyślnego SessionJobFailurePolicy.ABORT, podczas tworzenia sesji. Gdy zasady niepowodzenia zadania to CONTINUE, usługa nadal akceptuje zadania. Sesja zgłasza w tym przypadku stan Awarie , które zmienią się na Niepowodzenie po zamknięciu sesji.

Jeśli sesja nigdy nie zostanie zamknięta i przekroczono limit czasu, stan to Limit czasu, nawet jeśli zadania zakończyły się niepowodzeniem.

Na przykład poniższy program tworzy sesję z trzema zadaniami. Pierwsze zadanie kończy się niepowodzeniem, ponieważ określa "garbage" jako dane wejściowe. Aby uniknąć zakończenia sesji w tym momencie, program pokazuje, jak dodać job_failure_policy=SessionJobFailurePolicy.CONTINUE podczas tworzenia sesji.

#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")