セッションを管理する方法
この記事では、セッションを管理する方法について説明します。 セッションを使用すると、1 つの targetに対して 1 つ以上のジョブをグループ化できるため、ジョブを効果的に管理できます。 詳細については、「 セッションの開始」を参照してください。
前提条件
アクティブなサブスクリプションが含まれる Azure アカウント。 Azure アカウントをお持ちでない場合は、無料で登録し、 従って支払うサブスクリプションにサインアップしてください。
Azure Quantum ワークスペース。 詳細については、「Azure Quantum ワークスペースを作成する」を参照してください。
Python と Pip がインストールされた Python 環境。
Azure Quantum
azure-quantum
パッケージ。 Qiskit または Cirq を使用する場合は、[qiskit] タグまたは [cirq] タグを使用してazure-quantum
パッケージをインストールする必要があります。pip install --upgrade azure-quantum[qiskit]
Note
インライン コードを実行している場合でも、セッションは Python で管理 Q# 。
セッションの監視
Quantum ワークスペースの [ ジョブ管理 ] ブレードを使用すると、セッションやセッションに関連付けられていない個々のジョブなど、最上位レベルで送信されたすべてのアイテムを表示できます。
- Quantum ワークスペースで Job management ブレードを選択します。
- Sessionの種類のジョブを識別します。 このビューでは、列 Id のセッションの一意の ID を確認し、その Statusを監視できます。 セッションの状態は次のとおりです。
- 待機中: セッション内のジョブが実行されています。
- 成功: セッションは正常に終了しました。
- TimeOut: セッション内で 10 分間新しいジョブが送信されない場合、そのセッションはタイムアウトします。詳細については、「 Session timeouts」を参照してください。
- 失敗: セッション内のジョブが失敗した場合、そのセッションは終了し、 Failedの状態が報告されます。 詳細については、「セッション内のジョブの失敗ポリシーを参照してください。
- 詳細については、セッションの名前をクリックしてください。
- セッション内で すべてのジョブ の一覧を表示し、その状態を監視できます。
セッションの取得と一覧表示
次の表に、特定のセッションのすべてのセッションとすべてのジョブの一覧を取得する Python コマンドを示します。
command | 説明 |
---|---|
workspace.list_sessions() または session.list_sessions() |
Quantum ワークスペース内のすべてのセッションの一覧を取得します。 |
workspace.get_session(sessionId) または session.get_session(sessionId) |
ID sessionId を使用してセッションを取得します。 各セッションには一意の ID があります。 |
workspace.list_session_jobs(sessionId) または session.list_session_jobs(sessionId) |
ID sessionId を使用して、セッション内のすべてのジョブの一覧を取得します。 各セッションには一意の ID があります。 |
たとえば、次のコードは、最小数のジョブを含むセッションを取得する関数を定義します。 次に、そのセッションに対して、すべてのジョブ、ジョブの合計数、および最初の 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}")
セッションを開く/閉じる手動の方法
新しいセッションを作成するには、「 Get started with sessions 」の手順に従うことをお勧めします。 セッションを手動で作成することもできます。
最初に、 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}")
Note
この時点で、セッションはクライアントにのみ存在し、状態が None であることがわかります。 セッションの状態を表示するには、サービスでセッションを作成する必要もあります。
サービス内のセッションを 作成 するには、
workspace.open_session(session)
またはsession.open()
を使用できます。statusとセッションの詳細を
session.refresh()
で更新するか、セッション ID から新しいセッション オブジェクトを取得します。same_session = workspace.get_session(session.id) print(f"Session: {session.details} \n") print(f"Session: {same_session.details} \n")
session.close()
またはworkspace.close_session(session)
とのセッション閉じるできます。セッションをtargetに接続するには、
target.latest_session
を使用できます。セッションを完了するためにを待つことができます。
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# オブジェクトとして書式設定する必要があります。
引数をパラメーターとしてジョブに渡すときは、qsharp.compile
を呼び出すときにQ# コードとして書式設定されるため、Python の値を有効なQ#構文として文字列に書式設定する必要があります。
整数、n
、および角度の配列を入力として受け取る次のQ# プログラム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;
}
n=2
と異なる角度GenerateRandomBits
操作を 3 回実行する必要があります。 次の Python コードを使用して、異なる角度で 3 つのジョブを送信できます。
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 の状態を報告します。 このような状況を回避するには、backend.open_session(name="Name")
を使用してwith
ブロックを追加し、コード ブロックの最後にサービスによってセッション close()
が呼び出されるようにします。
Note
プログラムにエラーやバグがある場合は、セッション内の前のジョブがすべて完了した後、新しいジョブを送信するのに 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()
セッション内のジョブ エラー ポリシー
ジョブが失敗した場合のセッションの既定のポリシーは、そのセッションを終了することです。 同じセッション内で追加のジョブを送信すると、サービスはそれを拒否し、セッションは Failed の状態を報告します。 進行中のジョブはすべて取り消されます。
ただし、この動作は、セッションの作成時に既定のSessionJobFailurePolicy.ABORT
ではなく、job_failure_policy=SessionJobFailurePolicy.CONTINUE
のジョブエラー ポリシーを指定することで変更できます。 ジョブエラー ポリシーが CONTINUE
されると、サービスはジョブを引き続き受け入れます。 この場合、セッションは Failure(s) の状態を報告します。この状態は、セッションが閉じられると Failed に変わります。
セッションが閉じずにタイムアウトになった場合、ジョブが失敗した場合でも、状態は TimedOut になります。
たとえば、次のプログラムは、3 つのジョブを含むセッションを作成します。 最初のジョブは、入力データとして "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")