Поделиться через


Управление сеансами

Из этой статьи вы узнаете, как управлять сеансами. С помощью сеансов можно сгруппировать одно или несколько заданий по одному target, что позволяет эффективно управлять заданиями. Дополнительные сведения см. в статье "Начало работы с сеансами".

Необходимые компоненты

  • Учетная запись Azure с активной подпиской. Если у вас нет учетной записи Azure, зарегистрируйтесь бесплатно и зарегистрируйтесь для подписки с оплатой по мере использования.

  • Рабочая область Azure Quantum. Дополнительные сведения см. в статье Создание рабочей области Azure Quantum.

  • Среда Python с установленным Python и Pip .

  • Пакет Azure Quantum azure-quantum . Если вы хотите использовать Qiskit или Cirq, необходимо установить azure-quantum пакет с тегами [qiskit] или [cirq].

    pip install --upgrade azure-quantum[qiskit] 
    

Примечание.

Сеансы управляются с помощью Python, даже если выполняется Q# встроенный код.

Мониторинг сеансов

Вы можете использовать колонку управления заданиями в рабочей области Quantum для просмотра всех отправленных элементов верхнего уровня, включая сеансы и отдельные задания, которые не связаны с любым сеансом.

  1. Выберите колонку управления заданиями в рабочей области Quantum.
  2. Определите задания типа Session. В этом представлении можно увидеть уникальный идентификатор сеанса в идентификаторе столбца и отслеживать его состояние. Состояния сеанса:
    • Ожидание: выполняются задания в сеансе.
    • Выполнено: сеанс завершился успешно.
    • Время ожидания: если новое задание не отправляется в течение сеанса в течение 10 минут, время ожидания сеанса истекает. Дополнительные сведения см. в разделе "Время ожидания сеанса".
    • Сбой: если задание в сеансе завершается сбоем, этот сеанс завершается и сообщает о состоянии сбоя. Дополнительные сведения см . в разделе "Политика сбоя задания" в сеансах.
  3. Щелкните имя сеанса для получения дополнительных сведений.
  4. Список всех заданий в сеансе можно просмотреть и отслеживать их состояние.

Получение и перечисление сеансов

В следующей таблице показаны команды Python для получения списка всех сеансов и всех заданий для данного сеанса.

Команда Description
workspace.list_sessions() или session.list_sessions() Получение списка всех сеансов в рабочей области Quantum.
workspace.get_session(sessionId) или session.get_session(sessionId) Получение сеанса с идентификатором sessionId. Каждый сеанс имеет уникальный идентификатор.
workspace.list_session_jobs(sessionId) или session.list_session_jobs(sessionId) Получение списка всех заданий в сеансе с идентификатором sessionId. Каждый сеанс имеет уникальный идентификатор.

Например, следующий код определяет функцию, которая получает сеанс с минимальным количеством заданий. Затем для этого сеанса в нем перечислены все задания, общее количество заданий и первые 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}")

Методы ручного открытия и закрытия сеансов

Мы рекомендуем выполнить действия, описанные в разделе "Начало работы с сеансами ", чтобы создать новый сеанс. Вы также можете создавать сеансы вручную.

  1. Сначала создайте объект 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}")
    

    Примечание.

    На этом этапе сеанс существует только на клиенте, и вы увидите, что состояние "Нет". Чтобы просмотреть состояние сеанса, необходимо также создать сеанс в службе.

  2. Чтобы создать сеанс в службе, можно использовать workspace.open_session(session) или session.open().

  3. Вы можете обновить состояние и сведения о сеансе с session.refresh()помощью или получить новый объект сеанса из идентификатора сеанса.

    same_session = workspace.get_session(session.id) 
    print(f"Session: {session.details} \n")
    print(f"Session: {same_session.details} \n")
    
  4. Сеанс можно закрыть с session.close() помощью или workspace.close_session(session).

  5. Чтобы подключить сеанс к сеансу target, можно использовать target.latest_session.

  6. Вы можете дождаться завершения сеанса:

    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)
    

Передача аргументов в Q#

Если операция Q# принимает входные аргументы, эти аргументы передаются во время отправки задания, который является кодом Python. Это означает, что необходимо тщательно отформатировать аргументы в виде Q# объектов.

При передаче аргументов в качестве параметров в задание они форматируются как Q# код при вызове qsharp.compile, поэтому значения из Python должны быть отформатированы в строку как допустимый Q# синтаксис.

Рассмотрим следующую Q# программу, которая принимает целое число nи массив углов, angleв качестве входных данных.

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

Вы хотите выполнить GenerateRandomBits операцию три раза с n=2 различными углами. Для отправки трех заданий с разными углами можно использовать следующий код Python.

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]

В этом примере, так как массивы в Python уже печатаются как [item0, item1, ...], входные аргументы соответствуют Q# форматированию. Для других структур данных Python может потребоваться дополнительная обработка, чтобы получить строковые значения, вставляемые Q# в совместимый способ. Например, Q# кортеж должен находиться в скобках с разделенными запятыми значениями.

Время ожидания сеанса

Время ожидания сеанса, если новое задание не отправлено в течение 10 минут. Сеанс сообщает о состоянии TimedOut. Чтобы избежать этой ситуации, добавьте with блок с помощью backend.open_session(name="Name"), поэтому сеанс close() вызывается службой в конце блока кода.

Примечание.

Если в программе возникают ошибки или ошибки, может потребоваться более 10 минут, чтобы отправить новое задание после завершения предыдущих заданий в сеансе.

В следующем фрагменте кода показан пример времени ожидания сеанса через 10 минут, так как новые задания не отправляются. Чтобы избежать этого, в следующем фрагменте кода показано, как использовать with блок для создания сеанса.

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

Политика сбоя задания в сеансах

Политика по умолчанию для сеанса, когда задание завершается сбоем. Если вы отправляете дополнительное задание в одном сеансе, служба отклоняет его, а сеанс сообщает о состоянии сбоя. Все выполняемые задания отменяются.

Однако это поведение можно изменить, указав политику job_failure_policy=SessionJobFailurePolicy.CONTINUEсбоя задания, а не по умолчанию SessionJobFailurePolicy.ABORTпри создании сеанса. Если политика сбоя задания задана CONTINUE, служба продолжает принимать задания. Сеанс сообщает о состоянии сбоев в этом случае, который изменится на Failed после закрытия сеанса.

Если сеанс никогда не закрывается и истекает время ожидания, состояние — TimedOut , даже если задания завершились сбоем.

Например, следующая программа создает сеанс с тремя заданиями. Первое задание завершается "garbage" ошибкой, так как оно указывает в качестве входных данных. Чтобы избежать окончания сеанса на этом этапе, программа показывает, как добавить job_failure_policy=SessionJobFailurePolicy.CONTINUE при создании сеанса.

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